Index: src/compiler/bytecode-graph-builder.cc |
diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc |
index 96c1415c5fbf5168b00d0b76ca61b1ab65a0c80f..7c0481d842e270063226246831ba9330371171b5 100644 |
--- a/src/compiler/bytecode-graph-builder.cc |
+++ b/src/compiler/bytecode-graph-builder.cc |
@@ -14,7 +14,6 @@ namespace internal { |
namespace compiler { |
// Issues: |
-// - Need to deal with FrameState / FrameStateBeforeAndAfter / StateValue. |
// - Scopes - intimately tied to AST. Need to eval what is needed. |
// - Need to resolve closure parameter treatment. |
BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, |
@@ -28,10 +27,13 @@ BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, |
context_(context), |
control_dependency_(control_dependency), |
effect_dependency_(control_dependency), |
- values_(builder->local_zone()) { |
+ values_(builder->local_zone()), |
+ parameters_state_values_(nullptr), |
+ registers_state_values_(nullptr), |
+ accumulator_state_values_(nullptr) { |
// The layout of values_ is: |
// |
- // [receiver] [parameters] [registers] |
+ // [receiver] [parameters] [registers] [accumulator] |
// |
// parameter[0] is the receiver (this), parameters 1..N are the |
// parameters supplied to the method (arg0..argN-1). The accumulator |
@@ -51,7 +53,8 @@ BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, |
values()->insert(values()->end(), register_count, undefined_constant); |
// Accumulator |
- accumulator_ = undefined_constant; |
+ accumulator_base_ = static_cast<int>(values()->size()); |
+ values()->push_back(undefined_constant); |
} |
@@ -88,12 +91,12 @@ Node* BytecodeGraphBuilder::Environment::LookupRegister( |
void BytecodeGraphBuilder::Environment::BindAccumulator(Node* node) { |
- accumulator_ = node; |
+ values()->at(accumulator_base_) = node; |
} |
Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const { |
- return accumulator_; |
+ return values()->at(accumulator_base_); |
} |
@@ -107,17 +110,113 @@ void BytecodeGraphBuilder::Environment::MarkAsUnreachable() { |
} |
+void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
+ int offset, |
+ int count) { |
+ bool should_update = false; |
+ Node** env_values = (count == 0) ? nullptr : &values()->at(offset); |
+ if (*state_values == NULL) { |
+ should_update = true; |
+ } else { |
+ DCHECK_EQ((*state_values)->InputCount(), count); |
+ DCHECK_LE(static_cast<size_t>(offset + count), values()->size()); |
+ for (int i = 0; i < count; i++) { |
+ if ((*state_values)->InputAt(i) != env_values[i]) { |
+ should_update = true; |
+ break; |
+ } |
+ } |
+ } |
+ if (should_update) { |
+ const Operator* op = common()->StateValues(count); |
+ (*state_values) = graph()->NewNode(op, count, env_values); |
+ } |
+} |
+ |
+ |
+Node* BytecodeGraphBuilder::Environment::Checkpoint( |
+ BailoutId bailout_id, AccumulatorUpdateMode update_mode) { |
+ if (!builder()->info()->is_deoptimization_enabled()) { |
+ return builder()->jsgraph()->EmptyFrameState(); |
+ } |
+ |
+ // TODO(rmcilroy): Consider using StateValuesCache for some state values. |
+ UpdateStateValues(¶meters_state_values_, 0, parameter_count()); |
+ UpdateStateValues(®isters_state_values_, register_base(), |
+ register_count()); |
+ UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1); |
+ |
+ OutputFrameStateCombine combine = |
+ update_mode == AccumulatorUpdateMode::kOutputIgnored |
Jarin
2015/12/13 20:26:30
I do not understand why you differentiate between
rmcilroy
2015/12/16 15:40:56
We need this because some bytecodes don't modify t
Jarin
2015/12/17 09:44:05
Acknowledged.
|
+ ? OutputFrameStateCombine::Ignore() |
+ : OutputFrameStateCombine::Push(); |
+ const Operator* op = common()->FrameState( |
+ bailout_id, combine, builder()->frame_state_function_info()); |
+ |
+ Node* result = graph()->NewNode( |
+ op, parameters_state_values_, registers_state_values_, |
+ accumulator_state_values_, Context(), builder()->GetFunctionClosure(), |
+ builder()->graph()->start()); |
+ |
+ return result; |
+} |
+ |
+ |
+// Helper for generating frame states for before and after a bytecode. |
+class BytecodeGraphBuilder::FrameStateBeforeAndAfter { |
+ public: |
+ FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder, |
+ const interpreter::BytecodeArrayIterator& iterator) |
+ : builder_(builder), id_after_(BailoutId::None()) { |
+ BailoutId id_before(iterator.current_offset()); |
+ frame_state_before_ = builder_->environment()->Checkpoint( |
+ id_before, AccumulatorUpdateMode::kOutputIgnored); |
+ id_after_ = BailoutId(id_before.ToInt() + iterator.current_bytecode_size()); |
+ } |
+ |
+ void AddToNode(Node* node, AccumulatorUpdateMode update_mode) { |
+ int count = OperatorProperties::GetFrameStateInputCount(node->op()); |
+ DCHECK_LE(count, 2); |
+ |
+ if (count >= 1) { |
+ // Add the frame state for after the operation. |
+ DCHECK_EQ(IrOpcode::kDead, |
+ NodeProperties::GetFrameStateInput(node, 0)->opcode()); |
+ Node* frame_state_after = |
+ builder_->environment()->Checkpoint(id_after_, update_mode); |
+ NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after); |
+ } |
+ |
+ if (count >= 2) { |
+ // Add the frame state for before the operation. |
+ DCHECK_EQ(IrOpcode::kDead, |
+ NodeProperties::GetFrameStateInput(node, 1)->opcode()); |
+ NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_); |
+ } |
+ } |
+ |
+ private: |
+ BytecodeGraphBuilder* builder_; |
+ Node* frame_state_before_; |
+ BailoutId id_after_; |
+}; |
+ |
+ |
BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, |
CompilationInfo* compilation_info, |
JSGraph* jsgraph) |
: local_zone_(local_zone), |
info_(compilation_info), |
jsgraph_(jsgraph), |
+ bytecode_array_(handle(info()->shared_info()->bytecode_array())), |
+ frame_state_function_info_(common()->CreateFrameStateFunctionInfo( |
+ FrameStateType::kInterpretedFunction, |
+ bytecode_array()->parameter_count(), |
+ bytecode_array()->register_count(), info()->shared_info(), |
+ CALL_MAINTAINS_NATIVE_CONTEXT)), |
input_buffer_size_(0), |
input_buffer_(nullptr), |
- exit_controls_(local_zone) { |
- bytecode_array_ = handle(info()->shared_info()->bytecode_array()); |
-} |
+ exit_controls_(local_zone) {} |
Node* BytecodeGraphBuilder::GetNewTarget() { |
@@ -198,18 +297,6 @@ VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { |
} |
-// TODO(mythria): Replace this function with one which adds real frame state. |
-// Also add before and after frame states and checkpointing if required. |
-void BytecodeGraphBuilder::AddEmptyFrameStateInputs(Node* node) { |
- int frame_state_count = |
- OperatorProperties::GetFrameStateInputCount(node->op()); |
- for (int i = 0; i < frame_state_count; i++) { |
- NodeProperties::ReplaceFrameStateInput(node, i, |
- jsgraph()->EmptyFrameState()); |
- } |
-} |
- |
- |
bool BytecodeGraphBuilder::CreateGraph(bool stack_check) { |
// Set up the basic structure of the graph. Outputs for {Start} are |
// the formal parameters (including the receiver) plus context and |
@@ -349,13 +436,14 @@ void BytecodeGraphBuilder::VisitMov( |
void BytecodeGraphBuilder::BuildLoadGlobal( |
const interpreter::BytecodeArrayIterator& iterator, |
TypeofMode typeof_mode) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Handle<Name> name = |
Handle<Name>::cast(iterator.GetConstantForIndexOperand(0)); |
VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1)); |
const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode); |
Node* node = NewNode(op, BuildLoadFeedbackVector()); |
- AddEmptyFrameStateInputs(node); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(node); |
} |
@@ -418,6 +506,7 @@ void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrictWide( |
void BytecodeGraphBuilder::BuildStoreGlobal( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Jarin
2015/12/13 20:26:30
Could we please implement the minimal machinery ne
rmcilroy
2015/12/16 15:40:56
As discussed offline, keeping this machinary in si
Jarin
2015/12/17 09:44:05
Ack. Even though I am wondering whether the FrameS
rmcilroy
2015/12/17 14:43:48
Good point on the fact that the OutputIgnore/Outpu
|
Handle<Name> name = |
Handle<Name>::cast(iterator.GetConstantForIndexOperand(0)); |
VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1)); |
@@ -426,7 +515,7 @@ void BytecodeGraphBuilder::BuildStoreGlobal( |
const Operator* op = |
javascript()->StoreGlobal(language_mode(), name, feedback); |
Node* node = NewNode(op, value, BuildLoadFeedbackVector()); |
- AddEmptyFrameStateInputs(node); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputIgnored); |
} |
@@ -482,14 +571,13 @@ void BytecodeGraphBuilder::VisitStaContextSlot( |
javascript()->StoreContext(0, iterator.GetIndexOperand(1)); |
Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
Node* value = environment()->LookupAccumulator(); |
- Node* node = NewNode(op, context, value); |
- CHECK(node != nullptr); |
- environment()->BindAccumulator(value); |
+ NewNode(op, context, value); |
} |
void BytecodeGraphBuilder::BuildNamedLoad( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
Handle<Name> name = |
Handle<Name>::cast(iterator.GetConstantForIndexOperand(1)); |
@@ -497,7 +585,7 @@ void BytecodeGraphBuilder::BuildNamedLoad( |
const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback); |
Node* node = NewNode(op, object, BuildLoadFeedbackVector()); |
- AddEmptyFrameStateInputs(node); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(node); |
} |
@@ -532,13 +620,14 @@ void BytecodeGraphBuilder::VisitLoadICStrictWide( |
void BytecodeGraphBuilder::BuildKeyedLoad( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Node* key = environment()->LookupAccumulator(); |
Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1)); |
const Operator* op = javascript()->LoadProperty(language_mode(), feedback); |
Node* node = NewNode(op, object, key, BuildLoadFeedbackVector()); |
- AddEmptyFrameStateInputs(node); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(node); |
} |
@@ -573,6 +662,7 @@ void BytecodeGraphBuilder::VisitKeyedLoadICStrictWide( |
void BytecodeGraphBuilder::BuildNamedStore( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Node* value = environment()->LookupAccumulator(); |
Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
Handle<Name> name = |
@@ -582,8 +672,7 @@ void BytecodeGraphBuilder::BuildNamedStore( |
const Operator* op = |
javascript()->StoreNamed(language_mode(), name, feedback); |
Node* node = NewNode(op, object, value, BuildLoadFeedbackVector()); |
- AddEmptyFrameStateInputs(node); |
- environment()->BindAccumulator(value); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputIgnored); |
} |
@@ -617,6 +706,7 @@ void BytecodeGraphBuilder::VisitStoreICStrictWide( |
void BytecodeGraphBuilder::BuildKeyedStore( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Node* value = environment()->LookupAccumulator(); |
Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
Node* key = environment()->LookupRegister(iterator.GetRegisterOperand(1)); |
@@ -624,8 +714,7 @@ void BytecodeGraphBuilder::BuildKeyedStore( |
const Operator* op = javascript()->StoreProperty(language_mode(), feedback); |
Node* node = NewNode(op, object, key, value, BuildLoadFeedbackVector()); |
- AddEmptyFrameStateInputs(node); |
- environment()->BindAccumulator(value); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputIgnored); |
} |
@@ -680,7 +769,6 @@ void BytecodeGraphBuilder::VisitCreateClosure( |
iterator.GetImmediateOperand(1) ? TENURED : NOT_TENURED; |
const Operator* op = javascript()->CreateClosure(shared_info, tenured); |
Node* closure = NewNode(op); |
- AddEmptyFrameStateInputs(closure); |
environment()->BindAccumulator(closure); |
} |
@@ -703,9 +791,11 @@ void BytecodeGraphBuilder::VisitCreateUnmappedArguments( |
} |
-void BytecodeGraphBuilder::BuildCreateLiteral(const Operator* op) { |
+void BytecodeGraphBuilder::BuildCreateLiteral( |
+ const Operator* op, const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Node* literal = NewNode(op, GetFunctionClosure()); |
- AddEmptyFrameStateInputs(literal); |
+ states.AddToNode(literal, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(literal); |
} |
@@ -718,7 +808,7 @@ void BytecodeGraphBuilder::BuildCreateRegExpLiteral( |
int literal_flags = iterator.GetImmediateOperand(2); |
const Operator* op = javascript()->CreateLiteralRegExp( |
constant_pattern, literal_flags, literal_index); |
- BuildCreateLiteral(op); |
+ BuildCreateLiteral(op, iterator); |
} |
@@ -742,7 +832,7 @@ void BytecodeGraphBuilder::BuildCreateArrayLiteral( |
int literal_flags = iterator.GetImmediateOperand(2); |
const Operator* op = javascript()->CreateLiteralArray( |
constant_elements, literal_flags, literal_index); |
- BuildCreateLiteral(op); |
+ BuildCreateLiteral(op, iterator); |
} |
@@ -766,7 +856,7 @@ void BytecodeGraphBuilder::BuildCreateObjectLiteral( |
int literal_flags = iterator.GetImmediateOperand(2); |
const Operator* op = javascript()->CreateLiteralObject( |
constant_properties, literal_flags, literal_index); |
- BuildCreateLiteral(op); |
+ BuildCreateLiteral(op, iterator); |
} |
@@ -801,6 +891,7 @@ Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, |
void BytecodeGraphBuilder::BuildCall( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
// TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver |
// register has been loaded with null / undefined explicitly or we are sure it |
// is not null / undefined. |
@@ -813,7 +904,7 @@ void BytecodeGraphBuilder::BuildCall( |
const Operator* call = javascript()->CallFunction( |
arg_count + 2, language_mode(), feedback, receiver_hint); |
Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2); |
- AddEmptyFrameStateInputs(value); |
+ states.AddToNode(value, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(value); |
} |
@@ -832,6 +923,7 @@ void BytecodeGraphBuilder::VisitCallWide( |
void BytecodeGraphBuilder::VisitCallJSRuntime( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Node* callee = BuildLoadNativeContextField(iterator.GetIndexOperand(0)); |
interpreter::Register receiver = iterator.GetRegisterOperand(1); |
size_t arg_count = iterator.GetCountOperand(2); |
@@ -840,7 +932,7 @@ void BytecodeGraphBuilder::VisitCallJSRuntime( |
const Operator* call = |
javascript()->CallFunction(arg_count + 2, language_mode()); |
Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2); |
- AddEmptyFrameStateInputs(value); |
+ states.AddToNode(value, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(value); |
} |
@@ -861,6 +953,7 @@ Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments( |
void BytecodeGraphBuilder::VisitCallRuntime( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Runtime::FunctionId functionId = |
static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0)); |
interpreter::Register first_arg = iterator.GetRegisterOperand(1); |
@@ -869,7 +962,7 @@ void BytecodeGraphBuilder::VisitCallRuntime( |
// Create node to perform the runtime call. |
const Operator* call = javascript()->CallRuntime(functionId, arg_count); |
Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count); |
- AddEmptyFrameStateInputs(value); |
+ states.AddToNode(value, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(value); |
} |
@@ -893,6 +986,7 @@ Node* BytecodeGraphBuilder::ProcessCallNewArguments( |
void BytecodeGraphBuilder::VisitNew( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
interpreter::Register callee = iterator.GetRegisterOperand(0); |
interpreter::Register first_arg = iterator.GetRegisterOperand(1); |
size_t arg_count = iterator.GetCountOperand(2); |
@@ -901,30 +995,31 @@ void BytecodeGraphBuilder::VisitNew( |
const Operator* call = javascript()->CallConstruct( |
static_cast<int>(arg_count) + 2, VectorSlotPair()); |
Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2); |
- AddEmptyFrameStateInputs(value); |
+ states.AddToNode(value, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(value); |
} |
void BytecodeGraphBuilder::VisitThrow( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Node* value = environment()->LookupAccumulator(); |
// TODO(mythria): Change to Runtime::kThrow when we have deoptimization |
// information support in the interpreter. |
NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), value); |
Node* control = NewNode(common()->Throw(), value); |
+ states.AddToNode(control, AccumulatorUpdateMode::kOutputIgnored); |
UpdateControlDependencyToLeaveFunction(control); |
- environment()->BindAccumulator(value); |
} |
void BytecodeGraphBuilder::BuildBinaryOp( |
const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
Node* right = environment()->LookupAccumulator(); |
Node* node = NewNode(js_op, left, right); |
- |
- AddEmptyFrameStateInputs(node); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(node); |
} |
@@ -1009,24 +1104,24 @@ void BytecodeGraphBuilder::VisitShiftRightLogical( |
void BytecodeGraphBuilder::VisitInc( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
const Operator* js_op = |
javascript()->Add(language_mode(), BinaryOperationHints::Any()); |
Node* node = NewNode(js_op, environment()->LookupAccumulator(), |
jsgraph()->OneConstant()); |
- |
- AddEmptyFrameStateInputs(node); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(node); |
} |
void BytecodeGraphBuilder::VisitDec( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
const Operator* js_op = |
javascript()->Subtract(language_mode(), BinaryOperationHints::Any()); |
Node* node = NewNode(js_op, environment()->LookupAccumulator(), |
jsgraph()->OneConstant()); |
- |
- AddEmptyFrameStateInputs(node); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(node); |
} |
@@ -1051,12 +1146,12 @@ void BytecodeGraphBuilder::VisitTypeOf( |
void BytecodeGraphBuilder::BuildDelete( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Node* key = environment()->LookupAccumulator(); |
Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
- |
Node* node = |
NewNode(javascript()->DeleteProperty(language_mode()), object, key); |
- AddEmptyFrameStateInputs(node); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(node); |
} |
@@ -1077,11 +1172,11 @@ void BytecodeGraphBuilder::VisitDeletePropertySloppy( |
void BytecodeGraphBuilder::BuildCompareOp( |
const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
Node* right = environment()->LookupAccumulator(); |
Node* node = NewNode(js_op, left, right); |
- |
- AddEmptyFrameStateInputs(node); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(node); |
} |
@@ -1148,8 +1243,9 @@ void BytecodeGraphBuilder::VisitTestInstanceOf( |
void BytecodeGraphBuilder::BuildCastOperator( |
const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Node* node = NewNode(js_op, environment()->LookupAccumulator()); |
- AddEmptyFrameStateInputs(node); |
+ states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
environment()->BindAccumulator(node); |
} |