Index: src/ia32/ic-ia32.cc |
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc |
index 87af0d9b51fc9471d500f127b5d3ccb121dad207..413c36e922764e396fbf50688368e29dd35faa48 100644 |
--- a/src/ia32/ic-ia32.cc |
+++ b/src/ia32/ic-ia32.cc |
@@ -1661,6 +1661,38 @@ bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { |
} |
+// One byte opcode for mov ecx,0xXXXXXXXX. |
+static const byte kMovEcxByte = 0xB9; |
+ |
+bool LoadIC::PatchInlinedContextualLoad(Address address, |
+ Object* map, |
+ Object* cell) { |
+ // The address of the instruction following the call. |
+ Address mov_instruction_address = |
+ address + Assembler::kCallTargetAddressOffset; |
+ // If the instruction following the call is not a cmp eax, nothing |
+ // was inlined. |
+ if (*mov_instruction_address != kMovEcxByte) return false; |
+ |
+ Address delta_address = mov_instruction_address + 1; |
+ // The delta to the start of the map check instruction. |
+ int delta = *reinterpret_cast<int*>(delta_address); |
+ |
+ // The map address is the last 4 bytes of the 7-byte |
+ // operand-immediate compare instruction, so we add 3 to get the |
+ // offset to the last 4 bytes. |
+ Address map_address = mov_instruction_address + delta + 3; |
+ *(reinterpret_cast<Object**>(map_address)) = map; |
+ |
+ // The cell is in the last 4 bytes of a five byte mov reg, imm32 |
+ // instruction, so we add 1 to get the offset to the last 4 bytes. |
+ Address offset_address = |
+ mov_instruction_address + delta + kOffsetToLoadInstruction + 1; |
+ *reinterpret_cast<Object**>(offset_address) = cell; |
+ return true; |
+} |
+ |
+ |
bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) { |
// The address of the instruction following the call. |
Address test_instruction_address = |