| Index: src/arm/code-stubs-arm.cc
|
| ===================================================================
|
| --- src/arm/code-stubs-arm.cc (revision 8353)
|
| +++ src/arm/code-stubs-arm.cc (working copy)
|
| @@ -1610,15 +1610,13 @@
|
| }
|
|
|
|
|
| -// This stub does not handle the inlined cases (Smis, Booleans, undefined).
|
| // The stub returns zero for false, and a non-zero value for true.
|
| void ToBooleanStub::Generate(MacroAssembler* masm) {
|
| // This stub uses VFP3 instructions.
|
| CpuFeatures::Scope scope(VFP3);
|
|
|
| - Label false_result;
|
| - Label not_heap_number;
|
| - Register scratch = r9.is(tos_) ? r7 : r9;
|
| + Label false_result, true_result, not_string;
|
| + const Register map = r9.is(tos_) ? r7 : r9;
|
|
|
| // undefined -> false
|
| __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
|
| @@ -1648,11 +1646,31 @@
|
| __ cmp(tos_, ip);
|
| __ b(eq, &false_result);
|
|
|
| - // HeapNumber => false iff +0, -0, or NaN.
|
| - __ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset));
|
| - __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
|
| - __ cmp(scratch, ip);
|
| - __ b(¬_heap_number, ne);
|
| + // Get the map of the heap object.
|
| + __ ldr(map, FieldMemOperand(tos_, HeapObject::kMapOffset));
|
| +
|
| + // Undetectable -> false.
|
| + __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset));
|
| + __ tst(ip, Operand(1 << Map::kIsUndetectable));
|
| + __ b(&false_result, ne);
|
| +
|
| + // JavaScript object -> true.
|
| + __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE);
|
| + // "tos_" is a register and contains a non-zero value. Hence we implicitly
|
| + // return true if the greater than condition is satisfied.
|
| + __ Ret(ge);
|
| +
|
| + // String value -> false iff empty.
|
| + __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
|
| + __ b(¬_string, ge);
|
| + __ ldr(tos_, FieldMemOperand(tos_, String::kLengthOffset));
|
| + // Return string length as boolean value, i.e. return false iff length is 0.
|
| + __ Ret();
|
| +
|
| + __ bind(¬_string);
|
| + // HeapNumber -> false iff +0, -0, or NaN.
|
| + __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
|
| + __ b(&true_result, ne);
|
| __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset));
|
| __ VFPCompareAndSetFlags(d1, 0.0);
|
| // "tos_" is a register, and contains a non zero value by default.
|
| @@ -1662,41 +1680,10 @@
|
| __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs); // for FP_NAN
|
| __ Ret();
|
|
|
| - __ bind(¬_heap_number);
|
| -
|
| - // It can be an undetectable object.
|
| - // Undetectable => false.
|
| - __ ldr(ip, FieldMemOperand(tos_, HeapObject::kMapOffset));
|
| - __ ldrb(scratch, FieldMemOperand(ip, Map::kBitFieldOffset));
|
| - __ and_(scratch, scratch, Operand(1 << Map::kIsUndetectable));
|
| - __ cmp(scratch, Operand(1 << Map::kIsUndetectable));
|
| - __ b(&false_result, eq);
|
| -
|
| - // JavaScript object => true.
|
| - __ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset));
|
| - __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
|
| - __ cmp(scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
|
| - // "tos_" is a register and contains a non-zero value.
|
| - // Hence we implicitly return true if the greater than
|
| - // condition is satisfied.
|
| - __ Ret(gt);
|
| -
|
| - // Check for string
|
| - __ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset));
|
| - __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
|
| - __ cmp(scratch, Operand(FIRST_NONSTRING_TYPE));
|
| - // "tos_" is a register and contains a non-zero value.
|
| - // Hence we implicitly return true if the greater than
|
| - // condition is satisfied.
|
| - __ Ret(gt);
|
| -
|
| - // String value => false iff empty, i.e., length is zero
|
| - __ ldr(tos_, FieldMemOperand(tos_, String::kLengthOffset));
|
| - // If length is zero, "tos_" contains zero ==> false.
|
| - // If length is not zero, "tos_" contains a non-zero value ==> true.
|
| + // Return 1/0 for true/false in tos_.
|
| + __ bind(&true_result);
|
| + __ mov(tos_, Operand(1, RelocInfo::NONE));
|
| __ Ret();
|
| -
|
| - // Return 0 in "tos_" for false .
|
| __ bind(&false_result);
|
| __ mov(tos_, Operand(0, RelocInfo::NONE));
|
| __ Ret();
|
|
|