Index: src/stub-cache-arm.cc |
=================================================================== |
--- src/stub-cache-arm.cc (revision 500) |
+++ src/stub-cache-arm.cc (working copy) |
@@ -421,8 +421,15 @@ |
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_ExtendStorage)); |
__ Jump(ic, RelocInfo::CODE_TARGET); |
} else { |
- // Get the properties array |
- __ ldr(r1, FieldMemOperand(r3, JSObject::kPropertiesOffset)); |
+ // Adjust for the number of properties stored in the object. Even in the |
+ // face of a transition we can use the old map here because the size of the |
+ // object and the number of in-object properties is not going to change. |
+ index -= object->map()->inobject_properties(); |
+ |
+ if (index >= 0) { |
+ // Get the properties array |
+ __ ldr(r1, FieldMemOperand(r3, JSObject::kPropertiesOffset)); |
+ } |
if (transition != NULL) { |
// Update the map of the object; no write barrier updating is |
@@ -431,17 +438,31 @@ |
__ str(ip, FieldMemOperand(r3, HeapObject::kMapOffset)); |
} |
- // Write to the properties array. |
- int offset = index * kPointerSize + Array::kHeaderSize; |
- __ str(r0, FieldMemOperand(r1, offset)); |
+ if (index < 0) { |
+ // Set the property straight into the object. |
+ int offset = object->map()->instance_size() + (index * kPointerSize); |
+ __ str(r0, FieldMemOperand(r3, offset)); |
+ |
+ // Skip updating write barrier if storing a smi. |
+ __ tst(r0, Operand(kSmiTagMask)); |
+ __ b(eq, &exit); |
+ |
+ // Update the write barrier for the array address. |
+ __ mov(r1, Operand(offset)); |
+ __ RecordWrite(r3, r1, r2); |
+ } else { |
+ // Write to the properties array. |
+ int offset = index * kPointerSize + Array::kHeaderSize; |
+ __ str(r0, FieldMemOperand(r1, offset)); |
- // Skip updating write barrier if storing a smi. |
- __ tst(r0, Operand(kSmiTagMask)); |
- __ b(eq, &exit); |
+ // Skip updating write barrier if storing a smi. |
+ __ tst(r0, Operand(kSmiTagMask)); |
+ __ b(eq, &exit); |
- // Update the write barrier for the array address. |
- __ mov(r3, Operand(offset)); |
- __ RecordWrite(r1, r3, r2); // OK to clobber r2, since we return |
+ // Update the write barrier for the array address. |
+ __ mov(r3, Operand(offset)); |
+ __ RecordWrite(r1, r3, r2); // OK to clobber r2, since we return |
+ } |
// Return the value (register r0). |
__ bind(&exit); |
@@ -590,12 +611,19 @@ |
// Check that the maps haven't changed. |
Register reg = __ CheckMaps(object, r0, holder, r3, r1, &miss); |
- // Get the properties array of the holder. |
- __ ldr(r3, FieldMemOperand(reg, JSObject::kPropertiesOffset)); |
- |
- // Return the value from the properties array. |
- int offset = index * kPointerSize + Array::kHeaderSize; |
- __ ldr(r0, FieldMemOperand(r3, offset)); |
+ // Adjust for the number of properties stored in the holder. |
+ index -= holder->map()->inobject_properties(); |
+ if (index < 0) { |
+ // Get the property straight out of the holder. |
+ int offset = holder->map()->instance_size() + (index * kPointerSize); |
+ __ ldr(r0, FieldMemOperand(reg, offset)); |
+ } else { |
+ // Get the properties array of the holder. |
+ __ ldr(r3, FieldMemOperand(reg, JSObject::kPropertiesOffset)); |
+ // Return the value from the properties array. |
+ int offset = index * kPointerSize + Array::kHeaderSize; |
+ __ ldr(r0, FieldMemOperand(r3, offset)); |
+ } |
__ Ret(); |
// Handle load cache miss. |