Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1698)

Unified Diff: src/deoptimizer.cc

Issue 1761303002: [deoptimizer] Simplify handling of bottommost output frames. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@deopt-no-alignment-padding
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/deoptimizer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/deoptimizer.cc
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 942b5284a377a811c367ce76618e3765bbc1197e..7f4ace092aea6e91c6dc6e3d831466ffd380a979 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -481,6 +481,12 @@ Deoptimizer::Deoptimizer(Isolate* isolate, JSFunction* function,
output_count_(0),
jsframe_count_(0),
output_(nullptr),
+ caller_frame_top_(0),
+ caller_fp_(0),
+ caller_pc_(0),
+ caller_constant_pool_(0),
+ input_frame_context_(0),
+ stack_fp_(0),
trace_scope_(nullptr) {
if (isolate->deoptimizer_lazy_throw()) {
isolate->set_deoptimizer_lazy_throw(false);
@@ -762,8 +768,27 @@ void Deoptimizer::DoComputeOutputFrames() {
}
output_count_ = static_cast<int>(count);
- Register fp_reg = JavaScriptFrame::fp_register();
- stack_fp_ = reinterpret_cast<Address>(input_->GetRegister(fp_reg.code()));
+ {
+ // Read caller's PC, caller's FP and caller's constant pool values
+ // from input frame. Compute caller's frame top address.
+
+ Register fp_reg = JavaScriptFrame::fp_register();
+ stack_fp_ = input_->GetRegister(fp_reg.code());
+
+ caller_frame_top_ = stack_fp_ + ComputeInputFrameAboveFpFixedSize();
+
+ Address fp_address = input_->GetFramePointerAddress();
+ caller_fp_ = Memory::intptr_at(fp_address);
+ caller_pc_ =
+ Memory::intptr_at(fp_address + StandardFrameConstants::kCallerPCOffset);
+ input_frame_context_ =
+ Memory::intptr_at(fp_address + StandardFrameConstants::kContextOffset);
+
+ if (FLAG_enable_embedded_constant_pool) {
+ caller_constant_pool_ = Memory::intptr_at(
+ fp_address + StandardFrameConstants::kConstantPoolOffset);
+ }
+ }
// Translate each output frame.
for (size_t i = 0; i < count; ++i) {
@@ -855,7 +880,6 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
// The 'fixed' part of the frame consists of the incoming parameters and
// the part described by JavaScriptFrameConstants.
unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared);
- unsigned input_frame_size = input_->GetFrameSize();
unsigned output_frame_size = height_in_bytes + fixed_frame_size;
// Allocate and store the output frame description.
@@ -875,13 +899,7 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
Register fp_reg = JavaScriptFrame::fp_register();
intptr_t top_address;
if (is_bottommost) {
- // 2 = context and function in the frame.
- // If the optimized frame had alignment padding, adjust the frame pointer
- // to point to the new position of the old frame pointer after padding
- // is removed. Subtract 2 * kPointerSize for the context and function slots.
- top_address = input_->GetRegister(fp_reg.code()) -
- StandardFrameConstants::kFixedFrameSizeFromFp -
- height_in_bytes;
+ top_address = caller_frame_top_ - output_frame_size;
} else {
top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
}
@@ -889,13 +907,11 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
// Compute the incoming parameter translation.
unsigned output_offset = output_frame_size;
- unsigned input_offset = input_frame_size;
for (int i = 0; i < parameter_count; ++i) {
output_offset -= kPointerSize;
WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
output_offset);
}
- input_offset -= (parameter_count * kPointerSize);
// There are no translation commands for the caller's pc and fp, the
// context, and the function. Synthesize their values and set them up
@@ -906,10 +922,9 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
// previous one. This frame's pc can be computed from the non-optimized
// function code and AST id of the bailout.
output_offset -= kPCOnStackSize;
- input_offset -= kPCOnStackSize;
intptr_t value;
if (is_bottommost) {
- value = input_->GetFrameSlot(input_offset);
+ value = caller_pc_;
} else {
value = output_[frame_index - 1]->GetPc();
}
@@ -921,15 +936,14 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
// read from the previous one. Also compute and set this frame's frame
// pointer.
output_offset -= kFPOnStackSize;
- input_offset -= kFPOnStackSize;
if (is_bottommost) {
- value = input_->GetFrameSlot(input_offset);
+ value = caller_fp_;
} else {
value = output_[frame_index - 1]->GetFp();
}
output_frame->SetCallerFp(output_offset, value);
intptr_t fp_value = top_address + output_offset;
- DCHECK(!is_bottommost || input_->GetRegister(fp_reg.code()) == fp_value);
+ DCHECK(!is_bottommost || stack_fp_ == fp_value);
output_frame->SetFp(fp_value);
if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value);
DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
@@ -939,9 +953,8 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
// from the input frame. For subsequent output frames, it can be read from
// the previous frame.
output_offset -= kPointerSize;
- input_offset -= kPointerSize;
if (is_bottommost) {
- value = input_->GetFrameSlot(input_offset);
+ value = caller_constant_pool_;
} else {
value = output_[frame_index - 1]->GetConstantPool();
}
@@ -955,7 +968,6 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
// so long as we don't inline functions that need local contexts.
Register context_reg = JavaScriptFrame::context_register();
output_offset -= kPointerSize;
- input_offset -= kPointerSize;
TranslatedFrame::iterator context_pos = value_iterator;
int context_input_index = input_index;
@@ -974,10 +986,8 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
// If the context was optimized away, just use the context from
// the activation. This should only apply to Crankshaft code.
CHECK(!compiled_code_->is_turbofanned());
- context =
- is_bottommost
- ? reinterpret_cast<Object*>(input_->GetFrameSlot(input_offset))
- : function->context();
+ context = is_bottommost ? reinterpret_cast<Object*>(input_frame_context_)
+ : function->context();
}
value = reinterpret_cast<intptr_t>(context);
output_frame->SetContext(value);
@@ -995,11 +1005,10 @@ void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) {
// The function was mentioned explicitly in the BEGIN_FRAME.
output_offset -= kPointerSize;
- input_offset -= kPointerSize;
value = reinterpret_cast<intptr_t>(function);
// The function for the bottommost output frame should also agree with the
// input frame.
- DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value);
+ DCHECK(!is_bottommost || reinterpret_cast<intptr_t>(function_) == value);
WriteValueToOutput(function, 0, frame_index, output_offset, "function ");
// Translate the rest of the frame.
@@ -1096,7 +1105,6 @@ void Deoptimizer::DoComputeInterpretedFrame(int frame_index,
// The 'fixed' part of the frame consists of the incoming parameters and
// the part described by InterpreterFrameConstants.
unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared);
- unsigned input_frame_size = input_->GetFrameSize();
unsigned output_frame_size = height_in_bytes + fixed_frame_size;
// Allocate and store the output frame description.
@@ -1118,11 +1126,7 @@ void Deoptimizer::DoComputeInterpretedFrame(int frame_index,
Register fp_reg = InterpretedFrame::fp_register();
intptr_t top_address;
if (is_bottommost) {
- // Subtract interpreter fixed frame size for the context function slots,
- // new,target and bytecode offset.
- top_address = input_->GetRegister(fp_reg.code()) -
- InterpreterFrameConstants::kFixedFrameSizeFromFp -
- height_in_bytes;
+ top_address = caller_frame_top_ - output_frame_size;
} else {
top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
}
@@ -1130,13 +1134,11 @@ void Deoptimizer::DoComputeInterpretedFrame(int frame_index,
// Compute the incoming parameter translation.
unsigned output_offset = output_frame_size;
- unsigned input_offset = input_frame_size;
for (int i = 0; i < parameter_count; ++i) {
output_offset -= kPointerSize;
WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
output_offset);
}
- input_offset -= (parameter_count * kPointerSize);
// There are no translation commands for the caller's pc and fp, the
// context, the function, new.target and the bytecode offset. Synthesize
@@ -1148,10 +1150,9 @@ void Deoptimizer::DoComputeInterpretedFrame(int frame_index,
// previous one. This frame's pc can be computed from the non-optimized
// function code and AST id of the bailout.
output_offset -= kPCOnStackSize;
- input_offset -= kPCOnStackSize;
intptr_t value;
if (is_bottommost) {
- value = input_->GetFrameSlot(input_offset);
+ value = caller_pc_;
} else {
value = output_[frame_index - 1]->GetPc();
}
@@ -1163,15 +1164,14 @@ void Deoptimizer::DoComputeInterpretedFrame(int frame_index,
// read from the previous one. Also compute and set this frame's frame
// pointer.
output_offset -= kFPOnStackSize;
- input_offset -= kFPOnStackSize;
if (is_bottommost) {
- value = input_->GetFrameSlot(input_offset);
+ value = caller_fp_;
} else {
value = output_[frame_index - 1]->GetFp();
}
output_frame->SetCallerFp(output_offset, value);
intptr_t fp_value = top_address + output_offset;
- DCHECK(!is_bottommost || input_->GetRegister(fp_reg.code()) == fp_value);
+ DCHECK(!is_bottommost || stack_fp_ == fp_value);
output_frame->SetFp(fp_value);
if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value);
DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
@@ -1181,9 +1181,8 @@ void Deoptimizer::DoComputeInterpretedFrame(int frame_index,
// from the input frame. For subsequent output frames, it can be read from
// the previous frame.
output_offset -= kPointerSize;
- input_offset -= kPointerSize;
if (is_bottommost) {
- value = input_->GetFrameSlot(input_offset);
+ value = caller_constant_pool_;
} else {
value = output_[frame_index - 1]->GetConstantPool();
}
@@ -1197,7 +1196,6 @@ void Deoptimizer::DoComputeInterpretedFrame(int frame_index,
// so long as we don't inline functions that need local contexts.
Register context_reg = InterpretedFrame::context_register();
output_offset -= kPointerSize;
- input_offset -= kPointerSize;
// When deoptimizing into a catch block, we need to take the context
// from a register that was specified in the handler table.
@@ -1225,31 +1223,27 @@ void Deoptimizer::DoComputeInterpretedFrame(int frame_index,
// The function was mentioned explicitly in the BEGIN_FRAME.
output_offset -= kPointerSize;
- input_offset -= kPointerSize;
value = reinterpret_cast<intptr_t>(function);
// The function for the bottommost output frame should also agree with the
// input frame.
- DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value);
+ DCHECK(!is_bottommost || reinterpret_cast<intptr_t>(function_) == value);
WriteValueToOutput(function, 0, frame_index, output_offset, "function ");
// The new.target slot is only used during function activiation which is
// before the first deopt point, so should never be needed. Just set it to
// undefined.
output_offset -= kPointerSize;
- input_offset -= kPointerSize;
Object* new_target = isolate_->heap()->undefined_value();
WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target ");
// Set the bytecode array pointer.
output_offset -= kPointerSize;
- input_offset -= kPointerSize;
Object* bytecode_array = shared->bytecode_array();
WriteValueToOutput(bytecode_array, 0, frame_index, output_offset,
"bytecode array ");
// The bytecode offset was mentioned explicitly in the BEGIN_FRAME.
output_offset -= kPointerSize;
- input_offset -= kPointerSize;
int raw_bytecode_offset =
BytecodeArray::kHeaderSize - kHeapObjectTag + bytecode_offset;
Smi* smi_bytecode_offset = Smi::FromInt(raw_bytecode_offset);
@@ -1736,7 +1730,6 @@ void Deoptimizer::DoComputeCompiledStubFrame(int frame_index) {
int height_in_bytes = kPointerSize * (param_count + stack_param_count) +
sizeof(Arguments) + kPointerSize;
int fixed_frame_size = StandardFrameConstants::kFixedFrameSize;
- int input_frame_size = input_->GetFrameSize();
int output_frame_size = height_in_bytes + fixed_frame_size;
if (trace_scope_ != NULL) {
PrintF(trace_scope_->file(),
@@ -1756,24 +1749,23 @@ void Deoptimizer::DoComputeCompiledStubFrame(int frame_index) {
// frame pointer and the output frame's height. Subtract space for the
// context and function slots.
Register fp_reg = StubFailureTrampolineFrame::fp_register();
- intptr_t top_address = input_->GetRegister(fp_reg.code()) -
- StandardFrameConstants::kFixedFrameSizeFromFp - height_in_bytes;
+ intptr_t top_address = stack_fp_ - // input_->GetRegister(fp_reg.code()) -
+ StandardFrameConstants::kFixedFrameSizeFromFp -
+ height_in_bytes;
output_frame->SetTop(top_address);
- // Read caller's PC (JSFunction continuation) from the input frame.
- unsigned input_frame_offset = input_frame_size - kPCOnStackSize;
+ // Set caller's PC (JSFunction continuation).
unsigned output_frame_offset = output_frame_size - kFPOnStackSize;
- intptr_t value = input_->GetFrameSlot(input_frame_offset);
+ intptr_t value = caller_pc_;
output_frame->SetCallerPc(output_frame_offset, value);
DebugPrintOutputSlot(value, frame_index, output_frame_offset,
"caller's pc\n");
- // Read caller's FP from the input frame, and set this frame's FP.
- input_frame_offset -= kFPOnStackSize;
- value = input_->GetFrameSlot(input_frame_offset);
+ // Set caller's FP from the input frame, and set this frame's FP.
+ value = caller_fp_;
output_frame_offset -= kFPOnStackSize;
output_frame->SetCallerFp(output_frame_offset, value);
- intptr_t frame_ptr = input_->GetRegister(fp_reg.code());
+ intptr_t frame_ptr = stack_fp_;
output_frame->SetRegister(fp_reg.code(), frame_ptr);
output_frame->SetFp(frame_ptr);
DebugPrintOutputSlot(value, frame_index, output_frame_offset,
@@ -1781,8 +1773,7 @@ void Deoptimizer::DoComputeCompiledStubFrame(int frame_index) {
if (FLAG_enable_embedded_constant_pool) {
// Read the caller's constant pool from the input frame.
- input_frame_offset -= kPointerSize;
- value = input_->GetFrameSlot(input_frame_offset);
+ value = caller_constant_pool_;
output_frame_offset -= kPointerSize;
output_frame->SetCallerConstantPool(output_frame_offset, value);
DebugPrintOutputSlot(value, frame_index, output_frame_offset,
@@ -1931,7 +1922,8 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) {
if (frame_index != 0) it->Advance();
}
- translated_state_.Prepare(it->frame()->has_adapted_arguments(), stack_fp_);
+ translated_state_.Prepare(it->frame()->has_adapted_arguments(),
+ reinterpret_cast<Address>(stack_fp_));
for (auto& materialization : values_to_materialize_) {
Handle<Object> value = materialization.value_->GetValue();
@@ -1948,7 +1940,8 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
reinterpret_cast<intptr_t>(*value);
}
- isolate_->materialized_object_store()->Remove(stack_fp_);
+ isolate_->materialized_object_store()->Remove(
+ reinterpret_cast<Address>(stack_fp_));
}
@@ -2006,25 +1999,28 @@ void Deoptimizer::DebugPrintOutputSlot(intptr_t value, int frame_index,
}
}
-
-unsigned Deoptimizer::ComputeInputFrameSize() const {
- unsigned fixed_size = StandardFrameConstants::kFixedFrameSize;
+unsigned Deoptimizer::ComputeInputFrameAboveFpFixedSize() const {
+ unsigned fixed_size = StandardFrameConstants::kFixedFrameSizeAboveFp;
if (!function_->IsSmi()) {
fixed_size += ComputeIncomingArgumentSize(function_->shared());
} else {
CHECK_EQ(Smi::cast(function_), Smi::FromInt(StackFrame::STUB));
}
+ return fixed_size;
+}
+
+unsigned Deoptimizer::ComputeInputFrameSize() const {
// The fp-to-sp delta already takes the context, constant pool pointer and the
// function into account so we have to avoid double counting them.
- unsigned result = fixed_size + fp_to_sp_delta_ -
- StandardFrameConstants::kFixedFrameSizeFromFp;
+ unsigned fixed_size_from_fp = ComputeInputFrameAboveFpFixedSize();
+ unsigned result = fixed_size_from_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_);
CHECK(result ==
- fixed_size + (stack_slots * kPointerSize) -
- StandardFrameConstants::kFixedFrameSize + outgoing_size);
+ fixed_size_from_fp + (stack_slots * kPointerSize) -
+ StandardFrameConstants::kFixedFrameSizeAboveFp + outgoing_size);
}
return result;
}
« no previous file with comments | « src/deoptimizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698