[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: Jaroslav Sevcik <jarin@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#52522}
This commit is contained in:
parent
4eebf032e0
commit
543f2de418
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user