Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: src/arm/ic-arm.cc

Issue 5140002: Generate inline code for contextual loads on ARM.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
}

Powered by Google App Engine
This is Rietveld 408576698