From f39b0dfccb2d5fc8340c0bf35109f074d172f53b Mon Sep 17 00:00:00 2001 From: "svenpanne@chromium.org" Date: Wed, 18 May 2011 10:40:01 +0000 Subject: [PATCH] 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 --- src/arm/code-stubs-arm.cc | 36 +++++++++++++++++++++++++---------- src/arm/full-codegen-arm.cc | 19 ------------------ src/ia32/code-stubs-ia32.cc | 18 +++++++++++++++++- src/ia32/full-codegen-ia32.cc | 15 --------------- src/x64/code-stubs-x64.cc | 16 ++++++++++++++++ src/x64/full-codegen-x64.cc | 15 --------------- 6 files changed, 59 insertions(+), 60 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 812032457e..d510232409 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 68a23555b1..2b7cdef871 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 534c18753b..ccac14cc2a 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 59c3373866..d20e6223e1 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 702d06a51c..6fc6a17452 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 3194e8aab6..d5a220f9e3 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); }