Commit de62b486 authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Factor out the function specific part from the frame state operator.

This also threads through the parameter count and local count to the instruction selector. This will be later used to allow merging of various StateValues vector (and prepare for differential encoding which will not distinguish between parameters, locals and expression stack).

BUG=

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

Cr-Commit-Position: refs/heads/master@{#29214}
parent 771eb491
......@@ -448,6 +448,10 @@ AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
state_values_cache_(jsgraph),
liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()),
local_zone),
frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
FrameStateType::kJavaScriptFunction,
info->num_parameters_including_this(),
info->scope()->num_stack_slots(), info->shared_info())),
js_type_feedback_(js_type_feedback) {
InitializeAstVisitor(info->isolate(), local_zone);
}
......@@ -869,8 +873,8 @@ Node* AstGraphBuilder::Environment::Checkpoint(
UpdateStateValues(&stack_node_, parameters_count() + locals_count(),
stack_height());
const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine,
builder()->info()->shared_info());
const Operator* op = common()->FrameState(
ast_id, combine, builder()->frame_state_function_info());
Node* result = graph()->NewNode(op, parameters_node_, locals_node_,
stack_node_, builder()->current_context(),
......
......@@ -110,6 +110,9 @@ class AstGraphBuilder : public AstVisitor {
// Analyzer of local variable liveness.
LivenessAnalyzer liveness_analyzer_;
// Function info for frame state construction.
const FrameStateFunctionInfo* const frame_state_function_info_;
// Type feedback table.
JSTypeFeedbackTable* js_type_feedback_;
......@@ -133,6 +136,9 @@ class AstGraphBuilder : public AstVisitor {
Scope* current_scope() const;
Node* current_context() const;
LivenessAnalyzer* liveness_analyzer() { return &liveness_analyzer_; }
const FrameStateFunctionInfo* frame_state_function_info() const {
return frame_state_function_info_;
}
void set_environment(Environment* env) { environment_ = env; }
void set_ast_context(AstContext* ctx) { ast_context_ = ctx; }
......
......@@ -528,13 +528,13 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor(
int shared_info_id = DefineDeoptimizationLiteral(shared_info);
switch (descriptor->type()) {
case JS_FRAME:
case FrameStateType::kJavaScriptFunction:
translation->BeginJSFrame(
descriptor->bailout_id(), shared_info_id,
static_cast<unsigned int>(descriptor->GetSize(state_combine) -
(1 + descriptor->parameters_count())));
break;
case ARGUMENTS_ADAPTOR:
case FrameStateType::kArgumentsAdaptor:
translation->BeginArgumentsAdaptorFrame(
shared_info_id,
static_cast<unsigned int>(descriptor->parameters_count()));
......
......@@ -688,15 +688,14 @@ const Operator* CommonOperatorBuilder::TypedStateValues(
const Operator* CommonOperatorBuilder::FrameState(
FrameStateType type, BailoutId bailout_id,
OutputFrameStateCombine state_combine,
MaybeHandle<SharedFunctionInfo> shared_info) {
FrameStateCallInfo state_info(type, bailout_id, state_combine, shared_info);
return new (zone()) Operator1<FrameStateCallInfo>( // --
IrOpcode::kFrameState, Operator::kPure, // opcode
"FrameState", // name
5, 0, 0, 1, 0, 0, // counts
state_info); // parameter
BailoutId bailout_id, OutputFrameStateCombine state_combine,
const FrameStateFunctionInfo* function_info) {
FrameStateInfo state_info(bailout_id, state_combine, function_info);
return new (zone()) Operator1<FrameStateInfo>( // --
IrOpcode::kFrameState, Operator::kPure, // opcode
"FrameState", // name
5, 0, 0, 1, 0, 0, // counts
state_info); // parameter
}
......@@ -776,6 +775,14 @@ const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op,
}
const FrameStateFunctionInfo*
CommonOperatorBuilder::CreateFrameStateFunctionInfo(
FrameStateType type, int parameter_count, int local_count,
Handle<SharedFunctionInfo> shared_info) {
return new (zone()->New(sizeof(FrameStateFunctionInfo)))
FrameStateFunctionInfo(type, parameter_count, local_count, shared_info);
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -136,10 +136,9 @@ class CommonOperatorBuilder final : public ZoneObject {
const Operator* Finish(int arguments);
const Operator* StateValues(int arguments);
const Operator* TypedStateValues(const ZoneVector<MachineType>* types);
const Operator* FrameState(FrameStateType type, BailoutId bailout_id,
const Operator* FrameState(BailoutId bailout_id,
OutputFrameStateCombine state_combine,
MaybeHandle<SharedFunctionInfo> shared_info =
MaybeHandle<SharedFunctionInfo>());
const FrameStateFunctionInfo* function_info);
const Operator* Call(const CallDescriptor* descriptor);
const Operator* TailCall(const CallDescriptor* descriptor);
const Operator* Projection(size_t index);
......@@ -148,6 +147,11 @@ class CommonOperatorBuilder final : public ZoneObject {
// with {size} inputs.
const Operator* ResizeMergeOrPhi(const Operator* op, int size);
// Constructs function info for frame state construction.
const FrameStateFunctionInfo* CreateFrameStateFunctionInfo(
FrameStateType type, int parameter_count, int local_count,
Handle<SharedFunctionInfo> shared_info);
private:
Zone* zone() const { return zone_; }
......
......@@ -27,24 +27,38 @@ std::ostream& operator<<(std::ostream& os, OutputFrameStateCombine const& sc) {
}
bool operator==(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) {
bool operator==(FrameStateInfo const& lhs, FrameStateInfo const& rhs) {
return lhs.type() == rhs.type() && lhs.bailout_id() == rhs.bailout_id() &&
lhs.state_combine() == rhs.state_combine();
lhs.state_combine() == rhs.state_combine() &&
lhs.function_info() == rhs.function_info();
}
bool operator!=(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) {
bool operator!=(FrameStateInfo const& lhs, FrameStateInfo const& rhs) {
return !(lhs == rhs);
}
size_t hash_value(FrameStateCallInfo const& info) {
return base::hash_combine(info.type(), info.bailout_id(),
size_t hash_value(FrameStateInfo const& info) {
return base::hash_combine(static_cast<int>(info.type()), info.bailout_id(),
info.state_combine());
}
std::ostream& operator<<(std::ostream& os, FrameStateCallInfo const& info) {
std::ostream& operator<<(std::ostream& os, FrameStateType type) {
switch (type) {
case FrameStateType::kJavaScriptFunction:
os << "JS_FRAME";
break;
case FrameStateType::kArgumentsAdaptor:
os << "ARGUMENTS_ADAPTOR";
break;
}
return os;
}
std::ostream& operator<<(std::ostream& os, FrameStateInfo const& info) {
os << info.type() << ", " << info.bailout_id() << ", "
<< info.state_combine();
Handle<SharedFunctionInfo> shared_info;
......
......@@ -70,40 +70,73 @@ class OutputFrameStateCombine {
// The type of stack frame that a FrameState node represents.
enum FrameStateType {
JS_FRAME, // Represents an unoptimized JavaScriptFrame.
ARGUMENTS_ADAPTOR // Represents an ArgumentsAdaptorFrame.
enum class FrameStateType {
kJavaScriptFunction, // Represents an unoptimized JavaScriptFrame.
kArgumentsAdaptor // Represents an ArgumentsAdaptorFrame.
};
class FrameStateCallInfo final {
class FrameStateFunctionInfo {
public:
FrameStateCallInfo(FrameStateType type, BailoutId bailout_id,
OutputFrameStateCombine state_combine,
MaybeHandle<SharedFunctionInfo> shared_info)
FrameStateFunctionInfo(FrameStateType type, int parameter_count,
int local_count,
Handle<SharedFunctionInfo> shared_info)
: type_(type),
bailout_id_(bailout_id),
frame_state_combine_(state_combine),
parameter_count_(parameter_count),
local_count_(local_count),
shared_info_(shared_info) {}
int local_count() const { return local_count_; }
int parameter_count() const { return parameter_count_; }
Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
FrameStateType type() const { return type_; }
private:
FrameStateType const type_;
int const parameter_count_;
int const local_count_;
Handle<SharedFunctionInfo> const shared_info_;
};
class FrameStateInfo final {
public:
FrameStateInfo(BailoutId bailout_id, OutputFrameStateCombine state_combine,
const FrameStateFunctionInfo* info)
: bailout_id_(bailout_id),
frame_state_combine_(state_combine),
info_(info) {}
FrameStateType type() const {
return info_ == nullptr ? FrameStateType::kJavaScriptFunction
: info_->type();
}
BailoutId bailout_id() const { return bailout_id_; }
OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
MaybeHandle<SharedFunctionInfo> shared_info() const { return shared_info_; }
MaybeHandle<SharedFunctionInfo> shared_info() const {
return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>()
: info_->shared_info();
}
int parameter_count() const {
return info_ == nullptr ? 0 : info_->parameter_count();
}
int local_count() const {
return info_ == nullptr ? 0 : info_->local_count();
}
const FrameStateFunctionInfo* function_info() const { return info_; }
private:
FrameStateType const type_;
BailoutId const bailout_id_;
OutputFrameStateCombine const frame_state_combine_;
MaybeHandle<SharedFunctionInfo> const shared_info_;
const FrameStateFunctionInfo* const info_;
};
bool operator==(FrameStateCallInfo const&, FrameStateCallInfo const&);
bool operator!=(FrameStateCallInfo const&, FrameStateCallInfo const&);
bool operator==(FrameStateInfo const&, FrameStateInfo const&);
bool operator!=(FrameStateInfo const&, FrameStateInfo const&);
size_t hash_value(FrameStateCallInfo const&);
size_t hash_value(FrameStateInfo const&);
std::ostream& operator<<(std::ostream&, FrameStateCallInfo const&);
std::ostream& operator<<(std::ostream&, FrameStateInfo const&);
static const int kFrameStateParametersInput = 0;
static const int kFrameStateLocalsInput = 1;
......
......@@ -1037,7 +1037,7 @@ FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
Node* state) {
DCHECK(state->opcode() == IrOpcode::kFrameState);
DCHECK_EQ(kFrameStateInputCount, state->InputCount());
FrameStateCallInfo state_info = OpParameter<FrameStateCallInfo>(state);
FrameStateInfo state_info = OpParameter<FrameStateInfo>(state);
int parameters = static_cast<int>(
StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size());
......@@ -1046,6 +1046,9 @@ FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
int stack = static_cast<int>(
StateValuesAccess(state->InputAt(kFrameStateStackInput)).size());
DCHECK_EQ(parameters, state_info.parameter_count());
DCHECK_EQ(locals, state_info.local_count());
FrameStateDescriptor* outer_state = NULL;
Node* outer_node = state->InputAt(kFrameStateOuterStateInput);
if (outer_node->opcode() == IrOpcode::kFrameState) {
......
......@@ -721,7 +721,7 @@ size_t FrameStateDescriptor::GetJSFrameCount() const {
size_t count = 0;
for (const FrameStateDescriptor* iter = this; iter != NULL;
iter = iter->outer_state_) {
if (iter->type_ == JS_FRAME) {
if (iter->type_ == FrameStateType::kJavaScriptFunction) {
++count;
}
}
......
......@@ -877,7 +877,9 @@ class FrameStateDescriptor : public ZoneObject {
size_t stack_count() const { return stack_count_; }
MaybeHandle<SharedFunctionInfo> shared_info() const { return shared_info_; }
FrameStateDescriptor* outer_state() const { return outer_state_; }
bool HasContext() const { return type_ == JS_FRAME; }
bool HasContext() const {
return type_ == FrameStateType::kJavaScriptFunction;
}
size_t GetSize(OutputFrameStateCombine combine =
OutputFrameStateCombine::Ignore()) const;
......
......@@ -193,8 +193,8 @@ Node* JSGraph::EmptyFrameState() {
if (!empty_frame_state || empty_frame_state->IsDead()) {
Node* state_values = graph()->NewNode(common()->StateValues(0));
empty_frame_state = graph()->NewNode(
common()->FrameState(JS_FRAME, BailoutId::None(),
OutputFrameStateCombine::Ignore()),
common()->FrameState(BailoutId::None(),
OutputFrameStateCombine::Ignore(), nullptr),
state_values, state_values, state_values, NoContextConstant(),
UndefinedConstant(), graph()->start());
cached_nodes_[kEmptyFrameState] = empty_frame_state;
......
......@@ -214,9 +214,13 @@ Reduction JSInliner::InlineCall(Node* call, Node* frame_state, Node* start,
Node* JSInliner::CreateArgumentsAdaptorFrameState(
JSCallFunctionAccessor* call, Handle<SharedFunctionInfo> shared_info,
Zone* temp_zone) {
const FrameStateFunctionInfo* state_info =
jsgraph_->common()->CreateFrameStateFunctionInfo(
FrameStateType::kArgumentsAdaptor,
static_cast<int>(call->formal_arguments()) + 1, 0, shared_info);
const Operator* op = jsgraph_->common()->FrameState(
FrameStateType::ARGUMENTS_ADAPTOR, BailoutId(-1),
OutputFrameStateCombine::Ignore(), shared_info);
BailoutId(-1), OutputFrameStateCombine::Ignore(), state_info);
const Operator* op0 = jsgraph_->common()->StateValues(0);
Node* node0 = jsgraph_->graph()->NewNode(op0);
NodeVector params(temp_zone);
......
......@@ -362,7 +362,7 @@ Node* JSTypeFeedbackSpecializer::GetFrameStateBefore(Node* node) {
if (count == 2) {
Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
if (frame_state->opcode() == IrOpcode::kFrameState) {
BailoutId id = OpParameter<FrameStateCallInfo>(node).bailout_id();
BailoutId id = OpParameter<FrameStateInfo>(node).bailout_id();
if (id != BailoutId::None()) return frame_state;
}
}
......
......@@ -252,8 +252,7 @@ class JSBinopReduction final {
}
Node* CreateFrameStateForLeftInput(Node* frame_state) {
FrameStateCallInfo state_info =
OpParameter<FrameStateCallInfo>(frame_state);
FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
if (state_info.bailout_id() == BailoutId::None()) {
// Dummy frame state => just leave it as is.
......@@ -270,8 +269,8 @@ class JSBinopReduction final {
// the stack top. This is the slot that full code uses to store the
// left operand.
const Operator* op = jsgraph()->common()->FrameState(
state_info.type(), state_info.bailout_id(),
OutputFrameStateCombine::PokeAt(1), state_info.shared_info());
state_info.bailout_id(), OutputFrameStateCombine::PokeAt(1),
state_info.function_info());
return graph()->NewNode(op,
frame_state->InputAt(kFrameStateParametersInput),
......@@ -283,8 +282,7 @@ class JSBinopReduction final {
}
Node* CreateFrameStateForRightInput(Node* frame_state, Node* converted_left) {
FrameStateCallInfo state_info =
OpParameter<FrameStateCallInfo>(frame_state);
FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
if (state_info.bailout_id() == BailoutId::None()) {
// Dummy frame state => just leave it as is.
......@@ -294,8 +292,8 @@ class JSBinopReduction final {
// Create a frame state that stores the result of the operation to the
// top of the stack (i.e., the slot used for the right operand).
const Operator* op = jsgraph()->common()->FrameState(
state_info.type(), state_info.bailout_id(),
OutputFrameStateCombine::PokeAt(0), state_info.shared_info());
state_info.bailout_id(), OutputFrameStateCombine::PokeAt(0),
state_info.function_info());
// Change the left operand {converted_left} on the expression stack.
Node* stack = frame_state->InputAt(2);
......
......@@ -79,10 +79,10 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
Node* locals = graph.NewNode(common.StateValues(0));
Node* stack = graph.NewNode(common.StateValues(0));
Node* state_node =
graph.NewNode(common.FrameState(JS_FRAME, BailoutId::None(),
OutputFrameStateCombine::Ignore()),
parameters, locals, stack, context, UndefinedConstant());
Node* state_node = graph.NewNode(
common.FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(),
nullptr),
parameters, locals, stack, context, UndefinedConstant());
return state_node;
}
......
......@@ -84,8 +84,8 @@ Node* GraphTest::UndefinedConstant() {
Node* GraphTest::EmptyFrameState() {
Node* state_values = graph()->NewNode(common()->StateValues(0));
return graph()->NewNode(
common()->FrameState(JS_FRAME, BailoutId::None(),
OutputFrameStateCombine::Ignore()),
common()->FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(),
nullptr),
state_values, state_values, state_values, NumberConstant(0),
UndefinedConstant(), graph()->start());
}
......
......@@ -148,6 +148,15 @@ bool InstructionSelectorTest::Stream::IsUsedAtStart(
}
const FrameStateFunctionInfo*
InstructionSelectorTest::StreamBuilder::GetFrameStateFunctionInfo(
int parameter_count, int local_count) {
return common()->CreateFrameStateFunctionInfo(
FrameStateType::kJavaScriptFunction, parameter_count, local_count,
Handle<SharedFunctionInfo>());
}
// -----------------------------------------------------------------------------
// Return.
......@@ -362,11 +371,11 @@ TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) {
Node* stack = m.NewNode(m.common()->TypedStateValues(&empty_types));
Node* context_dummy = m.Int32Constant(0);
Node* state_node =
m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id,
OutputFrameStateCombine::Push()),
parameters, locals, stack, context_dummy, function_node,
m.UndefinedConstant());
Node* state_node = m.NewNode(
m.common()->FrameState(bailout_id, OutputFrameStateCombine::Push(),
m.GetFrameStateFunctionInfo(1, 0)),
parameters, locals, stack, context_dummy, function_node,
m.UndefinedConstant());
Node* call = m.CallJS0(function_node, receiver, context, state_node);
m.Return(call);
......@@ -411,11 +420,11 @@ TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
m.UndefinedConstant());
Node* context_sentinel = m.Int32Constant(0);
Node* frame_state_before =
m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_before,
OutputFrameStateCombine::Push()),
parameters, locals, stack, context_sentinel, function_node,
m.UndefinedConstant());
Node* frame_state_before = m.NewNode(
m.common()->FrameState(bailout_id_before, OutputFrameStateCombine::Push(),
m.GetFrameStateFunctionInfo(1, 1)),
parameters, locals, stack, context_sentinel, function_node,
m.UndefinedConstant());
// Build the call.
Node* call = m.CallFunctionStub0(function_node, receiver, context,
......@@ -506,8 +515,9 @@ TARGET_TEST_F(InstructionSelectorTest,
Node* stack =
m.NewNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(65));
Node* frame_state_parent = m.NewNode(
m.common()->FrameState(JS_FRAME, bailout_id_parent,
OutputFrameStateCombine::Ignore()),
m.common()->FrameState(bailout_id_parent,
OutputFrameStateCombine::Ignore(),
m.GetFrameStateFunctionInfo(1, 1)),
parameters, locals, stack, context, function_node, m.UndefinedConstant());
Node* context2 = m.Int32Constant(46);
......@@ -517,11 +527,11 @@ TARGET_TEST_F(InstructionSelectorTest,
m.Float64Constant(0.25));
Node* stack2 = m.NewNode(m.common()->TypedStateValues(&int32x2_type),
m.Int32Constant(44), m.Int32Constant(45));
Node* frame_state_before =
m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_before,
OutputFrameStateCombine::Push()),
parameters2, locals2, stack2, context2, function_node,
frame_state_parent);
Node* frame_state_before = m.NewNode(
m.common()->FrameState(bailout_id_before, OutputFrameStateCombine::Push(),
m.GetFrameStateFunctionInfo(1, 1)),
parameters2, locals2, stack2, context2, function_node,
frame_state_parent);
// Build the call.
Node* call = m.CallFunctionStub0(function_node, receiver, context2,
......
......@@ -77,6 +77,9 @@ class InstructionSelectorTest : public TestWithContext,
InstructionSelector::SourcePositionMode source_position_mode =
InstructionSelector::kAllSourcePositions);
const FrameStateFunctionInfo* GetFrameStateFunctionInfo(int parameter_count,
int local_count);
private:
MachineSignature* MakeMachineSignature(Zone* zone,
MachineType return_type) {
......
......@@ -57,8 +57,13 @@ class LivenessAnalysisTest : public GraphTest {
Node* locals =
graph()->NewNode(locals_op, locals_count_, &local_inputs.front());
const FrameStateFunctionInfo* state_info =
common()->CreateFrameStateFunctionInfo(
FrameStateType::kJavaScriptFunction, 0, locals_count_,
Handle<SharedFunctionInfo>());
const Operator* op = common()->FrameState(
JS_FRAME, BailoutId(ast_num), OutputFrameStateCombine::Ignore());
BailoutId(ast_num), OutputFrameStateCombine::Ignore(), state_info);
Node* result = graph()->NewNode(op, empty_values_, locals, empty_values_,
jsgraph()->UndefinedConstant(),
jsgraph()->UndefinedConstant());
......@@ -93,8 +98,7 @@ class LivenessAnalysisTest : public GraphTest {
}
DCHECK(frame_state->opcode() == IrOpcode::kFrameState);
FrameStateCallInfo state_info =
OpParameter<FrameStateCallInfo>(frame_state);
FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
int ast_num = state_info.bailout_id().ToInt();
int first_const = intconst_from_bailout_id(ast_num, locals_count_);
......
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