| 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));
|
| }
|
|
|
|
|
|
|