Index: src/arm/code-stubs-arm.cc |
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc |
index 47df2a353e989c6f824bf69199d3c58f6bd0c62c..ef286bbe01585a7a1ad56d3e71c0b5fdc278233f 100644 |
--- a/src/arm/code-stubs-arm.cc |
+++ b/src/arm/code-stubs-arm.cc |
@@ -3181,18 +3181,43 @@ void SubStringStub::Generate(MacroAssembler* masm) { |
void ToNumberStub::Generate(MacroAssembler* masm) { |
// The ToNumber stub takes one argument in r0. |
- Label check_heap_number, call_builtin; |
- __ JumpIfNotSmi(r0, &check_heap_number); |
+ Label not_smi; |
+ __ JumpIfNotSmi(r0, ¬_smi); |
__ Ret(); |
+ __ bind(¬_smi); |
- __ bind(&check_heap_number); |
+ Label not_heap_number; |
__ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); |
- __ CompareRoot(r1, Heap::kHeapNumberMapRootIndex); |
- __ b(ne, &call_builtin); |
+ __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); |
+ // r0: object |
+ // r1: instance type. |
+ __ cmp(r1, Operand(HEAP_NUMBER_TYPE)); |
+ __ b(ne, ¬_heap_number); |
+ __ Ret(); |
+ __ bind(¬_heap_number); |
+ |
+ Label not_string, slow_string; |
+ __ cmp(r1, Operand(FIRST_NONSTRING_TYPE)); |
+ __ b(hs, ¬_string); |
+ // Check if string has a cached array index. |
+ __ ldr(r2, FieldMemOperand(r0, String::kHashFieldOffset)); |
+ __ tst(r2, Operand(String::kContainsCachedArrayIndexMask)); |
+ __ b(ne, &slow_string); |
+ __ IndexFromHash(r2, r0); |
+ __ Ret(); |
+ __ bind(&slow_string); |
+ __ push(r0); // Push argument. |
+ __ TailCallRuntime(Runtime::kStringToNumber, 1, 1); |
+ __ bind(¬_string); |
+ |
+ Label not_oddball; |
+ __ cmp(r1, Operand(ODDBALL_TYPE)); |
+ __ b(ne, ¬_oddball); |
+ __ ldr(r0, FieldMemOperand(r0, Oddball::kToNumberOffset)); |
__ Ret(); |
+ __ bind(¬_oddball); |
- __ bind(&call_builtin); |
- __ push(r0); |
+ __ push(r0); // Push argument. |
__ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION); |
} |