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() {
// Assemble all eager deoptimization exits.
for (DeoptimizationExit* exit : deoptimization_exits_) {
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.
......@@ -599,10 +603,11 @@ void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) {
for (int i = 0; i < deopt_count; i++) {
DeoptimizationState* deoptimization_state = deoptimization_states_[i];
data->SetBytecodeOffset(i, deoptimization_state->bailout_id());
CHECK(deoptimization_states_[i]);
CHECK(deoptimization_state);
data->SetTranslationIndex(
i, Smi::FromInt(deoptimization_states_[i]->translation_id()));
data->SetArgumentsStackHeight(i, Smi::kZero);
i, Smi::FromInt(deoptimization_state->translation_id()));
data->SetTrampolinePc(i,
Smi::FromInt(deoptimization_state->trampoline_pc()));
data->SetPc(i, Smi::FromInt(deoptimization_state->pc_offset()));
}
......@@ -641,6 +646,11 @@ void CodeGenerator::RecordCallPosition(Instruction* instr) {
int pc_offset = tasm()->pc_offset();
int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset,
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
// pre-call frame state, too.
// TODO(jarin) We might want to avoid building the pre-call frame state
......@@ -978,7 +988,6 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
}
}
void CodeGenerator::MarkLazyDeoptSite() {
last_lazy_deopt_pc_ = tasm()->pc_offset();
}
......@@ -987,6 +996,7 @@ DeoptimizationExit* CodeGenerator::AddDeoptimizationExit(
Instruction* instr, size_t frame_state_offset) {
int const deoptimization_id = BuildTranslation(
instr, -1, frame_state_offset, OutputFrameStateCombine::Ignore());
DeoptimizationExit* const exit = new (zone())
DeoptimizationExit(deoptimization_id, current_source_position_);
deoptimization_exits_.push_back(exit);
......@@ -998,7 +1008,6 @@ OutOfLineCode::OutOfLineCode(CodeGenerator* gen)
gen->ools_ = this;
}
OutOfLineCode::~OutOfLineCode() {}
} // namespace compiler
......
......@@ -282,13 +282,16 @@ class CodeGenerator final : public GapResolver::Assembler {
translation_id_(translation_id),
pc_offset_(pc_offset),
kind_(kind),
reason_(reason) {}
reason_(reason),
trampoline_pc_(-1) {}
BailoutId bailout_id() const { return bailout_id_; }
int translation_id() const { return translation_id_; }
int pc_offset() const { return pc_offset_; }
DeoptimizeKind kind() const { return kind_; }
DeoptimizeReason reason() const { return reason_; }
int trampoline_pc() { return trampoline_pc_; }
void set_trampoline_pc(int t_pc) { trampoline_pc_ = t_pc; }
private:
BailoutId bailout_id_;
......@@ -296,6 +299,7 @@ class CodeGenerator final : public GapResolver::Assembler {
int pc_offset_;
DeoptimizeKind kind_;
DeoptimizeReason reason_;
int trampoline_pc_;
};
struct HandlerInfo {
......
......@@ -421,6 +421,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function, Code* code) {
TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
TRACE_EVENT0("v8", "V8.DeoptimizeCode");
if (code == nullptr) code = function->code();
if (code->kind() == Code::OPTIMIZED_FUNCTION) {
// Mark the code for deoptimization and unlink any functions that also
// refer to that code. The code cannot be shared across native contexts,
......@@ -1064,10 +1065,7 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
intptr_t context_value = reinterpret_cast<intptr_t>(Smi::kZero);
Register context_reg = JavaScriptFrame::context_register();
output_frame->SetRegister(context_reg.code(), context_value);
}
// Set the continuation for the topmost frame.
if (is_topmost) {
// Set the continuation for the topmost frame.
Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
if (bailout_type_ == LAZY) {
continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
......@@ -2035,8 +2033,8 @@ unsigned Deoptimizer::ComputeInputFrameSize() const {
unsigned result = fixed_size_above_fp + fp_to_sp_delta_;
if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
unsigned stack_slots = compiled_code_->stack_slots();
unsigned outgoing_size =
ComputeOutgoingArgumentSize(compiled_code_, bailout_id_);
unsigned outgoing_size = 0;
// ComputeOutgoingArgumentSize(compiled_code_, bailout_id_);
CHECK_EQ(fixed_size_above_fp + (stack_slots * kPointerSize) -
CommonFrameConstants::kFixedFrameSizeAboveFp + outgoing_size,
result);
......@@ -2066,16 +2064,6 @@ unsigned Deoptimizer::ComputeIncomingArgumentSize(SharedFunctionInfo* shared) {
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,
BailoutType type,
int max_entry_id) {
......
......@@ -2618,7 +2618,7 @@ DEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
DEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, 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)
BailoutId DeoptimizationInputData::BytecodeOffset(int i) {
......
......@@ -14310,26 +14310,26 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(
int deopt_count = DeoptCount();
os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n";
if (0 != deopt_count) {
os << " index bytecode-offset argc pc";
os << " index bytecode-offset trampoline_pc pc";
if (FLAG_print_code_verbose) os << " commands";
os << "\n";
}
for (int i = 0; i < deopt_count; i++) {
os << std::setw(6) << i << " " << std::setw(15)
<< BytecodeOffset(i).ToInt() << " " << std::setw(6)
<< ArgumentsStackHeight(i)->value() << " ";
<< BytecodeOffset(i).ToInt() << " " << std::setw(13) << std::hex
<< TrampolinePc(i)->value() << " " << std::setw(6);
int pc_value = Pc(i)->value();
if (pc_value != -1) {
os << std::setw(6) << std::hex << pc_value;
os << pc_value << std::dec;
} else {
os << std::setw(6) << "NA";
os << "NA";
}
os << std::dec;
if (!FLAG_print_code_verbose) {
os << "\n";
continue;
}
// Print details of the frame translation.
int translation_index = TranslationIndex(i)->value();
TranslationIterator iterator(TranslationByteArray(), translation_index);
......@@ -14345,7 +14345,7 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(
while (iterator.HasNext() &&
Translation::BEGIN !=
(opcode = static_cast<Translation::Opcode>(iterator.Next()))) {
os << std::setw(40) << " " << Translation::StringFor(opcode) << " ";
os << std::setw(47) << " " << Translation::StringFor(opcode) << " ";
switch (opcode) {
case Translation::BEGIN:
......
......@@ -3481,7 +3481,7 @@ class DeoptimizationInputData: public FixedArray {
// Offsets of deopt entry elements relative to the start of the entry.
static const int kBytecodeOffsetRawOffset = 0;
static const int kTranslationIndexOffset = 1;
static const int kArgumentsStackHeightOffset = 2;
static const int kTrampolinePcOffset = 2;
static const int kPcOffset = 3;
static const int kDeoptEntrySize = 4;
......@@ -3509,7 +3509,7 @@ class DeoptimizationInputData: public FixedArray {
DECL_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi)
DECL_ENTRY_ACCESSORS(TranslationIndex, Smi)
DECL_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
DECL_ENTRY_ACCESSORS(TrampolinePc, Smi)
DECL_ENTRY_ACCESSORS(Pc, Smi)
#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