Index: src/compiler/bytecode-graph-builder.cc |
diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc |
index 2f6cc4d20972455f2782dc8196ade90f3a87654c..bfbf371666ac3c33501dc3babc369acaed7753a2 100644 |
--- a/src/compiler/bytecode-graph-builder.cc |
+++ b/src/compiler/bytecode-graph-builder.cc |
@@ -13,8 +13,55 @@ namespace v8 { |
namespace internal { |
namespace compiler { |
+// 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()); |
+ } |
+ |
+ ~FrameStateBeforeAndAfter() { |
+ DCHECK(builder_->environment()->StateValuesAreUpToDate( |
+ accumulator_update_mode_)); |
+ } |
+ |
+ private: |
+ friend class Environment; |
+ |
+ 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_); |
+ } |
+ accumulator_update_mode_ = update_mode; |
+ } |
+ |
+ BytecodeGraphBuilder* builder_; |
+ Node* frame_state_before_; |
+ BailoutId id_after_; |
+ AccumulatorUpdateMode accumulator_update_mode_; |
+}; |
+ |
+ |
// 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 +75,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 +101,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); |
} |
@@ -60,12 +111,15 @@ BytecodeGraphBuilder::Environment::Environment( |
: builder_(other->builder_), |
register_count_(other->register_count_), |
parameter_count_(other->parameter_count_), |
- accumulator_(other->accumulator_), |
context_(other->context_), |
control_dependency_(other->control_dependency_), |
effect_dependency_(other->effect_dependency_), |
values_(other->zone()), |
- register_base_(other->register_base_) { |
+ parameters_state_values_(nullptr), |
+ registers_state_values_(nullptr), |
+ accumulator_state_values_(nullptr), |
+ register_base_(other->register_base_), |
+ accumulator_base_(other->accumulator_base_) { |
values_ = other->values_; |
} |
@@ -102,13 +156,22 @@ Node* BytecodeGraphBuilder::Environment::LookupRegister( |
} |
-void BytecodeGraphBuilder::Environment::BindAccumulator(Node* node) { |
- accumulator_ = node; |
+void BytecodeGraphBuilder::Environment::BindAccumulator( |
+ Node* node, FrameStateBeforeAndAfter* states) { |
+ if (states) { |
+ states->AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
+ } |
+ values()->at(accumulator_base_) = node; |
+} |
+ |
+void BytecodeGraphBuilder::Environment::RecordAfterState( |
+ Node* node, FrameStateBeforeAndAfter* states) { |
+ states->AddToNode(node, AccumulatorUpdateMode::kOutputIgnored); |
} |
Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const { |
- return accumulator_; |
+ return values()->at(accumulator_base_); |
} |
@@ -156,8 +219,6 @@ void BytecodeGraphBuilder::Environment::Merge( |
// Introduce Phi nodes for values that have differing input at merge points, |
// potentially extending an existing Phi node if possible. |
- accumulator_ = |
- builder()->MergeValue(accumulator_, other->accumulator_, control); |
context_ = builder()->MergeValue(context_, other->context_, control); |
for (size_t i = 0; i < values_.size(); i++) { |
values_[i] = builder()->MergeValue(values_[i], other->values_[i], control); |
@@ -174,7 +235,6 @@ void BytecodeGraphBuilder::Environment::PrepareForLoop() { |
UpdateEffectDependency(effect); |
// Assume everything in the loop is updated. |
- accumulator_ = builder()->NewPhi(1, accumulator_, control); |
context_ = builder()->NewPhi(1, context_, control); |
int size = static_cast<int>(values()->size()); |
for (int i = 0; i < size; i++) { |
@@ -188,19 +248,91 @@ void BytecodeGraphBuilder::Environment::PrepareForLoop() { |
} |
+bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( |
+ Node** state_values, int offset, int count) { |
+ Node** env_values = (count == 0) ? nullptr : &values()->at(offset); |
+ if (*state_values == nullptr) { |
+ return 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]) { |
+ return true; |
+ } |
+ } |
+ } |
+ return false; |
+} |
+ |
+ |
+void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
+ int offset, |
+ int count) { |
+ if (StateValuesRequireUpdate(state_values, offset, count)) { |
+ const Operator* op = common()->StateValues(count); |
+ (*state_values) = graph()->NewNode(op, count, &values()->at(offset)); |
+ } |
+} |
+ |
+ |
+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 |
+ ? OutputFrameStateCombine::Ignore() |
+ : OutputFrameStateCombine::PokeAt(0); |
+ 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; |
+} |
+ |
+ |
+bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate( |
+ AccumulatorUpdateMode update_mode) { |
+ return !StateValuesRequireUpdate(¶meters_state_values_, 0, |
+ parameter_count()) && |
+ !StateValuesRequireUpdate(®isters_state_values_, register_base(), |
+ register_count()) && |
+ (update_mode == AccumulatorUpdateMode::kOutputInAccumulator || |
+ !StateValuesRequireUpdate(&accumulator_state_values_, |
+ accumulator_base(), 1)); |
+} |
+ |
+ |
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)), |
merge_environments_(local_zone), |
loop_header_environments_(local_zone), |
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() { |
@@ -281,18 +413,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 |
@@ -444,14 +564,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); |
- environment()->BindAccumulator(node); |
+ environment()->BindAccumulator(node, &states); |
} |
@@ -513,6 +633,7 @@ void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrictWide( |
void BytecodeGraphBuilder::BuildStoreGlobal( |
const interpreter::BytecodeArrayIterator& iterator) { |
+ FrameStateBeforeAndAfter states(this, iterator); |
Handle<Name> name = |
Handle<Name>::cast(iterator.GetConstantForIndexOperand(0)); |
VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1)); |
@@ -521,7 +642,7 @@ void BytecodeGraphBuilder::BuildStoreGlobal( |
const Operator* op = |
javascript()->StoreGlobal(language_mode(), name, feedback); |
Node* node = NewNode(op, value, BuildLoadFeedbackVector()); |
- AddEmptyFrameStateInputs(node); |
+ environment()->RecordAfterState(node, &states); |
} |
@@ -577,9 +698,7 @@ 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); |
} |
@@ -609,6 +728,7 @@ void BytecodeGraphBuilder::VisitStaLookupSlotStrict( |
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)); |
@@ -616,8 +736,7 @@ void BytecodeGraphBuilder::BuildNamedLoad( |
const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback); |
Node* node = NewNode(op, object, BuildLoadFeedbackVector()); |
- AddEmptyFrameStateInputs(node); |
- environment()->BindAccumulator(node); |
+ environment()->BindAccumulator(node, &states); |
} |
@@ -651,14 +770,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); |
- environment()->BindAccumulator(node); |
+ environment()->BindAccumulator(node, &states); |
} |
@@ -692,6 +811,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 = |
@@ -701,8 +821,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); |
+ environment()->RecordAfterState(node, &states); |
} |
@@ -736,6 +855,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)); |
@@ -743,8 +863,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); |
+ environment()->RecordAfterState(node, &states); |
} |
@@ -799,7 +918,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); |
} |
@@ -822,10 +940,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); |
- environment()->BindAccumulator(literal); |
+ environment()->BindAccumulator(literal, &states); |
} |
@@ -837,7 +956,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); |
} |
@@ -861,7 +980,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); |
} |
@@ -885,7 +1004,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); |
} |
@@ -920,6 +1039,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. |
@@ -932,8 +1052,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); |
- environment()->BindAccumulator(value); |
+ environment()->BindAccumulator(value, &states); |
} |
@@ -951,6 +1070,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); |
@@ -959,8 +1079,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); |
- environment()->BindAccumulator(value); |
+ environment()->BindAccumulator(value, &states); |
} |
@@ -980,6 +1099,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); |
@@ -988,8 +1108,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); |
- environment()->BindAccumulator(value); |
+ environment()->BindAccumulator(value, &states); |
} |
@@ -1012,6 +1131,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); |
@@ -1020,31 +1140,30 @@ 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); |
- environment()->BindAccumulator(value); |
+ environment()->BindAccumulator(value, &states); |
} |
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); |
+ environment()->RecordAfterState(control, &states); |
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); |
- environment()->BindAccumulator(node); |
+ environment()->BindAccumulator(node, &states); |
} |
@@ -1128,25 +1247,23 @@ 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); |
- environment()->BindAccumulator(node); |
+ environment()->BindAccumulator(node, &states); |
} |
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); |
- environment()->BindAccumulator(node); |
+ environment()->BindAccumulator(node, &states); |
} |
@@ -1170,13 +1287,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); |
- environment()->BindAccumulator(node); |
+ environment()->BindAccumulator(node, &states); |
} |
@@ -1196,12 +1312,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); |
- environment()->BindAccumulator(node); |
+ environment()->BindAccumulator(node, &states); |
} |
@@ -1267,9 +1382,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); |
- environment()->BindAccumulator(node); |
+ environment()->BindAccumulator(node, &states); |
} |