| Index: src/ia32/deoptimizer-ia32.cc
|
| ===================================================================
|
| --- src/ia32/deoptimizer-ia32.cc (revision 7031)
|
| +++ src/ia32/deoptimizer-ia32.cc (working copy)
|
| @@ -80,6 +80,7 @@
|
| Address prev_address = code_start_address;
|
| for (unsigned i = 0; i < table.length(); ++i) {
|
| Address curr_address = code_start_address + table.GetPcOffset(i);
|
| + ASSERT_GE(curr_address, prev_address);
|
| ZapCodeRange(prev_address, curr_address);
|
|
|
| SafepointEntry safepoint_entry = table.GetEntry(i);
|
| @@ -97,7 +98,8 @@
|
| RelocInfo::RUNTIME_ENTRY,
|
| reinterpret_cast<intptr_t>(deopt_entry));
|
| reloc_info_writer.Write(&rinfo);
|
| -
|
| + ASSERT_GE(reloc_info_writer.pos(),
|
| + reloc_info->address() + ByteArray::kHeaderSize);
|
| curr_address += patch_size();
|
| }
|
| prev_address = curr_address;
|
| @@ -138,39 +140,39 @@
|
| void Deoptimizer::PatchStackCheckCodeAt(Address pc_after,
|
| Code* check_code,
|
| Code* replacement_code) {
|
| - Address call_target_address = pc_after - kPointerSize;
|
| - ASSERT(check_code->entry() ==
|
| - Assembler::target_address_at(call_target_address));
|
| - // The stack check code matches the pattern:
|
| - //
|
| - // cmp esp, <limit>
|
| - // jae ok
|
| - // call <stack guard>
|
| - // test eax, <loop nesting depth>
|
| - // ok: ...
|
| - //
|
| - // We will patch away the branch so the code is:
|
| - //
|
| - // cmp esp, <limit> ;; Not changed
|
| - // nop
|
| - // nop
|
| - // call <on-stack replacment>
|
| - // test eax, <loop nesting depth>
|
| - // ok:
|
| - ASSERT(*(call_target_address - 3) == 0x73 && // jae
|
| - *(call_target_address - 2) == 0x07 && // offset
|
| - *(call_target_address - 1) == 0xe8); // call
|
| - *(call_target_address - 3) = 0x90; // nop
|
| - *(call_target_address - 2) = 0x90; // nop
|
| - Assembler::set_target_address_at(call_target_address,
|
| - replacement_code->entry());
|
| + Address call_target_address = pc_after - kIntSize;
|
| + ASSERT(check_code->entry() ==
|
| + Assembler::target_address_at(call_target_address));
|
| + // The stack check code matches the pattern:
|
| + //
|
| + // cmp esp, <limit>
|
| + // jae ok
|
| + // call <stack guard>
|
| + // test eax, <loop nesting depth>
|
| + // ok: ...
|
| + //
|
| + // We will patch away the branch so the code is:
|
| + //
|
| + // cmp esp, <limit> ;; Not changed
|
| + // nop
|
| + // nop
|
| + // call <on-stack replacment>
|
| + // test eax, <loop nesting depth>
|
| + // ok:
|
| + ASSERT(*(call_target_address - 3) == 0x73 && // jae
|
| + *(call_target_address - 2) == 0x07 && // offset
|
| + *(call_target_address - 1) == 0xe8); // call
|
| + *(call_target_address - 3) = 0x90; // nop
|
| + *(call_target_address - 2) = 0x90; // nop
|
| + Assembler::set_target_address_at(call_target_address,
|
| + replacement_code->entry());
|
| }
|
|
|
|
|
| void Deoptimizer::RevertStackCheckCodeAt(Address pc_after,
|
| Code* check_code,
|
| Code* replacement_code) {
|
| - Address call_target_address = pc_after - kPointerSize;
|
| + Address call_target_address = pc_after - kIntSize;
|
| ASSERT(replacement_code->entry() ==
|
| Assembler::target_address_at(call_target_address));
|
| // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to
|
| @@ -431,14 +433,16 @@
|
| fp_value, output_offset, value);
|
| }
|
|
|
| - // The context can be gotten from the function so long as we don't
|
| - // optimize functions that need local contexts.
|
| + // For the bottommost output frame the context can be gotten from the input
|
| + // frame. For all subsequent output frames it can be gotten from the function
|
| + // so long as we don't inline functions that need local contexts.
|
| output_offset -= kPointerSize;
|
| input_offset -= kPointerSize;
|
| - value = reinterpret_cast<uint32_t>(function->context());
|
| - // The context for the bottommost output frame should also agree with the
|
| - // input frame.
|
| - ASSERT(!is_bottommost || input_->GetFrameSlot(input_offset) == value);
|
| + if (is_bottommost) {
|
| + value = input_->GetFrameSlot(input_offset);
|
| + } else {
|
| + value = reinterpret_cast<uint32_t>(function->context());
|
| + }
|
| output_frame->SetFrameSlot(output_offset, value);
|
| if (is_topmost) output_frame->SetRegister(esi.code(), value);
|
| if (FLAG_trace_deopt) {
|
|
|