Use explicit context translation in CodeStub deoptimization

Before this CL, the context of the parent frame was used when deoptimizing a
stub failure rather than the context value passed to the stub itself. In order
to guarantee that the right context is passed to the runtime upon stub failure,
this CL adds the context explicitly to the stub's environment that's used to
compute the failure deoptimizing translations. The context can then be extracted
during deoptimization translation to ensure that the precise context that was
passed to the stub is also passed to the runtime.

R=jarin@chromium.org
LOG=N

Review URL: https://codereview.chromium.org/1694183003

Cr-Commit-Position: refs/heads/master@{#34030}
This commit is contained in:
danno 2016-02-16 03:47:50 -08:00 committed by Commit bot
parent 14a5c18cc3
commit 3aa2dd34f7
3 changed files with 19 additions and 11 deletions

View File

@ -180,6 +180,7 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
context_ = Add<HContext>();
start_environment->BindContext(context_);
start_environment->Bind(param_count, context_);
Add<HSimulate>(BailoutId::StubEntry());

View File

@ -3651,8 +3651,9 @@ HGraph::HGraph(CompilationInfo* info, CallInterfaceDescriptor descriptor)
no_side_effects_scope_count_(0),
disallow_adding_new_values_(false) {
if (info->IsStub()) {
start_environment_ =
new (zone_) HEnvironment(zone_, descriptor.GetRegisterParameterCount());
// For stubs, explicitly add the context to the environment.
start_environment_ = new (zone_)
HEnvironment(zone_, descriptor.GetRegisterParameterCount() + 1);
} else {
if (info->is_tracking_positions()) {
info->TraceInlinedFunction(info->shared_info(), SourcePosition::Unknown(),

View File

@ -1737,7 +1737,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(int frame_index) {
// object to the stub failure handler.
int param_count = descriptor.GetRegisterParameterCount();
int stack_param_count = descriptor.GetStackParameterCount();
CHECK_EQ(translated_frame->height(), param_count);
// The translated frame contains all of the register parameters
// plus the context.
CHECK_EQ(translated_frame->height(), param_count + 1);
CHECK_GE(param_count, 0);
int height_in_bytes = kPointerSize * (param_count + stack_param_count) +
@ -1796,15 +1798,10 @@ void Deoptimizer::DoComputeCompiledStubFrame(int frame_index) {
"caller's constant_pool\n");
}
// The context can be gotten from the input frame.
Register context_reg = StubFailureTrampolineFrame::context_register();
input_frame_offset -= kPointerSize;
value = input_->GetFrameSlot(input_frame_offset);
output_frame->SetRegister(context_reg.code(), value);
// Remember where the context will need to be written back from the deopt
// translation.
output_frame_offset -= kPointerSize;
output_frame->SetFrameSlot(output_frame_offset, value);
CHECK(reinterpret_cast<Object*>(value)->IsContext());
DebugPrintOutputSlot(value, frame_index, output_frame_offset, "context\n");
unsigned context_frame_offset = output_frame_offset;
// A marker value is used in place of the function.
output_frame_offset -= kPointerSize;
@ -1862,6 +1859,15 @@ void Deoptimizer::DoComputeCompiledStubFrame(int frame_index) {
}
}
Object* maybe_context = value_iterator->GetRawValue();
CHECK(maybe_context->IsContext());
Register context_reg = StubFailureTrampolineFrame::context_register();
value = reinterpret_cast<intptr_t>(maybe_context);
output_frame->SetRegister(context_reg.code(), value);
output_frame->SetFrameSlot(context_frame_offset, value);
DebugPrintOutputSlot(value, frame_index, context_frame_offset, "context\n");
++value_iterator;
// Copy constant stack parameters to the failure frame. If the number of stack
// parameters is not known in the descriptor, the arguments object is the way
// to access them.