Commit 1910fcc3 authored by Juliana Franco's avatar Juliana Franco Committed by Commit Bot

[deoptimizer] Add trampoline pc to the DeoptimizationInputData.

Extend the deoptimization jump-table in optimized code objects
to also contain entries for lazy deoptimization exits, and
introduce a trampoline pc in the DeoptimizationInputData,
which maps back from the return-site to the jump-table offset.

Bug: v8:6562, v8:6561
Change-Id: Id085d5467e3ceff251c2ec2768329a9e22c0aff6
Reviewed-on: https://chromium-review.googlesource.com/563403
Commit-Queue: Juliana Patricia Vicente Franco <jupvfranco@google.com>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46501}
parent 2e1f5567
...@@ -193,7 +193,11 @@ void CodeGenerator::AssembleCode() { ...@@ -193,7 +193,11 @@ void CodeGenerator::AssembleCode() {
// Assemble all eager deoptimization exits. // Assemble all eager deoptimization exits.
for (DeoptimizationExit* exit : deoptimization_exits_) { for (DeoptimizationExit* exit : deoptimization_exits_) {
tasm()->bind(exit->label()); tasm()->bind(exit->label());
AssembleDeoptimizerCall(exit->deoptimization_id(), exit->pos()); int trampoline_pc = tasm()->pc_offset();
int deoptimization_id = exit->deoptimization_id();
DeoptimizationState* ds = deoptimization_states_[deoptimization_id];
ds->set_trampoline_pc(trampoline_pc);
AssembleDeoptimizerCall(deoptimization_id, exit->pos());
} }
// Ensure there is space for lazy deoptimization in the code. // Ensure there is space for lazy deoptimization in the code.
...@@ -599,10 +603,11 @@ void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) { ...@@ -599,10 +603,11 @@ void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) {
for (int i = 0; i < deopt_count; i++) { for (int i = 0; i < deopt_count; i++) {
DeoptimizationState* deoptimization_state = deoptimization_states_[i]; DeoptimizationState* deoptimization_state = deoptimization_states_[i];
data->SetBytecodeOffset(i, deoptimization_state->bailout_id()); data->SetBytecodeOffset(i, deoptimization_state->bailout_id());
CHECK(deoptimization_states_[i]); CHECK(deoptimization_state);
data->SetTranslationIndex( data->SetTranslationIndex(
i, Smi::FromInt(deoptimization_states_[i]->translation_id())); i, Smi::FromInt(deoptimization_state->translation_id()));
data->SetArgumentsStackHeight(i, Smi::kZero); data->SetTrampolinePc(i,
Smi::FromInt(deoptimization_state->trampoline_pc()));
data->SetPc(i, Smi::FromInt(deoptimization_state->pc_offset())); data->SetPc(i, Smi::FromInt(deoptimization_state->pc_offset()));
} }
...@@ -641,6 +646,11 @@ void CodeGenerator::RecordCallPosition(Instruction* instr) { ...@@ -641,6 +646,11 @@ void CodeGenerator::RecordCallPosition(Instruction* instr) {
int pc_offset = tasm()->pc_offset(); int pc_offset = tasm()->pc_offset();
int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset, int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset,
descriptor->state_combine()); descriptor->state_combine());
DeoptimizationExit* const exit = new (zone())
DeoptimizationExit(deopt_state_id, current_source_position_);
deoptimization_exits_.push_back(exit);
// If the pre-call frame state differs from the post-call one, produce the // If the pre-call frame state differs from the post-call one, produce the
// pre-call frame state, too. // pre-call frame state, too.
// TODO(jarin) We might want to avoid building the pre-call frame state // TODO(jarin) We might want to avoid building the pre-call frame state
...@@ -978,7 +988,6 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation, ...@@ -978,7 +988,6 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
} }
} }
void CodeGenerator::MarkLazyDeoptSite() { void CodeGenerator::MarkLazyDeoptSite() {
last_lazy_deopt_pc_ = tasm()->pc_offset(); last_lazy_deopt_pc_ = tasm()->pc_offset();
} }
...@@ -987,6 +996,7 @@ DeoptimizationExit* CodeGenerator::AddDeoptimizationExit( ...@@ -987,6 +996,7 @@ DeoptimizationExit* CodeGenerator::AddDeoptimizationExit(
Instruction* instr, size_t frame_state_offset) { Instruction* instr, size_t frame_state_offset) {
int const deoptimization_id = BuildTranslation( int const deoptimization_id = BuildTranslation(
instr, -1, frame_state_offset, OutputFrameStateCombine::Ignore()); instr, -1, frame_state_offset, OutputFrameStateCombine::Ignore());
DeoptimizationExit* const exit = new (zone()) DeoptimizationExit* const exit = new (zone())
DeoptimizationExit(deoptimization_id, current_source_position_); DeoptimizationExit(deoptimization_id, current_source_position_);
deoptimization_exits_.push_back(exit); deoptimization_exits_.push_back(exit);
...@@ -998,7 +1008,6 @@ OutOfLineCode::OutOfLineCode(CodeGenerator* gen) ...@@ -998,7 +1008,6 @@ OutOfLineCode::OutOfLineCode(CodeGenerator* gen)
gen->ools_ = this; gen->ools_ = this;
} }
OutOfLineCode::~OutOfLineCode() {} OutOfLineCode::~OutOfLineCode() {}
} // namespace compiler } // namespace compiler
......
...@@ -282,13 +282,16 @@ class CodeGenerator final : public GapResolver::Assembler { ...@@ -282,13 +282,16 @@ class CodeGenerator final : public GapResolver::Assembler {
translation_id_(translation_id), translation_id_(translation_id),
pc_offset_(pc_offset), pc_offset_(pc_offset),
kind_(kind), kind_(kind),
reason_(reason) {} reason_(reason),
trampoline_pc_(-1) {}
BailoutId bailout_id() const { return bailout_id_; } BailoutId bailout_id() const { return bailout_id_; }
int translation_id() const { return translation_id_; } int translation_id() const { return translation_id_; }
int pc_offset() const { return pc_offset_; } int pc_offset() const { return pc_offset_; }
DeoptimizeKind kind() const { return kind_; } DeoptimizeKind kind() const { return kind_; }
DeoptimizeReason reason() const { return reason_; } DeoptimizeReason reason() const { return reason_; }
int trampoline_pc() { return trampoline_pc_; }
void set_trampoline_pc(int t_pc) { trampoline_pc_ = t_pc; }
private: private:
BailoutId bailout_id_; BailoutId bailout_id_;
...@@ -296,6 +299,7 @@ class CodeGenerator final : public GapResolver::Assembler { ...@@ -296,6 +299,7 @@ class CodeGenerator final : public GapResolver::Assembler {
int pc_offset_; int pc_offset_;
DeoptimizeKind kind_; DeoptimizeKind kind_;
DeoptimizeReason reason_; DeoptimizeReason reason_;
int trampoline_pc_;
}; };
struct HandlerInfo { struct HandlerInfo {
......
...@@ -421,6 +421,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function, Code* code) { ...@@ -421,6 +421,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function, Code* code) {
TimerEventScope<TimerEventDeoptimizeCode> timer(isolate); TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
TRACE_EVENT0("v8", "V8.DeoptimizeCode"); TRACE_EVENT0("v8", "V8.DeoptimizeCode");
if (code == nullptr) code = function->code(); if (code == nullptr) code = function->code();
if (code->kind() == Code::OPTIMIZED_FUNCTION) { if (code->kind() == Code::OPTIMIZED_FUNCTION) {
// Mark the code for deoptimization and unlink any functions that also // Mark the code for deoptimization and unlink any functions that also
// refer to that code. The code cannot be shared across native contexts, // refer to that code. The code cannot be shared across native contexts,
...@@ -1064,10 +1065,7 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame, ...@@ -1064,10 +1065,7 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero); intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero);
Register context_reg = JavaScriptFrame::context_register(); Register context_reg = JavaScriptFrame::context_register();
output_frame->SetRegister(context_reg.code(), context_value); output_frame->SetRegister(context_reg.code(), context_value);
}
// Set the continuation for the topmost frame. // Set the continuation for the topmost frame.
if (is_topmost) {
Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized); Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
if (bailout_type_ == LAZY) { if (bailout_type_ == LAZY) {
continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
...@@ -2035,8 +2033,8 @@ unsigned Deoptimizer::ComputeInputFrameSize() const { ...@@ -2035,8 +2033,8 @@ unsigned Deoptimizer::ComputeInputFrameSize() const {
unsigned result = fixed_size_above_fp + fp_to_sp_delta_; unsigned result = fixed_size_above_fp + fp_to_sp_delta_;
if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
unsigned stack_slots = compiled_code_->stack_slots(); unsigned stack_slots = compiled_code_->stack_slots();
unsigned outgoing_size = unsigned outgoing_size = 0;
ComputeOutgoingArgumentSize(compiled_code_, bailout_id_); // ComputeOutgoingArgumentSize(compiled_code_, bailout_id_);
CHECK_EQ(fixed_size_above_fp + (stack_slots * kPointerSize) - CHECK_EQ(fixed_size_above_fp + (stack_slots * kPointerSize) -
CommonFrameConstants::kFixedFrameSizeAboveFp + outgoing_size, CommonFrameConstants::kFixedFrameSizeAboveFp + outgoing_size,
result); result);
...@@ -2066,16 +2064,6 @@ unsigned Deoptimizer::ComputeIncomingArgumentSize(SharedFunctionInfo* shared) { ...@@ -2066,16 +2064,6 @@ unsigned Deoptimizer::ComputeIncomingArgumentSize(SharedFunctionInfo* shared) {
return (shared->internal_formal_parameter_count() + 1) * kPointerSize; return (shared->internal_formal_parameter_count() + 1) * kPointerSize;
} }
// static
unsigned Deoptimizer::ComputeOutgoingArgumentSize(Code* code,
unsigned bailout_id) {
DeoptimizationInputData* data =
DeoptimizationInputData::cast(code->deoptimization_data());
unsigned height = data->ArgumentsStackHeight(bailout_id)->value();
return height * kPointerSize;
}
void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate, void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
BailoutType type, BailoutType type,
int max_entry_id) { int max_entry_id) {
......
...@@ -2618,7 +2618,7 @@ DEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>) ...@@ -2618,7 +2618,7 @@ DEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
DEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi) DEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi)
DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi) DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
DEFINE_DEOPT_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi) DEFINE_DEOPT_ENTRY_ACCESSORS(TrampolinePc, Smi)
DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi) DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
BailoutId DeoptimizationInputData::BytecodeOffset(int i) { BailoutId DeoptimizationInputData::BytecodeOffset(int i) {
......
...@@ -14310,26 +14310,26 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint( ...@@ -14310,26 +14310,26 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(
int deopt_count = DeoptCount(); int deopt_count = DeoptCount();
os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n"; os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n";
if (0 != deopt_count) { if (0 != deopt_count) {
os << " index bytecode-offset argc pc"; os << " index bytecode-offset trampoline_pc pc";
if (FLAG_print_code_verbose) os << " commands"; if (FLAG_print_code_verbose) os << " commands";
os << "\n"; os << "\n";
} }
for (int i = 0; i < deopt_count; i++) { for (int i = 0; i < deopt_count; i++) {
os << std::setw(6) << i << " " << std::setw(15) os << std::setw(6) << i << " " << std::setw(15)
<< BytecodeOffset(i).ToInt() << " " << std::setw(6) << BytecodeOffset(i).ToInt() << " " << std::setw(13) << std::hex
<< ArgumentsStackHeight(i)->value() << " "; << TrampolinePc(i)->value() << " " << std::setw(6);
int pc_value = Pc(i)->value(); int pc_value = Pc(i)->value();
if (pc_value != -1) { if (pc_value != -1) {
os << std::setw(6) << std::hex << pc_value; os << pc_value << std::dec;
} else { } else {
os << std::setw(6) << "NA"; os << "NA";
} }
os << std::dec;
if (!FLAG_print_code_verbose) { if (!FLAG_print_code_verbose) {
os << "\n"; os << "\n";
continue; continue;
} }
// Print details of the frame translation. // Print details of the frame translation.
int translation_index = TranslationIndex(i)->value(); int translation_index = TranslationIndex(i)->value();
TranslationIterator iterator(TranslationByteArray(), translation_index); TranslationIterator iterator(TranslationByteArray(), translation_index);
...@@ -14345,7 +14345,7 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint( ...@@ -14345,7 +14345,7 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(
while (iterator.HasNext() && while (iterator.HasNext() &&
Translation::BEGIN != Translation::BEGIN !=
(opcode = static_cast<Translation::Opcode>(iterator.Next()))) { (opcode = static_cast<Translation::Opcode>(iterator.Next()))) {
os << std::setw(40) << " " << Translation::StringFor(opcode) << " "; os << std::setw(47) << " " << Translation::StringFor(opcode) << " ";
switch (opcode) { switch (opcode) {
case Translation::BEGIN: case Translation::BEGIN:
......
...@@ -3481,7 +3481,7 @@ class DeoptimizationInputData: public FixedArray { ...@@ -3481,7 +3481,7 @@ class DeoptimizationInputData: public FixedArray {
// Offsets of deopt entry elements relative to the start of the entry. // Offsets of deopt entry elements relative to the start of the entry.
static const int kBytecodeOffsetRawOffset = 0; static const int kBytecodeOffsetRawOffset = 0;
static const int kTranslationIndexOffset = 1; static const int kTranslationIndexOffset = 1;
static const int kArgumentsStackHeightOffset = 2; static const int kTrampolinePcOffset = 2;
static const int kPcOffset = 3; static const int kPcOffset = 3;
static const int kDeoptEntrySize = 4; static const int kDeoptEntrySize = 4;
...@@ -3509,7 +3509,7 @@ class DeoptimizationInputData: public FixedArray { ...@@ -3509,7 +3509,7 @@ class DeoptimizationInputData: public FixedArray {
DECL_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi) DECL_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi)
DECL_ENTRY_ACCESSORS(TranslationIndex, Smi) DECL_ENTRY_ACCESSORS(TranslationIndex, Smi)
DECL_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi) DECL_ENTRY_ACCESSORS(TrampolinePc, Smi)
DECL_ENTRY_ACCESSORS(Pc, Smi) DECL_ENTRY_ACCESSORS(Pc, Smi)
#undef DECL_ENTRY_ACCESSORS #undef DECL_ENTRY_ACCESSORS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment