Commit 9b24f6ec authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

Move knowledge of frame stack height into the FrameStateDescriptor

When serializing frame states into translations (later used by
deopts), we pass certain values, depending on the frame kind, to be
serialized as the frame height.

This CL moves the calculation of this height value into the
FrameStateDescriptor. In a follow-up, we may want to simplify the way
these height values are passed and processed by deopts.

The motivation behind this is to simplify calculation of unoptimized
stack frame sizes during compilation.

Bug: v8:9534
Change-Id: I20d2b57a42cea0c238b9c887dba0280f6aad76de
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1728609
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63085}
parent 887b6f5d
......@@ -996,8 +996,12 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor(
}
shared_info = info()->shared_info();
}
int shared_info_id =
const BailoutId bailout_id = descriptor->bailout_id();
const int shared_info_id =
DefineDeoptimizationLiteral(DeoptimizationLiteral(shared_info));
const unsigned int height =
static_cast<unsigned int>(descriptor->GetHeight());
switch (descriptor->type()) {
case FrameStateType::kInterpretedFunction: {
......@@ -1007,45 +1011,30 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor(
return_offset = static_cast<int>(state_combine.GetOffsetToPokeAt());
return_count = static_cast<int>(iter->instruction()->OutputCount());
}
translation->BeginInterpretedFrame(
descriptor->bailout_id(), shared_info_id,
static_cast<unsigned int>(descriptor->locals_count() + 1),
return_offset, return_count);
translation->BeginInterpretedFrame(bailout_id, shared_info_id, height,
return_offset, return_count);
break;
}
case FrameStateType::kArgumentsAdaptor:
translation->BeginArgumentsAdaptorFrame(
shared_info_id,
static_cast<unsigned int>(descriptor->parameters_count()));
translation->BeginArgumentsAdaptorFrame(shared_info_id, height);
break;
case FrameStateType::kConstructStub:
DCHECK(descriptor->bailout_id().IsValidForConstructStub());
translation->BeginConstructStubFrame(
descriptor->bailout_id(), shared_info_id,
static_cast<unsigned int>(descriptor->parameters_count() + 1));
DCHECK(bailout_id.IsValidForConstructStub());
translation->BeginConstructStubFrame(bailout_id, shared_info_id, height);
break;
case FrameStateType::kBuiltinContinuation: {
BailoutId bailout_id = descriptor->bailout_id();
int parameter_count =
static_cast<unsigned int>(descriptor->parameters_count());
translation->BeginBuiltinContinuationFrame(bailout_id, shared_info_id,
parameter_count);
height);
break;
}
case FrameStateType::kJavaScriptBuiltinContinuation: {
BailoutId bailout_id = descriptor->bailout_id();
int parameter_count =
static_cast<unsigned int>(descriptor->parameters_count());
translation->BeginJavaScriptBuiltinContinuationFrame(
bailout_id, shared_info_id, parameter_count);
bailout_id, shared_info_id, height);
break;
}
case FrameStateType::kJavaScriptBuiltinContinuationWithCatch: {
BailoutId bailout_id = descriptor->bailout_id();
int parameter_count =
static_cast<unsigned int>(descriptor->parameters_count());
translation->BeginJavaScriptBuiltinContinuationWithCatchFrame(
bailout_id, shared_info_id, parameter_count);
bailout_id, shared_info_id, height);
break;
}
}
......
......@@ -1018,6 +1018,29 @@ FrameStateDescriptor::FrameStateDescriptor(
shared_info_(shared_info),
outer_state_(outer_state) {}
size_t FrameStateDescriptor::GetHeight() const {
// TODO(jgruber): Unify how the height is handled. Currently, we seem to add
// and subtract 1 at random spots. For example, for interpreted functions we
// add 1 here, and subtract it in DoComputeInterpretedFrame. For builtin
// continuation frames, we add 1 in CreateNextTranslatedFrame, and subtract
// it in DoComputeBuiltinContinuation. Arguments adaptor frames thread through
// the height unmodified.
// Handling in all these cases should ideally be consistent and use named
// constants.
switch (type()) {
case FrameStateType::kInterpretedFunction:
return locals_count() + 1; // +1 for the accumulator.
case FrameStateType::kConstructStub:
return parameters_count() + 1; // +1 for the context.
case FrameStateType::kArgumentsAdaptor:
case FrameStateType::kBuiltinContinuation:
case FrameStateType::kJavaScriptBuiltinContinuation:
case FrameStateType::kJavaScriptBuiltinContinuationWithCatch:
return parameters_count();
}
UNREACHABLE();
}
size_t FrameStateDescriptor::GetSize() const {
return 1 + parameters_count() + locals_count() + stack_count() +
(HasContext() ? 1 : 0);
......
......@@ -1270,6 +1270,13 @@ class FrameStateDescriptor : public ZoneObject {
type_ == FrameStateType::kConstructStub;
}
// The frame height on the stack, in number of slots, as serialized into a
// Translation and later used by the deoptimizer. Does *not* include
// information from the chain of outer states. Unlike |GetSize| this does not
// always include parameters, locals, and stack slots; instead, the returned
// slot kinds depend on the frame type.
size_t GetHeight() const;
size_t GetSize() const;
size_t GetTotalSize() const;
size_t GetFrameCount() const;
......
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