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

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

Issue 3046006: Inline in-object property stores when in loop and not in top-level (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 5 months 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
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/ic-ia32.cc
===================================================================
--- src/ia32/ic-ia32.cc (revision 5101)
+++ src/ia32/ic-ia32.cc (working copy)
@@ -1644,37 +1644,6 @@
// One byte opcode for test eax,0xXXXXXXXX.
static const byte kTestEaxByte = 0xA9;
-
-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(), kMaxInt);
-}
-
-
-void KeyedLoadIC::ClearInlinedVersion(Address address) {
- // Insert null as the map to check for to make sure the map check fails
- // sending control flow to the IC instead of the inlined version.
- PatchInlinedLoad(address, Heap::null_value());
-}
-
-
-void KeyedStoreIC::ClearInlinedVersion(Address address) {
- // Insert null as the elements map to check for. This will make
- // sure that the elements fast-case map check fails so that control
- // flows to the IC instead of the inlined version.
- PatchInlinedStore(address, Heap::null_value());
-}
-
-
-void KeyedStoreIC::RestoreInlinedVersion(Address address) {
- // Restore the fast-case elements map check so that the inlined
- // version can be used again.
- PatchInlinedStore(address, Heap::fixed_array_map());
-}
-
-
bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
// The address of the instruction following the call.
Address test_instruction_address =
@@ -1703,6 +1672,52 @@
}
+bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
+ // The address of the instruction following the call.
+ Address test_instruction_address =
+ address + Assembler::kCallTargetAddressOffset;
+
+ // If the instruction following the call is not a test eax, nothing
+ // was inlined.
+ if (*test_instruction_address != kTestEaxByte) return false;
+
+ // Extract the encoded deltas from the test eax instruction.
+ Address encoded_offsets_address = test_instruction_address + 1;
+ int encoded_offsets = *reinterpret_cast<int*>(encoded_offsets_address);
+ int delta_to_map_check = -(encoded_offsets & 0xFFFF);
+ int delta_to_record_write = encoded_offsets >> 16;
+
+ // Patch the map to check. The map address is the last 4 bytes of
+ // the 7-byte operand-immediate compare instruction.
+ Address map_check_address = test_instruction_address + delta_to_map_check;
+ Address map_address = map_check_address + 3;
+ *(reinterpret_cast<Object**>(map_address)) = map;
+
+ // Patch the offset in the store instruction. The offset is in the
+ // last 4 bytes of a six byte register-to-memory move instruction.
+ Address offset_address =
+ map_check_address + StoreIC::kOffsetToStoreInstruction + 2;
+ // The offset should have initial value (kMaxInt - 1), cleared value
+ // (-1) or we should be clearing the inlined version.
+ ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt - 1 ||
+ *reinterpret_cast<int*>(offset_address) == -1 ||
+ (offset == 0 && map == Heap::null_value()));
+ *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
+
+ // Patch the offset in the write-barrier code. The offset is the
+ // last 4 bytes of a six byte lea instruction.
+ offset_address = map_check_address + delta_to_record_write + 2;
+ // The offset should have initial value (kMaxInt), cleared value
+ // (-1) or we should be clearing the inlined version.
+ ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt ||
+ *reinterpret_cast<int*>(offset_address) == -1 ||
+ (offset == 0 && map == Heap::null_value()));
+ *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
+
+ return true;
+}
+
+
static bool PatchInlinedMapCheck(Address address, Object* map) {
Address test_instruction_address =
address + Assembler::kCallTargetAddressOffset;
@@ -1814,6 +1829,12 @@
}
+// The offset from the inlined patch site to the start of the inlined
+// store instruction. It is 7 bytes (test reg, imm) plus 6 bytes (jne
+// slow_label).
+const int StoreIC::kOffsetToStoreInstruction = 13;
+
+
void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : value
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698