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
This commit is contained in:
svenpanne@chromium.org 2011-05-18 10:40:01 +00:00
parent 2cb0c0a957
commit f39b0dfccb
6 changed files with 59 additions and 60 deletions

View File

@ -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(&not_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(&not_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));

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}