From: svenpanne@chromium.org Date: Wed, 18 May 2011 10:40:01 +0000 (+0000) Subject: Handle all kind of arguments in the ToBooleanStub. While this is not very thrilling... X-Git-Tag: upstream/4.7.83~19387 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f39b0dfccb2d5fc8340c0bf35109f074d172f53b;p=platform%2Fupstream%2Fv8.git Handle all kind of arguments in the ToBooleanStub. While this is not very thrilling in itself, it is one of several steps to add type recording to this stub. Removed a duplicate check for null in the ARM stub and made a tiny simplification, removing a sub instruction. As a side note, this change has some positive impact on the performace, e.g. imaging-darkroom is 8.3% faster and ws-ieee754conv is even 19.9% faster. No idea why the speedup is so big in some cases, but never look a gift horse in the mouth... ;-) Review URL: http://codereview.chromium.org/7042004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7926 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 812032457..d51023240 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -1616,12 +1616,36 @@ void CompareStub::Generate(MacroAssembler* masm) { // The stub returns zero for false, and a non-zero value for true. void ToBooleanStub::Generate(MacroAssembler* masm) { // This stub uses VFP3 instructions. - ASSERT(CpuFeatures::IsEnabled(VFP3)); + CpuFeatures::Scope scope(VFP3); Label false_result; Label not_heap_number; Register scratch = r9.is(tos_) ? r7 : r9; + // undefined -> false + __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); + __ cmp(tos_, ip); + __ b(eq, &false_result); + + // Boolean -> its value + __ LoadRoot(ip, Heap::kFalseValueRootIndex); + __ cmp(tos_, ip); + __ b(eq, &false_result); + __ LoadRoot(ip, Heap::kTrueValueRootIndex); + __ cmp(tos_, ip); + // "tos_" is a register and contains a non-zero value. Hence we implicitly + // return true if the equal condition is satisfied. + __ Ret(eq); + + // Smis: 0 -> false, all other -> true + __ tst(tos_, tos_); + __ b(eq, &false_result); + __ tst(tos_, Operand(kSmiTagMask)); + // "tos_" is a register and contains a non-zero value. Hence we implicitly + // return true if the not equal condition is satisfied. + __ Ret(eq); + + // 'null' -> false __ LoadRoot(ip, Heap::kNullValueRootIndex); __ cmp(tos_, ip); __ b(eq, &false_result); @@ -1631,9 +1655,7 @@ void ToBooleanStub::Generate(MacroAssembler* masm) { __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); __ cmp(scratch, ip); __ b(¬_heap_number, ne); - - __ sub(ip, tos_, Operand(kHeapObjectTag)); - __ vldr(d1, ip, HeapNumber::kValueOffset); + __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset)); __ VFPCompareAndSetFlags(d1, 0.0); // "tos_" is a register, and contains a non zero value by default. // Hence we only need to overwrite "tos_" with zero to return false for @@ -1644,12 +1666,6 @@ void ToBooleanStub::Generate(MacroAssembler* masm) { __ bind(¬_heap_number); - // Check if the value is 'null'. - // 'null' => false. - __ LoadRoot(ip, Heap::kNullValueRootIndex); - __ cmp(tos_, ip); - __ b(&false_result, eq); - // It can be an undetectable object. // Undetectable => false. __ ldr(ip, FieldMemOperand(tos_, HeapObject::kMapOffset)); diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 68a23555b..2b7cdef87 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -562,23 +562,6 @@ void FullCodeGenerator::DoTest(Label* if_true, Label* if_false, Label* fall_through) { if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); - // Emit the inlined tests assumed by the stub. - __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); - __ cmp(result_register(), ip); - __ b(eq, if_false); - __ LoadRoot(ip, Heap::kTrueValueRootIndex); - __ cmp(result_register(), ip); - __ b(eq, if_true); - __ LoadRoot(ip, Heap::kFalseValueRootIndex); - __ cmp(result_register(), ip); - __ b(eq, if_false); - STATIC_ASSERT(kSmiTag == 0); - __ tst(result_register(), result_register()); - __ b(eq, if_false); - __ JumpIfSmi(result_register(), if_true); - - // Call the ToBoolean stub for all other cases. ToBooleanStub stub(result_register()); __ CallStub(&stub); __ tst(result_register(), result_register()); @@ -590,8 +573,6 @@ void FullCodeGenerator::DoTest(Label* if_true, __ LoadRoot(ip, Heap::kFalseValueRootIndex); __ cmp(r0, ip); } - - // The stub returns nonzero for true. Split(ne, if_true, if_false, fall_through); } diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 534c18753..ccac14cc2 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -244,9 +244,25 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { void ToBooleanStub::Generate(MacroAssembler* masm) { Label false_result, true_result, not_string; __ mov(eax, Operand(esp, 1 * kPointerSize)); + Factory* factory = masm->isolate()->factory(); + + // undefined -> false + __ cmp(eax, factory->undefined_value()); + __ j(equal, &false_result); + + // Boolean -> its value + __ cmp(eax, factory->true_value()); + __ j(equal, &true_result); + __ cmp(eax, factory->false_value()); + __ j(equal, &false_result); + + // Smis: 0 -> false, all other -> true + __ test(eax, Operand(eax)); + __ j(zero, &false_result); + __ test(eax, Immediate(kSmiTagMask)); + __ j(zero, &true_result); // 'null' => false. - Factory* factory = masm->isolate()->factory(); __ cmp(eax, factory->null_value()); __ j(equal, &false_result, Label::kNear); diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 59c337386..d20e6223e 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -548,25 +548,10 @@ void FullCodeGenerator::TestContext::Plug(bool flag) const { void FullCodeGenerator::DoTest(Label* if_true, Label* if_false, Label* fall_through) { - // Emit the inlined tests assumed by the stub. - __ cmp(result_register(), isolate()->factory()->undefined_value()); - __ j(equal, if_false); - __ cmp(result_register(), isolate()->factory()->true_value()); - __ j(equal, if_true); - __ cmp(result_register(), isolate()->factory()->false_value()); - __ j(equal, if_false); - STATIC_ASSERT(kSmiTag == 0); - __ test(result_register(), Operand(result_register())); - __ j(zero, if_false); - __ test(result_register(), Immediate(kSmiTagMask)); - __ j(zero, if_true); - - // Call the ToBoolean stub for all other cases. ToBooleanStub stub; __ push(result_register()); __ CallStub(&stub); __ test(eax, Operand(eax)); - // The stub returns nonzero for true. Split(not_zero, if_true, if_false, fall_through); } diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 702d06a51..6fc6a1745 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -235,6 +235,22 @@ void ToBooleanStub::Generate(MacroAssembler* masm) { Label false_result, true_result, not_string; __ movq(rax, Operand(rsp, 1 * kPointerSize)); + // undefined -> false + __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); + __ j(equal, &false_result); + + // Boolean -> its value + __ CompareRoot(rax, Heap::kFalseValueRootIndex); + __ j(equal, &false_result); + __ CompareRoot(rax, Heap::kTrueValueRootIndex); + __ j(equal, &true_result); + + // Smis: 0 -> false, all other -> true + __ Cmp(rax, Smi::FromInt(0)); + __ j(equal, &false_result); + Condition is_smi = __ CheckSmi(rax); + __ j(is_smi, &true_result); + // 'null' => false. __ CompareRoot(rax, Heap::kNullValueRootIndex); __ j(equal, &false_result, Label::kNear); diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 3194e8aab..d5a220f9e 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -553,25 +553,10 @@ void FullCodeGenerator::TestContext::Plug(bool flag) const { void FullCodeGenerator::DoTest(Label* if_true, Label* if_false, Label* fall_through) { - // Emit the inlined tests assumed by the stub. - __ CompareRoot(result_register(), Heap::kUndefinedValueRootIndex); - __ j(equal, if_false); - __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); - __ j(equal, if_true); - __ CompareRoot(result_register(), Heap::kFalseValueRootIndex); - __ j(equal, if_false); - STATIC_ASSERT(kSmiTag == 0); - __ Cmp(result_register(), Smi::FromInt(0)); - __ j(equal, if_false); - Condition is_smi = masm_->CheckSmi(result_register()); - __ j(is_smi, if_true); - - // Call the ToBoolean stub for all other cases. ToBooleanStub stub; __ push(result_register()); __ CallStub(&stub); __ testq(rax, rax); - // The stub returns nonzero for true. Split(not_zero, if_true, if_false, fall_through); }