Index: src/compiler/code-generator.cc |
diff --git a/src/compiler/code-generator.cc b/src/compiler/code-generator.cc |
index 5a5d9f9674fcc1203f12f81b47e0dc223a25b9e5..1cbb59643705bd222f1b44f89b213e99f7e655a3 100644 |
--- a/src/compiler/code-generator.cc |
+++ b/src/compiler/code-generator.cc |
@@ -53,6 +53,7 @@ Handle<Code> CodeGenerator::GenerateCode() { |
FinishCode(masm()); |
+ UpdateSafepointsWithDeoptimizationPc(); |
safepoints()->Emit(masm(), frame()->GetSpillSlotCount()); |
// TODO(titzer): what are the right code flags here? |
@@ -76,9 +77,10 @@ Handle<Code> CodeGenerator::GenerateCode() { |
} |
-void CodeGenerator::RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind, |
- int arguments, |
- Safepoint::DeoptMode deopt_mode) { |
+Safepoint::Id CodeGenerator::RecordSafepoint(PointerMap* pointers, |
+ Safepoint::Kind kind, |
+ int arguments, |
+ Safepoint::DeoptMode deopt_mode) { |
const ZoneList<InstructionOperand*>* operands = |
pointers->GetNormalizedOperands(); |
Safepoint safepoint = |
@@ -92,6 +94,7 @@ void CodeGenerator::RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind, |
safepoint.DefinePointerRegister(reg, zone()); |
} |
} |
+ return safepoint.id(); |
} |
@@ -172,13 +175,25 @@ void CodeGenerator::AssembleGap(GapInstruction* instr) { |
} |
+void CodeGenerator::UpdateSafepointsWithDeoptimizationPc() { |
+ int patch_count = static_cast<int>(lazy_deoptimization_entries_.size()); |
+ for (int i = 0; i < patch_count; ++i) { |
+ LazyDeoptimizationEntry entry = lazy_deoptimization_entries_[i]; |
+ // TODO(jarin) make sure that there is no code (other than nops) |
+ // between the call position and the continuation position. |
+ safepoints()->SetDeoptimizationPc(entry.safepoint_id(), |
+ entry.deoptimization()->pos()); |
+ } |
+} |
+ |
+ |
void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) { |
CompilationInfo* info = linkage()->info(); |
int deopt_count = code()->GetDeoptimizationEntryCount(); |
int patch_count = static_cast<int>(lazy_deoptimization_entries_.size()); |
if (patch_count == 0 && deopt_count == 0) return; |
- Handle<DeoptimizationInputData> data = DeoptimizationInputData::New( |
- isolate(), deopt_count, patch_count, TENURED); |
+ Handle<DeoptimizationInputData> data = |
+ DeoptimizationInputData::New(isolate(), deopt_count, TENURED); |
Handle<ByteArray> translation_array = |
translations_.CreateByteArray(isolate()->factory()); |
@@ -222,13 +237,6 @@ void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) { |
data->SetPc(i, Smi::FromInt(-1)); |
} |
- // Populate the return address patcher entries. |
- for (int i = 0; i < patch_count; ++i) { |
- LazyDeoptimizationEntry entry = lazy_deoptimization_entries_[i]; |
- data->SetReturnAddressPc(i, Smi::FromInt(entry.position_after_call())); |
- data->SetPatchedAddressPc(i, Smi::FromInt(entry.deoptimization()->pos())); |
- } |
- |
code_object->set_deoptimization_data(*data); |
} |
@@ -238,30 +246,43 @@ void CodeGenerator::AddSafepointAndDeopt(Instruction* instr) { |
static_cast<CallDescriptor::DeoptimizationSupport>( |
MiscField::decode(instr->opcode())); |
- if ((deopt & CallDescriptor::kLazyDeoptimization) != 0) { |
- RecordLazyDeoptimizationEntry(instr); |
- } |
- |
bool needs_frame_state = (deopt & CallDescriptor::kNeedsFrameState) != 0; |
- RecordSafepoint( |
+ Safepoint::Id safepoint_id = RecordSafepoint( |
instr->pointer_map(), Safepoint::kSimple, 0, |
needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt); |
- if ((deopt & CallDescriptor::kNeedsFrameState) != 0) { |
+ if ((deopt & CallDescriptor::kLazyDeoptimization) != 0) { |
+ RecordLazyDeoptimizationEntry(instr, safepoint_id); |
+ } |
+ |
+ if (needs_frame_state) { |
// If the frame state is present, it starts at argument 1 |
// (just after the code address). |
InstructionOperandConverter converter(this, instr); |
// Argument 1 is deoptimization id. |
int deoptimization_id = converter.ToConstant(instr->InputAt(1)).ToInt32(); |
// The actual frame state values start with argument 2. |
- BuildTranslation(instr, 2, deoptimization_id); |
+ int first_state_value_offset = 2; |
+#if DEBUG |
+ // Make sure all the values live in stack slots or they are immediates. |
+ // (The values should not live in register because registers are clobbered |
+ // by calls.) |
+ FrameStateDescriptor* descriptor = |
+ code()->GetDeoptimizationEntry(deoptimization_id); |
+ for (int i = 0; i < descriptor->size(); i++) { |
+ InstructionOperand* op = instr->InputAt(first_state_value_offset + i); |
+ CHECK(op->IsStackSlot() || op->IsImmediate()); |
+ } |
+#endif |
+ BuildTranslation(instr, first_state_value_offset, deoptimization_id); |
safepoints()->RecordLazyDeoptimizationIndex(deoptimization_id); |
} |
} |
-void CodeGenerator::RecordLazyDeoptimizationEntry(Instruction* instr) { |
+void CodeGenerator::RecordLazyDeoptimizationEntry(Instruction* instr, |
+ Safepoint::Id safepoint_id) { |
InstructionOperandConverter i(this, instr); |
Label after_call; |
@@ -276,8 +297,8 @@ void CodeGenerator::RecordLazyDeoptimizationEntry(Instruction* instr) { |
Label* cont_label = code_->GetLabel(cont_block); |
Label* deopt_label = code_->GetLabel(deopt_block); |
- lazy_deoptimization_entries_.push_back( |
- LazyDeoptimizationEntry(after_call.pos(), cont_label, deopt_label)); |
+ lazy_deoptimization_entries_.push_back(LazyDeoptimizationEntry( |
+ after_call.pos(), cont_label, deopt_label, safepoint_id)); |
} |