Index: src/arm/ic-arm.cc |
=================================================================== |
--- src/arm/ic-arm.cc (revision 7619) |
+++ src/arm/ic-arm.cc (working copy) |
@@ -926,218 +926,7 @@ |
__ TailCallExternalReference(ref, 2, 1); |
} |
-// Returns the code marker, or the 0 if the code is not marked. |
-static inline int InlinedICSiteMarker(Address address, |
- Address* inline_end_address) { |
- if (V8::UseCrankshaft()) return false; |
- // 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 |
- // handling the miss in the inlined code. After the nop1 instruction there is |
- // 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); |
- int code_marker = MacroAssembler::GetCodeMarker(instr_after_call); |
- |
- // A negative result means the code is not marked. |
- if (code_marker <= 0) return 0; |
- |
- Address address_after_nop = address_after_call + Assembler::kInstrSize; |
- Instr instr_after_nop = Assembler::instr_at(address_after_nop); |
- // There may be some reg-reg move and frame merging code to skip over before |
- // the branch back from the DeferredReferenceGetKeyedValue code to the inlined |
- // code. |
- while (!Assembler::IsBranch(instr_after_nop)) { |
- address_after_nop += Assembler::kInstrSize; |
- instr_after_nop = Assembler::instr_at(address_after_nop); |
- } |
- |
- // Find the end of the inlined code for handling the load. |
- int b_offset = |
- Assembler::GetBranchOffset(instr_after_nop) + Assembler::kPcLoadDelta; |
- ASSERT(b_offset < 0); // Jumping back from deferred code. |
- *inline_end_address = address_after_nop + b_offset; |
- |
- return code_marker; |
-} |
- |
- |
-bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { |
- if (V8::UseCrankshaft()) return false; |
- |
- // Find the end of the inlined code for handling the load if this is an |
- // inlined IC call site. |
- Address inline_end_address = 0; |
- if (InlinedICSiteMarker(address, &inline_end_address) |
- != Assembler::PROPERTY_ACCESS_INLINED) { |
- return false; |
- } |
- |
- // Patch the offset of the property load instruction (ldr r0, [r1, #+XXX]). |
- // The immediate must be representable in 12 bits. |
- ASSERT((JSObject::kMaxInstanceSize - JSObject::kHeaderSize) < (1 << 12)); |
- 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); |
- ldr_property_instr = Assembler::SetLdrRegisterImmediateOffset( |
- ldr_property_instr, offset - kHeapObjectTag); |
- Assembler::instr_at_put(ldr_property_instr_address, ldr_property_instr); |
- |
- // Indicate that code has changed. |
- CPU::FlushICache(ldr_property_instr_address, 1 * Assembler::kInstrSize); |
- |
- // Patch the map check. |
- // For PROPERTY_ACCESS_INLINED, the load map instruction is generated |
- // 4 instructions before the end of the inlined code. |
- // See codgen-arm.cc CodeGenerator::EmitNamedLoad. |
- int ldr_map_offset = -4; |
- Address ldr_map_instr_address = |
- inline_end_address + ldr_map_offset * Assembler::kInstrSize; |
- Assembler::set_target_address_at(ldr_map_instr_address, |
- reinterpret_cast<Address>(map)); |
- return true; |
-} |
- |
- |
-bool LoadIC::PatchInlinedContextualLoad(Address address, |
- Object* map, |
- Object* cell, |
- bool is_dont_delete) { |
- // Find the end of the inlined code for handling the contextual load if |
- // this is inlined IC call site. |
- Address inline_end_address = 0; |
- int marker = InlinedICSiteMarker(address, &inline_end_address); |
- if (!((marker == Assembler::PROPERTY_ACCESS_INLINED_CONTEXT) || |
- (marker == Assembler::PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE))) { |
- return false; |
- } |
- // On ARM we don't rely on the is_dont_delete argument as the hint is already |
- // embedded in the code marker. |
- bool marker_is_dont_delete = |
- marker == Assembler::PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE; |
- |
- // These are the offsets from the end of the inlined code. |
- // See codgen-arm.cc CodeGenerator::EmitNamedLoad. |
- int ldr_map_offset = marker_is_dont_delete ? -5: -8; |
- int ldr_cell_offset = marker_is_dont_delete ? -2: -5; |
- if (FLAG_debug_code && marker_is_dont_delete) { |
- // Three extra instructions were generated to check for the_hole_value. |
- ldr_map_offset -= 3; |
- ldr_cell_offset -= 3; |
- } |
- Address ldr_map_instr_address = |
- inline_end_address + ldr_map_offset * Assembler::kInstrSize; |
- Address ldr_cell_instr_address = |
- inline_end_address + ldr_cell_offset * Assembler::kInstrSize; |
- |
- // Patch the map check. |
- Assembler::set_target_address_at(ldr_map_instr_address, |
- reinterpret_cast<Address>(map)); |
- // Patch the cell address. |
- Assembler::set_target_address_at(ldr_cell_instr_address, |
- reinterpret_cast<Address>(cell)); |
- |
- return true; |
-} |
- |
- |
-bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) { |
- if (V8::UseCrankshaft()) 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 = 0; |
- if (InlinedICSiteMarker(address, &inline_end_address) |
- != Assembler::PROPERTY_ACCESS_INLINED) { |
- 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 + 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, 2 * Assembler::kInstrSize); |
- } |
- |
- // Patch the map check. |
- Assembler::set_target_address_at(ldr_map_instr_address, |
- reinterpret_cast<Address>(map)); |
- |
- return true; |
-} |
- |
- |
-bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) { |
- if (V8::UseCrankshaft()) return false; |
- |
- Address inline_end_address = 0; |
- if (InlinedICSiteMarker(address, &inline_end_address) |
- != Assembler::PROPERTY_ACCESS_INLINED) { |
- return false; |
- } |
- |
- // Patch the map check. |
- Address ldr_map_instr_address = |
- inline_end_address - |
- (CodeGenerator::GetInlinedKeyedLoadInstructionsAfterPatch() * |
- Assembler::kInstrSize); |
- Assembler::set_target_address_at(ldr_map_instr_address, |
- reinterpret_cast<Address>(map)); |
- return true; |
-} |
- |
- |
-bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) { |
- if (V8::UseCrankshaft()) return false; |
- |
- // Find the end of the inlined code for handling the store if this is an |
- // inlined IC call site. |
- Address inline_end_address = 0; |
- if (InlinedICSiteMarker(address, &inline_end_address) |
- != Assembler::PROPERTY_ACCESS_INLINED) { |
- return false; |
- } |
- |
- // Patch the map check. |
- Address ldr_map_instr_address = |
- inline_end_address - |
- (CodeGenerator::kInlinedKeyedStoreInstructionsAfterPatch * |
- Assembler::kInstrSize); |
- Assembler::set_target_address_at(ldr_map_instr_address, |
- reinterpret_cast<Address>(map)); |
- return true; |
-} |
- |
- |
Object* KeyedLoadIC_Miss(Arguments args); |