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