Index: src/mips/deoptimizer-mips.cc |
=================================================================== |
--- src/mips/deoptimizer-mips.cc (revision 10035) |
+++ src/mips/deoptimizer-mips.cc (working copy) |
@@ -45,12 +45,6 @@ |
} |
-void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) { |
- // Nothing to do. No new relocation information is written for lazy |
- // deoptimization on MIPS. |
-} |
- |
- |
void Deoptimizer::DeoptimizeFunction(JSFunction* function) { |
HandleScope scope; |
AssertNoAllocation no_allocation; |
@@ -59,58 +53,38 @@ |
// Get the optimized code. |
Code* code = function->code(); |
+ Address code_start_address = code->instruction_start(); |
// Invalidate the relocation information, as it will become invalid by the |
// code patching below, and is not needed any more. |
code->InvalidateRelocation(); |
- // For each return after a safepoint insert an absolute call to the |
- // corresponding deoptimization entry. |
- unsigned last_pc_offset = 0; |
- SafepointTable table(function->code()); |
- for (unsigned i = 0; i < table.length(); i++) { |
- unsigned pc_offset = table.GetPcOffset(i); |
- SafepointEntry safepoint_entry = table.GetEntry(i); |
- int deoptimization_index = safepoint_entry.deoptimization_index(); |
- int gap_code_size = safepoint_entry.gap_code_size(); |
- // Check that we did not shoot past next safepoint. |
- CHECK(pc_offset >= last_pc_offset); |
+ // For each LLazyBailout instruction insert a call to the corresponding |
+ // deoptimization entry. |
+ DeoptimizationInputData* deopt_data = |
+ DeoptimizationInputData::cast(code->deoptimization_data()); |
#ifdef DEBUG |
- // Destroy the code which is not supposed to be run again. |
- int instructions = (pc_offset - last_pc_offset) / Assembler::kInstrSize; |
- CodePatcher destroyer(code->instruction_start() + last_pc_offset, |
- instructions); |
- for (int x = 0; x < instructions; x++) { |
- destroyer.masm()->break_(0); |
- } |
+ Address prev_call_address = NULL; |
#endif |
- last_pc_offset = pc_offset; |
- if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) { |
- Address deoptimization_entry = Deoptimizer::GetDeoptimizationEntry( |
- deoptimization_index, Deoptimizer::LAZY); |
- last_pc_offset += gap_code_size; |
- int call_size_in_bytes = MacroAssembler::CallSize(deoptimization_entry, |
- RelocInfo::NONE); |
- int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize; |
- ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0); |
- ASSERT(call_size_in_bytes <= patch_size()); |
- CodePatcher patcher(code->instruction_start() + last_pc_offset, |
- call_size_in_words); |
- patcher.masm()->Call(deoptimization_entry, RelocInfo::NONE); |
- last_pc_offset += call_size_in_bytes; |
- } |
- } |
+ for (int i = 0; i < deopt_data->DeoptCount(); i++) { |
+ if (deopt_data->Pc(i)->value() == -1) continue; |
+ Address call_address = code_start_address + deopt_data->Pc(i)->value(); |
+ Address deopt_entry = GetDeoptimizationEntry(i, LAZY); |
+ int call_size_in_bytes = MacroAssembler::CallSize(deopt_entry, |
+ RelocInfo::NONE); |
+ int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize; |
+ ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0); |
+ ASSERT(call_size_in_bytes <= patch_size()); |
+ CodePatcher patcher(call_address, call_size_in_words); |
+ patcher.masm()->Call(deopt_entry, RelocInfo::NONE); |
+ ASSERT(prev_call_address == NULL || |
+ call_address >= prev_call_address + patch_size()); |
+ ASSERT(call_address + patch_size() <= code->instruction_end()); |
#ifdef DEBUG |
- // Destroy the code which is not supposed to be run again. |
- int instructions = |
- (code->safepoint_table_offset() - last_pc_offset) / Assembler::kInstrSize; |
- CodePatcher destroyer(code->instruction_start() + last_pc_offset, |
- instructions); |
- for (int x = 0; x < instructions; x++) { |
- destroyer.masm()->break_(0); |
- } |
+ prev_call_address = call_address; |
#endif |
+ } |
Isolate* isolate = code->GetIsolate(); |