| 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
|
|
|