| Index: src/arm/ic-arm.cc
|
| ===================================================================
|
| --- src/arm/ic-arm.cc (revision 4509)
|
| +++ src/arm/ic-arm.cc (working copy)
|
| @@ -563,15 +563,8 @@
|
| }
|
|
|
|
|
| -void LoadIC::ClearInlinedVersion(Address address) {
|
| - // Reset the map check of the inlined inobject property load (if present) to
|
| - // guarantee failure by holding an invalid map (the null value). The offset
|
| - // can be patched to anything.
|
| - PatchInlinedLoad(address, Heap::null_value(), 0);
|
| -}
|
| -
|
| -
|
| -bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
|
| +static inline bool IsInlinedICSite(Address address,
|
| + Address* inline_end_address) {
|
| // If the instruction after the call site is not the pseudo instruction nop1
|
| // then this is not related to an inlined in-object property load. The nop1
|
| // instruction is located just after the call to the IC in the deferred code
|
| @@ -579,24 +572,42 @@
|
| // a branch instruction for jumping back from the deferred code.
|
| Address address_after_call = address + Assembler::kCallTargetAddressOffset;
|
| Instr instr_after_call = Assembler::instr_at(address_after_call);
|
| - if (!Assembler::IsNop(instr_after_call, NAMED_PROPERTY_LOAD_INLINED)) {
|
| + if (!Assembler::IsNop(instr_after_call, PROPERTY_LOAD_INLINED)) {
|
| return false;
|
| }
|
| - ASSERT_EQ(0, RegisterAllocator::kNumRegisters);
|
| - Address address_after_nop1 = address_after_call + Assembler::kInstrSize;
|
| - Instr instr_after_nop1 = Assembler::instr_at(address_after_nop1);
|
| - ASSERT(Assembler::IsBranch(instr_after_nop1));
|
| + Address address_after_nop = address_after_call + Assembler::kInstrSize;
|
| + Instr instr_after_nop = Assembler::instr_at(address_after_nop);
|
| + ASSERT(Assembler::IsBranch(instr_after_nop));
|
|
|
| // Find the end of the inlined code for handling the load.
|
| int b_offset =
|
| - Assembler::GetBranchOffset(instr_after_nop1) + Assembler::kPcLoadDelta;
|
| + Assembler::GetBranchOffset(instr_after_nop) + Assembler::kPcLoadDelta;
|
| ASSERT(b_offset < 0); // Jumping back from deferred code.
|
| - Address inline_end_address = address_after_nop1 + b_offset;
|
| + *inline_end_address = address_after_nop + b_offset;
|
|
|
| + return true;
|
| +}
|
| +
|
| +
|
| +void LoadIC::ClearInlinedVersion(Address address) {
|
| + // Reset the map check of the inlined in-object property load (if present) to
|
| + // guarantee failure by holding an invalid map (the null value). The offset
|
| + // can be patched to anything.
|
| + PatchInlinedLoad(address, Heap::null_value(), 0);
|
| +}
|
| +
|
| +
|
| +bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
|
| + // Find the end of the inlined code for handling the load if this is an
|
| + // inlined IC call site.
|
| + Address inline_end_address;
|
| + if (!IsInlinedICSite(address, &inline_end_address)) return false;
|
| +
|
| // Patch the offset of the property load instruction (ldr r0, [r1, #+XXX]).
|
| - // The immediate must be represenatble in 12 bits.
|
| + // The immediate must be representable in 12 bits.
|
| ASSERT((JSObject::kMaxInstanceSize - JSObject::kHeaderSize) < (1 << 12));
|
| - Address ldr_property_instr_address = inline_end_address - 4;
|
| + Address ldr_property_instr_address =
|
| + inline_end_address - Assembler::kInstrSize;
|
| ASSERT(Assembler::IsLdrRegisterImmediate(
|
| Assembler::instr_at(ldr_property_instr_address)));
|
| Instr ldr_property_instr = Assembler::instr_at(ldr_property_instr_address);
|
| @@ -608,18 +619,31 @@
|
| CPU::FlushICache(ldr_property_instr_address, 1 * Assembler::kInstrSize);
|
|
|
| // Patch the map check.
|
| - Address ldr_map_instr_address = inline_end_address - 16;
|
| + Address ldr_map_instr_address =
|
| + inline_end_address - 4 * Assembler::kInstrSize;
|
| Assembler::set_target_address_at(ldr_map_instr_address,
|
| reinterpret_cast<Address>(map));
|
| return true;
|
| }
|
|
|
|
|
| -void KeyedLoadIC::ClearInlinedVersion(Address address) {}
|
| +void KeyedLoadIC::ClearInlinedVersion(Address address) {
|
| + // Reset the map check of the inlined keyed load (if present) to
|
| + // guarantee failure by holding an invalid map (the null value).
|
| + PatchInlinedLoad(address, Heap::null_value());
|
| +}
|
|
|
|
|
| bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) {
|
| - return false;
|
| + Address inline_end_address;
|
| + if (!IsInlinedICSite(address, &inline_end_address)) return false;
|
| +
|
| + // Patch the map check.
|
| + Address ldr_map_instr_address =
|
| + inline_end_address - 19 * Assembler::kInstrSize;
|
| + Assembler::set_target_address_at(ldr_map_instr_address,
|
| + reinterpret_cast<Address>(map));
|
| + return true;
|
| }
|
|
|
|
|
|
|