Commit 543f2de4 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[frames] Add context slot for builtin continuations

This CL adds a context slot to builtin continuation frames which
stores the context, even for stub continuations. This context slot
is used in NotifyDeoptimized to provide the JavaScript context.

Bug: v8:7639
Change-Id: Ibdfe24141a759cda6d319db0933bea57919dc171
Reviewed-on: https://chromium-review.googlesource.com/1002776
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52522}
parent 4eebf032
...@@ -1455,6 +1455,8 @@ Builtins::Name Deoptimizer::TrampolineForBuiltinContinuation( ...@@ -1455,6 +1455,8 @@ Builtins::Name Deoptimizer::TrampolineForBuiltinContinuation(
// +-------------------------+ // +-------------------------+
// | frame height above FP | // | frame height above FP |
// +-------------------------+ // +-------------------------+
// | context |<- this non-standard context slot contains
// +-------------------------+ the context, even for non-JS builtins.
// | builtin address | // | builtin address |
// +-------------------------+ // +-------------------------+
// | builtin input GPR reg0 |<- populated from deopt FrameState using // | builtin input GPR reg0 |<- populated from deopt FrameState using
...@@ -1649,7 +1651,8 @@ void Deoptimizer::DoComputeBuiltinContinuation( ...@@ -1649,7 +1651,8 @@ void Deoptimizer::DoComputeBuiltinContinuation(
// instruction selector). // instruction selector).
Object* context = value_iterator->GetRawValue(); Object* context = value_iterator->GetRawValue();
value = reinterpret_cast<intptr_t>(context); value = reinterpret_cast<intptr_t>(context);
register_values[kContextRegister.code()] = {context, value_iterator}; const RegisterValue context_register_value = {context, value_iterator};
register_values[kContextRegister.code()] = context_register_value;
output_frame->SetContext(value); output_frame->SetContext(value);
output_frame->SetRegister(kContextRegister.code(), value); output_frame->SetRegister(kContextRegister.code(), value);
++input_index; ++input_index;
...@@ -1718,6 +1721,21 @@ void Deoptimizer::DoComputeBuiltinContinuation( ...@@ -1718,6 +1721,21 @@ void Deoptimizer::DoComputeBuiltinContinuation(
DebugPrintOutputSlot(value, frame_index, output_frame_offset, DebugPrintOutputSlot(value, frame_index, output_frame_offset,
"frame height at deoptimization\n"); "frame height at deoptimization\n");
// The context even if this is a stub contininuation frame. We can't use the
// usual context slot, because we must store the frame marker there.
output_frame_offset -= kPointerSize;
value = reinterpret_cast<intptr_t>(context);
output_frame->SetFrameSlot(output_frame_offset, value);
DebugPrintOutputSlot(value, frame_index, output_frame_offset,
"builtin JavaScript context\n");
if (context == isolate_->heap()->arguments_marker()) {
Address output_address =
reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
output_frame_offset;
values_to_materialize_.push_back(
{output_address, context_register_value.iterator_});
}
// The builtin to continue to. // The builtin to continue to.
output_frame_offset -= kPointerSize; output_frame_offset -= kPointerSize;
value = reinterpret_cast<intptr_t>(builtin); value = reinterpret_cast<intptr_t>(builtin);
......
...@@ -254,12 +254,13 @@ class BuiltinContinuationFrameConstants : public TypedFrameConstants { ...@@ -254,12 +254,13 @@ class BuiltinContinuationFrameConstants : public TypedFrameConstants {
static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0); static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
static const int kFrameSPtoFPDeltaAtDeoptimize = static const int kFrameSPtoFPDeltaAtDeoptimize =
TYPED_FRAME_PUSHED_VALUE_OFFSET(1); TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
static const int kBuiltinOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2); static const int kBuiltinContextOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
static const int kBuiltinOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
// The argument count is in the first allocatable register, stored below the // The argument count is in the first allocatable register, stored below the
// fixed part of the frame and therefore is not part of the fixed frame size. // fixed part of the frame and therefore is not part of the fixed frame size.
static const int kArgCOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3); static const int kArgCOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(4);
DEFINE_TYPED_FRAME_SIZES(3); DEFINE_TYPED_FRAME_SIZES(4);
// Returns the number of padding stack slots needed when we have // Returns the number of padding stack slots needed when we have
// 'register_count' register slots. // 'register_count' register slots.
......
...@@ -1227,6 +1227,11 @@ intptr_t JavaScriptBuiltinContinuationFrame::GetSPToFPDelta() const { ...@@ -1227,6 +1227,11 @@ intptr_t JavaScriptBuiltinContinuationFrame::GetSPToFPDelta() const {
return height; return height;
} }
Object* JavaScriptBuiltinContinuationFrame::context() const {
return Memory::Object_at(
fp() + BuiltinContinuationFrameConstants::kBuiltinContextOffset);
}
void JavaScriptBuiltinContinuationWithCatchFrame::SetException( void JavaScriptBuiltinContinuationWithCatchFrame::SetException(
Object* exception) { Object* exception) {
Address exception_argument_slot = Address exception_argument_slot =
......
...@@ -1148,6 +1148,8 @@ class JavaScriptBuiltinContinuationFrame : public JavaScriptFrame { ...@@ -1148,6 +1148,8 @@ class JavaScriptBuiltinContinuationFrame : public JavaScriptFrame {
int ComputeParametersCount() const override; int ComputeParametersCount() const override;
intptr_t GetSPToFPDelta() const; intptr_t GetSPToFPDelta() const;
Object* context() const override;
protected: protected:
inline explicit JavaScriptBuiltinContinuationFrame( inline explicit JavaScriptBuiltinContinuationFrame(
StackFrameIteratorBase* iterator); StackFrameIteratorBase* iterator);
......
...@@ -1459,7 +1459,7 @@ Object* Isolate::UnwindAndFindHandler() { ...@@ -1459,7 +1459,7 @@ Object* Isolate::UnwindAndFindHandler() {
JavaScriptBuiltinContinuationWithCatchFrame::cast(frame); JavaScriptBuiltinContinuationWithCatchFrame::cast(frame);
js_frame->SetException(exception); js_frame->SetException(exception);
// Reconstructor stack pointer from the frame pointer. // Reconstruct the stack pointer from the frame pointer.
Address return_sp = js_frame->fp() - js_frame->GetSPToFPDelta(); Address return_sp = js_frame->fp() - js_frame->GetSPToFPDelta();
Code* code = js_frame->LookupCode(); Code* code = js_frame->LookupCode();
return FoundHandler(nullptr, code->InstructionStart(), 0, return FoundHandler(nullptr, code->InstructionStart(), 0,
......
...@@ -166,14 +166,6 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { ...@@ -166,14 +166,6 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
// Ensure the context register is updated for materialized objects. // Ensure the context register is updated for materialized objects.
JavaScriptFrameIterator top_it(isolate); JavaScriptFrameIterator top_it(isolate);
JavaScriptFrame* top_frame = top_it.frame(); JavaScriptFrame* top_frame = top_it.frame();
// TODO(7639): We currently don't have a valid context in
// JavaScriptBuiltinContinuationFrames; skip them and use the
// parent's context instead.
if (top_frame->is_java_script_builtin_continuation() ||
top_frame->is_java_script_builtin_with_catch_continuation()) {
top_it.Advance();
top_frame = top_it.frame();
}
isolate->set_context(Context::cast(top_frame->context())); isolate->set_context(Context::cast(top_frame->context()));
// Invalidate the underlying optimized code on non-lazy deopts. // Invalidate the underlying optimized code on non-lazy deopts.
......
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