Commit cc1e84b9 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[turbofan] Remove eager frame state from all nodes.

This completely removes the ability from nodes to point directly to the
frame state representing their eager bailout point. All nodes now either
have zero or one frame state inputs. These frame states can by now be
found via checkpoints in the graph.

R=bmeurer@chromium.org
BUG=v8:5021

Review-Url: https://codereview.chromium.org/2020323004
Cr-Commit-Position: refs/heads/master@{#38282}
parent 34581118
......@@ -424,21 +424,18 @@ class AstGraphBuilder::FrameStateBeforeAndAfter {
// Create an explicit checkpoint node for before the operation.
Node* node = builder_->NewNode(builder_->common()->Checkpoint());
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_before_);
NodeProperties::GetFrameStateInput(node)->opcode());
NodeProperties::ReplaceFrameStateInput(node, frame_state_before_);
}
}
void AddToNode(
Node* node, BailoutId id_after,
OutputFrameStateCombine combine = OutputFrameStateCombine::Ignore()) {
int count = OperatorProperties::GetFrameStateInputCount(node->op());
DCHECK_LE(count, 2);
if (count >= 1) {
if (OperatorProperties::HasFrameStateInput(node->op())) {
// Add the frame state for after the operation.
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
NodeProperties::GetFrameStateInput(node)->opcode());
bool node_has_exception = NodeProperties::IsExceptionalCall(node);
......@@ -448,15 +445,7 @@ class AstGraphBuilder::FrameStateBeforeAndAfter {
: builder_->environment()->Checkpoint(id_after, combine,
node_has_exception);
NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
}
if (count >= 2) {
// Add the frame state for before the operation.
// TODO(mstarzinger): Get rid of frame state input before!
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 1)->opcode());
NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
}
}
......@@ -4049,14 +4038,14 @@ bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) {
void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id,
OutputFrameStateCombine combine) {
if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
if (OperatorProperties::HasFrameStateInput(node->op())) {
DCHECK(ast_id.IsNone() || info()->shared_info()->VerifyBailoutId(ast_id));
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
NodeProperties::GetFrameStateInput(node)->opcode());
bool has_exception = NodeProperties::IsExceptionalCall(node);
Node* state = environment()->Checkpoint(ast_id, combine, has_exception);
NodeProperties::ReplaceFrameStateInput(node, 0, state);
NodeProperties::ReplaceFrameStateInput(node, state);
}
}
......@@ -4070,9 +4059,9 @@ void AstGraphBuilder::PrepareEagerCheckpoint(BailoutId ast_id) {
DCHECK(info()->shared_info()->VerifyBailoutId(ast_id));
Node* node = NewNode(common()->Checkpoint());
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
NodeProperties::GetFrameStateInput(node)->opcode());
Node* state = environment()->Checkpoint(ast_id);
NodeProperties::ReplaceFrameStateInput(node, 0, state);
NodeProperties::ReplaceFrameStateInput(node, state);
}
}
......@@ -4098,7 +4087,7 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
DCHECK_EQ(op->ValueInputCount(), value_input_count);
bool has_context = OperatorProperties::HasContextInput(op);
int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
bool has_frame_state = OperatorProperties::HasFrameStateInput(op);
bool has_control = op->ControlInputCount() == 1;
bool has_effect = op->EffectInputCount() == 1;
......@@ -4106,13 +4095,13 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
DCHECK(op->EffectInputCount() < 2);
Node* result = nullptr;
if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
if (!has_context && !has_frame_state && !has_control && !has_effect) {
result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
} else {
bool inside_try_scope = try_nesting_level_ > 0;
int input_count_with_deps = value_input_count;
if (has_context) ++input_count_with_deps;
input_count_with_deps += frame_state_count;
if (has_frame_state) ++input_count_with_deps;
if (has_control) ++input_count_with_deps;
if (has_effect) ++input_count_with_deps;
Node** buffer = EnsureInputBufferSize(input_count_with_deps);
......@@ -4121,7 +4110,7 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
if (has_context) {
*current_input++ = current_context();
}
for (int i = 0; i < frame_state_count; i++) {
if (has_frame_state) {
// The frame state will be inserted later. Here we misuse
// the {Dead} node as a sentinel to be later overwritten
// with the real frame state.
......
......@@ -113,8 +113,8 @@ class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
// Create an explicit checkpoint node for before the operation.
Node* node = builder_->NewNode(builder_->common()->Checkpoint());
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_before_);
NodeProperties::GetFrameStateInput(node)->opcode());
NodeProperties::ReplaceFrameStateInput(node, frame_state_before_);
}
~FrameStateBeforeAndAfter() {
......@@ -129,30 +129,21 @@ class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
void AddToNode(Node* node, OutputFrameStateCombine combine) {
DCHECK(!added_to_node_);
int count = OperatorProperties::GetFrameStateInputCount(node->op());
DCHECK_LE(count, 2);
if (count >= 1) {
bool has_frame_state = OperatorProperties::HasFrameStateInput(node->op());
if (has_frame_state) {
// Add the frame state for after the operation.
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
NodeProperties::GetFrameStateInput(node)->opcode());
Node* frame_state_after =
builder_->environment()->Checkpoint(id_after_, combine);
NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
}
if (count >= 2) {
// Add the frame state for before the operation.
// TODO(mstarzinger): Get rid of frame state input before!
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 1)->opcode());
NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
}
if (!combine.IsOutputIgnored()) {
output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt());
output_poke_count_ = node->op()->ValueOutputCount();
}
frame_states_unused_ = count == 0;
frame_states_unused_ = !has_frame_state;
added_to_node_ = true;
}
......@@ -1681,7 +1672,7 @@ Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
DCHECK_EQ(op->ValueInputCount(), value_input_count);
bool has_context = OperatorProperties::HasContextInput(op);
int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
bool has_frame_state = OperatorProperties::HasFrameStateInput(op);
bool has_control = op->ControlInputCount() == 1;
bool has_effect = op->EffectInputCount() == 1;
......@@ -1689,13 +1680,13 @@ Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
DCHECK_LT(op->EffectInputCount(), 2);
Node* result = nullptr;
if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
if (!has_context && !has_frame_state && !has_control && !has_effect) {
result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
} else {
bool inside_handler = !exception_handlers_.empty();
int input_count_with_deps = value_input_count;
if (has_context) ++input_count_with_deps;
input_count_with_deps += frame_state_count;
if (has_frame_state) ++input_count_with_deps;
if (has_control) ++input_count_with_deps;
if (has_effect) ++input_count_with_deps;
Node** buffer = EnsureInputBufferSize(input_count_with_deps);
......@@ -1704,7 +1695,7 @@ Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
if (has_context) {
*current_input++ = environment()->Context();
}
for (int i = 0; i < frame_state_count; i++) {
if (has_frame_state) {
// The frame state will be inserted later. Here we misuse
// the {Dead} node as a sentinel to be later overwritten
// with the real frame state.
......
......@@ -531,7 +531,7 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state,
// Unlink the check point; effect uses will be updated to the incoming
// effect that is passed. The frame state is preserved for lowering.
DCHECK_EQ(RegionObservability::kObservable, region_observability_);
*frame_state = NodeProperties::GetFrameStateInput(node, 0);
*frame_state = NodeProperties::GetFrameStateInput(node);
return;
}
......
......@@ -268,7 +268,7 @@ Node* EscapeAnalysisReducer::ReduceDeoptState(Node* node, Node* effect,
}
}
if (node->opcode() == IrOpcode::kFrameState) {
Node* outer_frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* outer_frame_state = NodeProperties::GetFrameStateInput(node);
if (outer_frame_state->opcode() == IrOpcode::kFrameState) {
if (Node* ret =
ReduceDeoptState(outer_frame_state, effect, multiple_users_rec)) {
......@@ -277,7 +277,7 @@ Node* EscapeAnalysisReducer::ReduceDeoptState(Node* node, Node* effect,
node = clone = jsgraph()->graph()->CloneNode(node);
TRACE(" to #%d\n", node->id());
}
NodeProperties::ReplaceFrameStateInput(node, 0, ret);
NodeProperties::ReplaceFrameStateInput(node, ret);
}
}
}
......
......@@ -1154,7 +1154,7 @@ void EscapeAnalysis::ForwardVirtualState(Node* node) {
effect->op()->mnemonic(), effect->id(), node->op()->mnemonic(),
node->id());
if (status_analysis_->IsEffectBranchPoint(effect) ||
OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
OperatorProperties::HasFrameStateInput(node->op())) {
virtual_states_[node->id()]->SetCopyRequired();
TRACE(", effect input %s#%d is branch point", effect->op()->mnemonic(),
effect->id());
......
......@@ -637,7 +637,7 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
// all the frames on top of it that are either an arguments adaptor frame
// or a tail caller frame.
if (buffer->descriptor->SupportsTailCalls()) {
frame_state = NodeProperties::GetFrameStateInput(frame_state, 0);
frame_state = NodeProperties::GetFrameStateInput(frame_state);
buffer->frame_state_descriptor =
buffer->frame_state_descriptor->outer_state();
while (buffer->frame_state_descriptor != nullptr &&
......@@ -645,7 +645,7 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
FrameStateType::kArgumentsAdaptor ||
buffer->frame_state_descriptor->type() ==
FrameStateType::kTailCallerFunction)) {
frame_state = NodeProperties::GetFrameStateInput(frame_state, 0);
frame_state = NodeProperties::GetFrameStateInput(frame_state);
buffer->frame_state_descriptor =
buffer->frame_state_descriptor->outer_state();
}
......
......@@ -129,7 +129,7 @@ Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) {
// we can only optimize this in case the {node} was already inlined into
// some other function (and same for the {arg_array}).
CreateArgumentsType type = CreateArgumentsTypeOf(arg_array->op());
Node* frame_state = NodeProperties::GetFrameStateInput(arg_array, 0);
Node* frame_state = NodeProperties::GetFrameStateInput(arg_array);
Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
if (outer_state->opcode() != IrOpcode::kFrameState) return NoChange();
FrameStateInfo outer_info = OpParameter<FrameStateInfo>(outer_state);
......
......@@ -102,7 +102,7 @@ class AllocationBuilder final {
// Retrieves the frame state holding actual argument values.
Node* GetArgumentsFrameState(Node* frame_state) {
Node* const outer_state = NodeProperties::GetFrameStateInput(frame_state, 0);
Node* const outer_state = NodeProperties::GetFrameStateInput(frame_state);
FrameStateInfo outer_state_info = OpParameter<FrameStateInfo>(outer_state);
return outer_state_info.type() == FrameStateType::kArgumentsAdaptor
? outer_state
......@@ -279,7 +279,7 @@ Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode());
CreateArgumentsType type = CreateArgumentsTypeOf(node->op());
Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* const frame_state = NodeProperties::GetFrameStateInput(node);
Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
Node* const control = graph()->start();
FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
......@@ -565,7 +565,7 @@ Reduction JSCreateLowering::ReduceNewArrayToStubCall(
Node* if_success_packed;
Node* if_success_holey;
Node* context = NodeProperties::GetContextInput(node);
Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* frame_state = NodeProperties::GetFrameStateInput(node);
Node* if_equal = graph()->NewNode(common()->IfTrue(), branch);
{
ArraySingleArgumentConstructorStub stub(isolate(), elements_kind,
......
......@@ -16,18 +16,16 @@ namespace v8 {
namespace internal {
namespace compiler {
static CallDescriptor::Flags AdjustFrameStatesForCall(Node* node) {
int count = OperatorProperties::GetFrameStateInputCount(node->op());
if (count > 1) {
int index = NodeProperties::FirstFrameStateIndex(node) + 1;
do {
node->RemoveInput(index);
} while (--count > 1);
}
return count > 0 ? CallDescriptor::kNeedsFrameState
: CallDescriptor::kNoFlags;
namespace {
CallDescriptor::Flags FrameStateFlagForCall(Node* node) {
return OperatorProperties::HasFrameStateInput(node->op())
? CallDescriptor::kNeedsFrameState
: CallDescriptor::kNoFlags;
}
} // namespace
JSGenericLowering::JSGenericLowering(JSGraph* jsgraph) : jsgraph_(jsgraph) {}
JSGenericLowering::~JSGenericLowering() {}
......@@ -55,11 +53,11 @@ REPLACE_RUNTIME_CALL(JSCreateWithContext, Runtime::kPushWithContext)
REPLACE_RUNTIME_CALL(JSConvertReceiver, Runtime::kConvertReceiver)
#undef REPLACE_RUNTIME_CALL
#define REPLACE_STUB_CALL(Name) \
void JSGenericLowering::LowerJS##Name(Node* node) { \
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); \
Callable callable = CodeFactory::Name(isolate()); \
ReplaceWithStubCall(node, callable, flags); \
#define REPLACE_STUB_CALL(Name) \
void JSGenericLowering::LowerJS##Name(Node* node) { \
CallDescriptor::Flags flags = FrameStateFlagForCall(node); \
Callable callable = CodeFactory::Name(isolate()); \
ReplaceWithStubCall(node, callable, flags); \
}
REPLACE_STUB_CALL(Add)
REPLACE_STUB_CALL(Subtract)
......@@ -106,7 +104,7 @@ void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
void JSGenericLowering::ReplaceWithRuntimeCall(Node* node,
Runtime::FunctionId f,
int nargs_override) {
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Operator::Properties properties = node->op()->properties();
const Runtime::Function* fun = Runtime::FunctionForId(f);
int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
......@@ -153,7 +151,7 @@ void JSGenericLowering::LowerJSLoadProperty(Node* node) {
Node* closure = NodeProperties::GetValueInput(node, 2);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
const PropertyAccess& p = PropertyAccessOf(node->op());
Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate());
// Load the type feedback vector from the closure.
......@@ -177,7 +175,7 @@ void JSGenericLowering::LowerJSLoadNamed(Node* node) {
Node* closure = NodeProperties::GetValueInput(node, 1);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
NamedAccess const& p = NamedAccessOf(node->op());
Callable callable = CodeFactory::LoadICInOptimizedCode(isolate());
// Load the type feedback vector from the closure.
......@@ -202,7 +200,7 @@ void JSGenericLowering::LowerJSLoadGlobal(Node* node) {
Node* closure = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
const LoadGlobalParameters& p = LoadGlobalParametersOf(node->op());
Callable callable =
CodeFactory::LoadGlobalICInOptimizedCode(isolate(), p.typeof_mode());
......@@ -230,7 +228,7 @@ void JSGenericLowering::LowerJSStoreProperty(Node* node) {
Node* closure = NodeProperties::GetValueInput(node, 3);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
PropertyAccess const& p = PropertyAccessOf(node->op());
LanguageMode language_mode = p.language_mode();
Callable callable =
......@@ -264,7 +262,7 @@ void JSGenericLowering::LowerJSStoreNamed(Node* node) {
Node* closure = NodeProperties::GetValueInput(node, 2);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
NamedAccess const& p = NamedAccessOf(node->op());
Callable callable =
CodeFactory::StoreICInOptimizedCode(isolate(), p.language_mode());
......@@ -297,7 +295,7 @@ void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
Node* context = NodeProperties::GetContextInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
const StoreGlobalParameters& p = StoreGlobalParametersOf(node->op());
Callable callable =
CodeFactory::StoreICInOptimizedCode(isolate(), p.language_mode());
......@@ -343,7 +341,7 @@ void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
void JSGenericLowering::LowerJSInstanceOf(Node* node) {
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable = CodeFactory::InstanceOf(isolate());
ReplaceWithStubCall(node, callable, flags);
}
......@@ -388,7 +386,7 @@ void JSGenericLowering::LowerJSStoreContext(Node* node) {
void JSGenericLowering::LowerJSCreate(Node* node) {
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable = CodeFactory::FastNewObject(isolate());
ReplaceWithStubCall(node, callable, flags);
}
......@@ -426,7 +424,7 @@ void JSGenericLowering::LowerJSCreateArray(Node* node) {
void JSGenericLowering::LowerJSCreateClosure(Node* node) {
CreateClosureParameters const& p = CreateClosureParametersOf(node->op());
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Handle<SharedFunctionInfo> const shared_info = p.shared_info();
node->InsertInput(zone(), 0, jsgraph()->HeapConstant(shared_info));
......@@ -444,7 +442,7 @@ void JSGenericLowering::LowerJSCreateClosure(Node* node) {
void JSGenericLowering::LowerJSCreateFunctionContext(Node* node) {
int const slot_count = OpParameter<int>(node->op());
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable = CodeFactory::FastNewFunctionContext(isolate());
node->InsertInput(zone(), 1, jsgraph()->Int32Constant(slot_count));
......@@ -459,7 +457,7 @@ void JSGenericLowering::LowerJSCreateIterResultObject(Node* node) {
void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
......@@ -478,7 +476,7 @@ void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
......@@ -498,7 +496,7 @@ void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
void JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable = CodeFactory::FastCloneRegExp(isolate());
Node* literal_index = jsgraph()->SmiConstant(p.index());
Node* literal_flags = jsgraph()->SmiConstant(p.flags());
......@@ -534,7 +532,7 @@ void JSGenericLowering::LowerJSCreateScriptContext(Node* node) {
void JSGenericLowering::LowerJSCallConstruct(Node* node) {
CallConstructParameters const& p = CallConstructParametersOf(node->op());
int const arg_count = static_cast<int>(p.arity() - 2);
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable = CodeFactory::Construct(isolate());
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate(), zone(), callable.descriptor(), arg_count + 1, flags);
......@@ -556,7 +554,7 @@ void JSGenericLowering::LowerJSCallFunction(Node* node) {
int const arg_count = static_cast<int>(p.arity() - 2);
ConvertReceiverMode const mode = p.convert_mode();
Callable callable = CodeFactory::Call(isolate(), mode);
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
if (p.tail_call_mode() == TailCallMode::kAllow) {
flags |= CallDescriptor::kSupportsTailCalls;
}
......@@ -572,7 +570,6 @@ void JSGenericLowering::LowerJSCallFunction(Node* node) {
void JSGenericLowering::LowerJSCallRuntime(Node* node) {
const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op());
AdjustFrameStatesForCall(node);
ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity()));
}
......
......@@ -67,9 +67,9 @@ Reduction JSInliningHeuristic::Reduce(Node* node) {
// Stop inlinining once the maximum allowed level is reached.
int level = 0;
for (Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
for (Node* frame_state = NodeProperties::GetFrameStateInput(node);
frame_state->opcode() == IrOpcode::kFrameState;
frame_state = NodeProperties::GetFrameStateInput(frame_state, 0)) {
frame_state = NodeProperties::GetFrameStateInput(frame_state)) {
if (++level > FLAG_max_inlining_levels) return NoChange();
}
......
......@@ -57,7 +57,7 @@ class JSCallAccessor {
Node* frame_state() {
// Both, {JSCallFunction} and {JSCallConstruct}, have frame state.
return NodeProperties::GetFrameStateInput(call_, 0);
return NodeProperties::GetFrameStateInput(call_);
}
int formal_arguments() {
......@@ -212,11 +212,11 @@ Node* JSInliner::CreateTailCallerFrameState(Node* node, Node* frame_state) {
// If we are inlining a tail call drop caller's frame state and an
// arguments adaptor if it exists.
frame_state = NodeProperties::GetFrameStateInput(frame_state, 0);
frame_state = NodeProperties::GetFrameStateInput(frame_state);
if (frame_state->opcode() == IrOpcode::kFrameState) {
FrameStateInfo const& frame_info = OpParameter<FrameStateInfo>(frame_state);
if (frame_info.type() == FrameStateType::kArgumentsAdaptor) {
frame_state = NodeProperties::GetFrameStateInput(frame_state, 0);
frame_state = NodeProperties::GetFrameStateInput(frame_state);
}
}
......
......@@ -99,7 +99,7 @@ Reduction JSIntrinsicLowering::ReduceCreateIterResultObject(Node* node) {
Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
if (mode() != kDeoptimizationEnabled) return NoChange();
Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* const frame_state = NodeProperties::GetFrameStateInput(node);
Node* const effect = NodeProperties::GetEffectInput(node);
Node* const control = NodeProperties::GetControlInput(node);
......
......@@ -112,7 +112,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
Node* receiver = NodeProperties::GetValueInput(node, 0);
Node* context = NodeProperties::GetContextInput(node);
Node* frame_state_eager = NodeProperties::FindFrameStateBefore(node);
Node* frame_state_lazy = NodeProperties::GetFrameStateInput(node, 0);
Node* frame_state_lazy = NodeProperties::GetFrameStateInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
......
......@@ -31,7 +31,7 @@ class JSBinopReduction final {
if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
DCHECK_NE(0, node_->op()->ControlOutputCount());
DCHECK_EQ(1, node_->op()->EffectOutputCount());
DCHECK_LE(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
BinaryOperationHints hints = BinaryOperationHintsOf(node_->op());
BinaryOperationHints::Hint combined = hints.combined();
if (combined == BinaryOperationHints::kSignedSmall ||
......@@ -151,7 +151,7 @@ class JSBinopReduction final {
DCHECK_EQ(1, node_->op()->EffectOutputCount());
DCHECK_EQ(1, node_->op()->ControlInputCount());
DCHECK_LT(1, node_->op()->ControlOutputCount());
DCHECK_LE(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
DCHECK_EQ(2, node_->op()->ValueInputCount());
// Reconnect the control output to bypass the IfSuccess node and
......@@ -170,10 +170,7 @@ class JSBinopReduction final {
}
}
// Remove both bailout frame states and the context.
if (OperatorProperties::GetFrameStateInputCount(node_->op()) == 2) {
node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_) + 1);
}
// Remove the frame state and the context.
node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_));
node_->RemoveInput(NodeProperties::FirstContextIndex(node_));
......@@ -227,88 +224,17 @@ class JSBinopReduction final {
Node* node_; // The original node.
Node* CreateFrameStateForLeftInput() {
if (OperatorProperties::GetFrameStateInputCount(node_->op()) < 2) {
// Deoptimization is disabled => return dummy frame state instead.
Node* dummy_state = NodeProperties::GetFrameStateInput(node_, 0);
DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone());
return dummy_state;
}
Node* frame_state = NodeProperties::GetFrameStateInput(node_, 1);
FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
if (state_info.bailout_id() == BailoutId::None()) {
// Dummy frame state => just leave it as is.
return frame_state;
}
// If the frame state is already the right one, just return it.
if (state_info.state_combine().kind() == OutputFrameStateCombine::kPokeAt &&
state_info.state_combine().GetOffsetToPokeAt() == 1) {
return frame_state;
}
// Here, we smash the result of the conversion into the slot just below
// the stack top. This is the slot that full code uses to store the
// left operand.
const Operator* op = jsgraph()->common()->FrameState(
state_info.bailout_id(), OutputFrameStateCombine::PokeAt(1),
state_info.function_info());
return graph()->NewNode(op,
frame_state->InputAt(kFrameStateParametersInput),
frame_state->InputAt(kFrameStateLocalsInput),
frame_state->InputAt(kFrameStateStackInput),
frame_state->InputAt(kFrameStateContextInput),
frame_state->InputAt(kFrameStateFunctionInput),
frame_state->InputAt(kFrameStateOuterStateInput));
// Deoptimization is disabled => return dummy frame state instead.
Node* dummy_state = NodeProperties::GetFrameStateInput(node_);
DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone());
return dummy_state;
}
Node* CreateFrameStateForRightInput(Node* converted_left) {
if (OperatorProperties::GetFrameStateInputCount(node_->op()) < 2) {
// Deoptimization is disabled => return dummy frame state instead.
Node* dummy_state = NodeProperties::GetFrameStateInput(node_, 0);
DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone());
return dummy_state;
}
Node* frame_state = NodeProperties::GetFrameStateInput(node_, 1);
FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
if (state_info.bailout_id() == BailoutId::None()) {
// Dummy frame state => just leave it as is.
return frame_state;
}
// 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.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);
DCHECK_EQ(stack->opcode(), IrOpcode::kStateValues);
DCHECK_GE(stack->InputCount(), 2);
// TODO(jarin) Allocate in a local zone or a reusable buffer.
NodeVector new_values(stack->InputCount(), zone());
for (int i = 0; i < stack->InputCount(); i++) {
if (i == stack->InputCount() - 2) {
new_values[i] = converted_left;
} else {
new_values[i] = stack->InputAt(i);
}
}
Node* new_stack =
graph()->NewNode(stack->op(), stack->InputCount(), &new_values.front());
return graph()->NewNode(
op, frame_state->InputAt(kFrameStateParametersInput),
frame_state->InputAt(kFrameStateLocalsInput), new_stack,
frame_state->InputAt(kFrameStateContextInput),
frame_state->InputAt(kFrameStateFunctionInput),
frame_state->InputAt(kFrameStateOuterStateInput));
// Deoptimization is disabled => return dummy frame state instead.
Node* dummy_state = NodeProperties::GetFrameStateInput(node_);
DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone());
return dummy_state;
}
Node* ConvertPlainPrimitiveToNumber(Node* node) {
......@@ -1034,7 +960,7 @@ Reduction JSTypedLowering::ReduceJSToObject(Node* node) {
Node* receiver = NodeProperties::GetValueInput(node, 0);
Type* receiver_type = NodeProperties::GetType(receiver);
Node* context = NodeProperties::GetContextInput(node);
Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* frame_state = NodeProperties::GetFrameStateInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
if (receiver_type->Is(Type::Receiver())) {
......@@ -1236,7 +1162,7 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
Reduction JSTypedLowering::ReduceJSInstanceOf(Node* node) {
DCHECK_EQ(IrOpcode::kJSInstanceOf, node->opcode());
Node* const context = NodeProperties::GetContextInput(node);
Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* const frame_state = NodeProperties::GetFrameStateInput(node);
// If deoptimization is disabled, we cannot optimize.
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
......@@ -1457,7 +1383,7 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
Type* receiver_type = NodeProperties::GetType(receiver);
Node* context = NodeProperties::GetContextInput(node);
Type* context_type = NodeProperties::GetType(context);
Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* frame_state = NodeProperties::GetFrameStateInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
if (!receiver_type->Is(Type::Receiver())) {
......@@ -1731,7 +1657,7 @@ Reduction JSTypedLowering::ReduceJSForInNext(Node* node) {
Node* cache_type = NodeProperties::GetValueInput(node, 2);
Node* index = NodeProperties::GetValueInput(node, 3);
Node* context = NodeProperties::GetContextInput(node);
Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* frame_state = NodeProperties::GetFrameStateInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
......
......@@ -62,9 +62,9 @@ Node* NodeProperties::GetContextInput(Node* node) {
// static
Node* NodeProperties::GetFrameStateInput(Node* node, int index) {
DCHECK_LT(index, OperatorProperties::GetFrameStateInputCount(node->op()));
return node->InputAt(FirstFrameStateIndex(node) + index);
Node* NodeProperties::GetFrameStateInput(Node* node) {
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
return node->InputAt(FirstFrameStateIndex(node));
}
......@@ -172,10 +172,9 @@ void NodeProperties::ReplaceEffectInput(Node* node, Node* effect, int index) {
// static
void NodeProperties::ReplaceFrameStateInput(Node* node, int index,
Node* frame_state) {
DCHECK_LT(index, OperatorProperties::GetFrameStateInputCount(node->op()));
node->ReplaceInput(FirstFrameStateIndex(node) + index, frame_state);
void NodeProperties::ReplaceFrameStateInput(Node* node, Node* frame_state) {
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
node->ReplaceInput(FirstFrameStateIndex(node), frame_state);
}
......@@ -244,7 +243,7 @@ Node* NodeProperties::FindFrameStateBefore(Node* node) {
DCHECK_EQ(1, effect->op()->EffectInputCount());
effect = NodeProperties::GetEffectInput(effect);
}
Node* frame_state = GetFrameStateInput(effect, 0);
Node* frame_state = GetFrameStateInput(effect);
return frame_state;
}
......
......@@ -41,7 +41,7 @@ class NodeProperties final {
static Node* GetValueInput(Node* node, int index);
static Node* GetContextInput(Node* node);
static Node* GetFrameStateInput(Node* node, int index);
static Node* GetFrameStateInput(Node* node);
static Node* GetEffectInput(Node* node, int index = 0);
static Node* GetControlInput(Node* node, int index = 0);
......@@ -83,7 +83,7 @@ class NodeProperties final {
static void ReplaceContextInput(Node* node, Node* context);
static void ReplaceControlInput(Node* node, Node* control, int index = 0);
static void ReplaceEffectInput(Node* node, Node* effect, int index = 0);
static void ReplaceFrameStateInput(Node* node, int index, Node* frame_state);
static void ReplaceFrameStateInput(Node* node, Node* frame_state);
static void RemoveNonValueInputs(Node* node);
static void RemoveValueInputs(Node* node);
......
......@@ -20,20 +20,20 @@ bool OperatorProperties::HasContextInput(const Operator* op) {
// static
int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
bool OperatorProperties::HasFrameStateInput(const Operator* op) {
switch (op->opcode()) {
case IrOpcode::kCheckpoint:
case IrOpcode::kFrameState:
return 1;
return true;
case IrOpcode::kJSCallRuntime: {
const CallRuntimeParameters& p = CallRuntimeParametersOf(op);
return Linkage::NeedsFrameStateInput(p.id()) ? 1 : 0;
return Linkage::NeedsFrameStateInput(p.id());
}
// Strict equality cannot lazily deoptimize.
case IrOpcode::kJSStrictEqual:
case IrOpcode::kJSStrictNotEqual:
return 0;
return false;
// Binary operations
case IrOpcode::kJSAdd:
......@@ -99,10 +99,10 @@ int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
case IrOpcode::kJSForInNext:
case IrOpcode::kJSForInPrepare:
case IrOpcode::kJSStackCheck:
return 1;
return true;
default:
return 0;
return false;
}
}
......
......@@ -14,14 +14,17 @@ namespace compiler {
// Forward declarations.
class Operator;
class OperatorProperties final {
public:
static bool HasContextInput(const Operator* op);
static int GetContextInputCount(const Operator* op) {
return HasContextInput(op) ? 1 : 0;
}
static int GetFrameStateInputCount(const Operator* op);
static bool HasFrameStateInput(const Operator* op);
static int GetFrameStateInputCount(const Operator* op) {
return HasFrameStateInput(op) ? 1 : 0;
}
static int GetTotalInputCount(const Operator* op);
......
......@@ -112,7 +112,7 @@ void Verifier::Visitor::Check(Node* node) {
// Verify that frame state has been inserted for the nodes that need it.
for (int i = 0; i < frame_state_count; i++) {
Node* frame_state = NodeProperties::GetFrameStateInput(node, i);
Node* frame_state = NodeProperties::GetFrameStateInput(node);
CHECK(frame_state->opcode() == IrOpcode::kFrameState ||
// kFrameState uses Start as a sentinel.
(node->opcode() == IrOpcode::kFrameState &&
......@@ -1531,10 +1531,9 @@ void Verifier::VerifyNode(Node* node) {
}
}
}
// Frame state inputs should be frame states (or sentinels).
for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(node->op());
i++) {
Node* input = NodeProperties::GetFrameStateInput(node, i);
// Frame state input should be a frame state (or sentinel).
if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
Node* input = NodeProperties::GetFrameStateInput(node);
CHECK(input->opcode() == IrOpcode::kFrameState ||
input->opcode() == IrOpcode::kStart ||
input->opcode() == IrOpcode::kDead);
......
......@@ -2432,7 +2432,7 @@ Node* WasmGraphBuilder::BuildChangeTaggedToFloat64(Node* value) {
// else BuildLoadHeapNumberValue(y)
Node* object = NodeProperties::GetValueInput(value, 0);
Node* context = NodeProperties::GetContextInput(value);
Node* frame_state = NodeProperties::GetFrameStateInput(value, 0);
Node* frame_state = NodeProperties::GetFrameStateInput(value);
Node* effect = NodeProperties::GetEffectInput(value);
Node* control = NodeProperties::GetControlInput(value);
......
......@@ -239,7 +239,7 @@ class GraphBuilderTester : public HandleAndZoneScope,
CHECK_EQ(op->ValueInputCount(), value_input_count);
CHECK(!OperatorProperties::HasContextInput(op));
CHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op));
CHECK(!OperatorProperties::HasFrameStateInput(op));
bool has_control = op->ControlInputCount() == 1;
bool has_effect = op->EffectInputCount() == 1;
......
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