| 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.
|
|
|