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(
// +-------------------------+
// | frame height above FP |
// +-------------------------+
// | context |<- this non-standard context slot contains
// +-------------------------+ the context, even for non-JS builtins.
// | builtin address |
// +-------------------------+
// | builtin input GPR reg0 |<- populated from deopt FrameState using
......@@ -1649,7 +1651,8 @@ void Deoptimizer::DoComputeBuiltinContinuation(
// instruction selector).
Object* context = value_iterator->GetRawValue();
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->SetRegister(kContextRegister.code(), value);
++input_index;
......@@ -1718,6 +1721,21 @@ void Deoptimizer::DoComputeBuiltinContinuation(
DebugPrintOutputSlot(value, frame_index, output_frame_offset,
"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.
output_frame_offset -= kPointerSize;
value = reinterpret_cast<intptr_t>(builtin);
......
......@@ -254,12 +254,13 @@ class BuiltinContinuationFrameConstants : public TypedFrameConstants {
static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
static const int kFrameSPtoFPDeltaAtDeoptimize =
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
// 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);
DEFINE_TYPED_FRAME_SIZES(3);
static const int kArgCOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(4);
DEFINE_TYPED_FRAME_SIZES(4);
// Returns the number of padding stack slots needed when we have
// 'register_count' register slots.
......
......@@ -1227,6 +1227,11 @@ intptr_t JavaScriptBuiltinContinuationFrame::GetSPToFPDelta() const {
return height;
}
Object* JavaScriptBuiltinContinuationFrame::context() const {
return Memory::Object_at(
fp() + BuiltinContinuationFrameConstants::kBuiltinContextOffset);
}
void JavaScriptBuiltinContinuationWithCatchFrame::SetException(
Object* exception) {
Address exception_argument_slot =
......
......@@ -1148,6 +1148,8 @@ class JavaScriptBuiltinContinuationFrame : public JavaScriptFrame {
int ComputeParametersCount() const override;
intptr_t GetSPToFPDelta() const;
Object* context() const override;
protected:
inline explicit JavaScriptBuiltinContinuationFrame(
StackFrameIteratorBase* iterator);
......
......@@ -1459,7 +1459,7 @@ Object* Isolate::UnwindAndFindHandler() {
JavaScriptBuiltinContinuationWithCatchFrame::cast(frame);
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();
Code* code = js_frame->LookupCode();
return FoundHandler(nullptr, code->InstructionStart(), 0,
......
......@@ -166,14 +166,6 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
// Ensure the context register is updated for materialized objects.
JavaScriptFrameIterator top_it(isolate);
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()));
// 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