| Index: src/arm/ic-arm.cc
|
| ===================================================================
|
| --- src/arm/ic-arm.cc (revision 5106)
|
| +++ src/arm/ic-arm.cc (working copy)
|
| @@ -989,8 +989,49 @@
|
|
|
|
|
| bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
|
| - // TODO(787): Implement inline stores on arm.
|
| - return false;
|
| + // Find the end of the inlined code for the store if there is an
|
| + // inlined version of the store.
|
| + Address inline_end_address;
|
| + if (!IsInlinedICSite(address, &inline_end_address)) return false;
|
| +
|
| + // Compute the address of the map load instruction.
|
| + Address ldr_map_instr_address =
|
| + inline_end_address -
|
| + (CodeGenerator::GetInlinedNamedStoreInstructionsAfterPatch() *
|
| + Assembler::kInstrSize);
|
| +
|
| + // Update the offsets if initializing the inlined store. No reason
|
| + // to update the offsets when clearing the inlined version because
|
| + // it will bail out in the map check.
|
| + if (map != Heap::null_value()) {
|
| + // Patch the offset in the actual store instruction.
|
| + Address str_property_instr_address =
|
| + ldr_map_instr_address + 3 * Assembler::kInstrSize;
|
| + Instr str_property_instr = Assembler::instr_at(str_property_instr_address);
|
| + ASSERT(Assembler::IsStrRegisterImmediate(str_property_instr));
|
| + str_property_instr = Assembler::SetStrRegisterImmediateOffset(
|
| + str_property_instr, offset - kHeapObjectTag);
|
| + Assembler::instr_at_put(str_property_instr_address, str_property_instr);
|
| +
|
| + // Patch the offset in the add instruction that is part of the
|
| + // write barrier.
|
| + Address add_offset_instr_address =
|
| + str_property_instr_address + 4 * Assembler::kInstrSize;
|
| + Instr add_offset_instr = Assembler::instr_at(add_offset_instr_address);
|
| + ASSERT(Assembler::IsAddRegisterImmediate(add_offset_instr));
|
| + add_offset_instr = Assembler::SetAddRegisterImmediateOffset(
|
| + add_offset_instr, offset - kHeapObjectTag);
|
| + Assembler::instr_at_put(add_offset_instr_address, add_offset_instr);
|
| +
|
| + // Indicate that code has changed.
|
| + CPU::FlushICache(str_property_instr_address, 5 * Assembler::kInstrSize);
|
| + }
|
| +
|
| + // Patch the map check.
|
| + Assembler::set_target_address_at(ldr_map_instr_address,
|
| + reinterpret_cast<Address>(map));
|
| +
|
| + return true;
|
| }
|
|
|
|
|
|
|