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:
parent
2cb0c0a957
commit
f39b0dfccb
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user