Chromium Code Reviews| Index: src/arm/ic-arm.cc |
| =================================================================== |
| --- src/arm/ic-arm.cc (revision 5854) |
| +++ src/arm/ic-arm.cc (working copy) |
| @@ -906,7 +906,9 @@ |
| static inline bool IsInlinedICSite(Address address, |
| - Address* inline_end_address) { |
| + Address* inline_end_address, |
| + Assembler::NopMarkerTypes type = |
|
Søren Thygesen Gjesse
2010/11/19 09:08:47
I think you should loose the default value here.
Alexandre
2010/11/23 11:23:21
Done.
|
| + Assembler::PROPERTY_ACCESS_INLINED) { |
| // 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 |
| @@ -914,7 +916,7 @@ |
| // 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, PROPERTY_ACCESS_INLINED)) { |
| + if (!MacroAssembler::IsMarkedCode(instr_after_call, type)) { |
| return false; |
| } |
| Address address_after_nop = address_after_call + Assembler::kInstrSize; |
| @@ -941,7 +943,11 @@ |
| // 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; |
| + if (!IsInlinedICSite(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. |
| @@ -959,8 +965,12 @@ |
| 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 - 4 * Assembler::kInstrSize; |
| + inline_end_address + ldr_map_offset * Assembler::kInstrSize; |
| Assembler::set_target_address_at(ldr_map_instr_address, |
| reinterpret_cast<Address>(map)); |
| return true; |
| @@ -971,8 +981,56 @@ |
| Object* map, |
| Object* cell, |
| bool is_dont_delete) { |
| - // TODO(<bug#>): implement this. |
| - return false; |
| + // Find the end of the inlined code for handling the contextual load if |
| + // this is inlined IC call site. |
| + Address inline_end_address; |
| + if (!IsInlinedICSite(address, |
| + &inline_end_address, |
| + Assembler::PROPERTY_ACCESS_INLINED_CONTEXT)) { |
| + return false; |
| + } |
| + |
| + // These are the offsets from the end of the inlined code. |
| + // See codgen-arm.cc CodeGenerator::EmitNamedLoad. |
| + int ldr_map_offset = is_dont_delete ? -5: -8; |
| + int ldr_cell_offset = is_dont_delete ? -2: -5; |
| + if (is_dont_delete && FLAG_debug_code) { |
| + // 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; |
| + Instr ldr_map_instr = Memory::int32_at(ldr_map_instr_address); |
| + Instr ldr_cell_instr = Memory::int32_at(ldr_cell_instr_address); |
| + |
| + // LoadIC::ClearInlinedVersion will call PatchInlinedContextualLoad with |
|
Søren Thygesen Gjesse
2010/11/19 09:08:47
Could you please elaborate a bit here on the diffe
Alexandre
2010/11/23 11:23:21
I refactored the code following your idea to encod
|
| + // is_dont_delete == true, but we rely on it to compute offsets. This may be |
| + // the reason we fail here, so retry with is_dont_delete == false. |
| + if (is_dont_delete && !(Assembler::IsLdrPcImmediateOffset(ldr_map_instr) && |
| + Assembler::IsLdrPcImmediateOffset(ldr_cell_instr))) { |
| + is_dont_delete = false; |
| + // See offsets before when is_dont_delete is false. |
| + ldr_map_offset = -8; |
| + ldr_cell_offset = -5; |
| + // We don't need to check for FLAG_debug_code. It should be handled only |
| + // when is_dont_delete == true, so it was taken care of before. |
| + ldr_map_instr_address = |
| + inline_end_address + ldr_map_offset * Assembler::kInstrSize; |
| + 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; |
| } |