Handle all kind of arguments in the ToBooleanStub. While this is not very...

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
parent 2cb0c0a9
......@@ -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));
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment