Chromium Code Reviews| Index: src/arm/code-stubs-arm.cc |
| diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc |
| index 3670765a61223bf20f6c5178edb1396cd3296dec..1242c9ffd26af9fd9b55fa3cacadfdae7eeacd73 100644 |
| --- a/src/arm/code-stubs-arm.cc |
| +++ b/src/arm/code-stubs-arm.cc |
| @@ -2893,37 +2893,46 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { |
| } |
| -// This stub performs an instanceof, calling the builtin function if |
| -// necessary. Uses r1 for the object, r0 for the function that it may |
| -// be an instance of (these are fetched from the stack). |
| +// Uses registers r0 to r5. Expected input is |
| +// function in r0 (or at sp+1*ptrsz) and object in |
| +// r1 (or at sp), depending on whether or not |
| +// args_in_registers() is true. |
| void InstanceofStub::Generate(MacroAssembler* masm) { |
| - // Get the object - slow case for smis (we may need to throw an exception |
| - // depending on the rhs). |
| - Label slow, loop, is_instance, is_not_instance; |
| - __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); |
| - __ BranchOnSmi(r0, &slow); |
| + // Fixed register usage throughout the stub: |
| + const Register object = r1; // Object (lhs). |
| + const Register map = r3; // Map of the object. |
| + const Register function = r0; // Function (rhs). |
| + const Register prototype = r4; // Prototype of the function. |
| + const Register scratch = r2; |
| + const Register scratch2 = r5; // Used for IncrementCounter. |
| + const Register result = r0; |
|
Søren Thygesen Gjesse
2010/12/20 13:03:25
I don't think an alias for the result is required
|
| + Label slow, loop, is_instance, is_not_instance, not_js_object; |
| + if (!args_in_registers()) { |
| + __ ldr(function, MemOperand(sp, 1 * kPointerSize)); |
| + __ ldr(object, MemOperand(sp, 0)); |
| + } |
| + __ BranchOnSmi(function, &slow); |
| - // Check that the left hand is a JS object and put map in r3. |
| - __ CompareObjectType(r0, r3, r2, FIRST_JS_OBJECT_TYPE); |
| + // Check that the left hand is a JS object, load map, |
| + // and type into scratch |
|
Søren Thygesen Gjesse
2010/12/20 13:03:25
How about implementing IsObjectJSObjectType in the
Karl Klose
2010/12/21 08:56:37
Done.
|
| + __ CompareObjectType(function, map, scratch, FIRST_JS_OBJECT_TYPE); |
| __ b(lt, &slow); |
| - __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE)); |
| + __ cmp(scratch, Operand(LAST_JS_OBJECT_TYPE)); |
| __ b(gt, &slow); |
| - // Get the prototype of the function (r4 is result, r2 is scratch). |
| - __ ldr(r1, MemOperand(sp, 0)); |
| - // r1 is function, r3 is map. |
| - |
| // Look up the function and the map in the instanceof cache. |
| Label miss; |
| __ LoadRoot(ip, Heap::kInstanceofCacheFunctionRootIndex); |
| - __ cmp(r1, ip); |
| + __ cmp(object, ip); |
| __ b(ne, &miss); |
| __ LoadRoot(ip, Heap::kInstanceofCacheMapRootIndex); |
| - __ cmp(r3, ip); |
| + __ cmp(map, ip); |
| __ b(ne, &miss); |
| - __ LoadRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); |
| - __ pop(); |
| - __ pop(); |
| + __ LoadRoot(function, Heap::kInstanceofCacheAnswerRootIndex); |
| + if (!args_in_registers()) { |
|
Søren Thygesen Gjesse
2010/12/20 13:03:25
Use Drop from the ARM macro assembler to drop two
Karl Klose
2010/12/21 08:56:37
Done.
|
| + __ pop(); |
| + __ pop(); |
| + } |
|
Søren Thygesen Gjesse
2010/12/20 13:03:25
Use Ret from the ARM macro assembler. I suggest yo
Karl Klose
2010/12/21 08:56:37
Done.
|
| __ mov(pc, Operand(lr)); |
| __ bind(&miss); |
|
Søren Thygesen Gjesse
2010/12/20 13:03:25
You should use the register aliases created throug
Karl Klose
2010/12/21 08:56:37
Done.
|
| @@ -2957,17 +2966,70 @@ void InstanceofStub::Generate(MacroAssembler* masm) { |
| __ bind(&is_instance); |
| __ mov(r0, Operand(Smi::FromInt(0))); |
| __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); |
| - __ pop(); |
| - __ pop(); |
| + if (!args_in_registers()) { |
| + __ pop(); |
| + __ pop(); |
| + } |
| __ mov(pc, Operand(lr)); // Return. |
| __ bind(&is_not_instance); |
| __ mov(r0, Operand(Smi::FromInt(1))); |
| __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex); |
| - __ pop(); |
| - __ pop(); |
| + if (!args_in_registers()) { |
| + __ pop(); |
| + __ pop(); |
| + } |
| __ mov(pc, Operand(lr)); // Return. |
| + Label object_not_null, object_not_null_or_smi; |
| + __ bind(¬_js_object); |
| + // Before null, smi and string value checks, check that the rhs is a function |
| + // as for a non-function rhs an exception needs to be thrown. |
| + __ tst(function, Operand(kSmiTagMask)); |
|
Søren Thygesen Gjesse
2010/12/20 13:03:25
The ARM macro assembler has BranchOnSmi.
Karl Klose
2010/12/21 08:56:37
Done.
|
| + __ b(eq, &slow); |
| + __ CompareObjectType(function, map, scratch, JS_FUNCTION_TYPE); |
| + __ b(ne, &slow); |
| + |
| + // Null is not instance of anything. |
| + __ cmp(scratch, Operand(Factory::null_value())); |
| + __ b(ne, &object_not_null); |
| + __ mov(result, Operand(Smi::FromInt(1))); |
| + if (!args_in_registers()) { |
| + __ pop(); |
| + __ pop(); |
| + } |
| + __ mov(pc, Operand(lr)); // return |
| + |
| + __ bind(&object_not_null); |
| + // Smi values are not instances of anything. |
| + __ tst(object, Operand(kSmiTagMask)); |
|
Søren Thygesen Gjesse
2010/12/20 13:03:25
The ARM macro assembler has BranchOnNotSmi.
Karl Klose
2010/12/21 08:56:37
Done.
|
| + __ b(nz, &object_not_null_or_smi); |
| + __ mov(result, Operand(Smi::FromInt(1))); |
| + if (!args_in_registers()) { |
| + __ pop(); |
| + __ pop(); |
| + } |
| + __ mov(pc, Operand(lr)); // return |
| + |
| + __ bind(&object_not_null_or_smi); |
| + // String values are not instances of anything. |
|
Søren Thygesen Gjesse
2010/12/20 13:03:25
Please implement IsObjectStringType in ARM macro a
Karl Klose
2010/12/21 08:56:37
Done.
|
| + __ ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); |
| + __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); |
| + ASSERT(kNotStringTag != 0); |
| + __ tst(scratch, Operand(kIsNotStringMask)); |
| + __ b(nz, &slow); |
| + __ IncrementCounter(&Counters::instance_of_stub_false_string, |
|
Søren Thygesen Gjesse
2010/12/20 13:03:25
You can leave out all the counters. Then you don't
Karl Klose
2010/12/21 08:56:37
Done.
|
| + 1, |
| + scratch, |
| + scratch2); |
| + |
| + __ mov(result, Operand(Smi::FromInt(1))); |
| + if (!args_in_registers()) { |
| + __ pop(); |
| + __ pop(); |
| + } |
| + __ mov(pc, Operand(lr)); // return |
| + |
| // Slow-case. Tail call builtin. |
| __ bind(&slow); |
| __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_JS); |