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; |
} |