| Index: src/compiler/bytecode-graph-builder.cc
|
| diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc
|
| index 26409d3696426906fd5dba410ab1b631e220cb76..7e88cff89980a5a9e19d6489f1bf511174f64b5e 100644
|
| --- a/src/compiler/bytecode-graph-builder.cc
|
| +++ b/src/compiler/bytecode-graph-builder.cc
|
| @@ -25,6 +25,11 @@ class BytecodeGraphBuilder::Environment : public ZoneObject {
|
| Environment(BytecodeGraphBuilder* builder, int register_count,
|
| int parameter_count, Node* control_dependency, Node* context);
|
|
|
| + // Specifies whether environment binding methods should attach frame state
|
| + // inputs to nodes representing the value being bound. This is done because
|
| + // the {OutputFrameStateCombine} is closely related to the binding method.
|
| + enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState };
|
| +
|
| int parameter_count() const { return parameter_count_; }
|
| int register_count() const { return register_count_; }
|
|
|
| @@ -32,12 +37,15 @@ class BytecodeGraphBuilder::Environment : public ZoneObject {
|
| Node* LookupRegister(interpreter::Register the_register) const;
|
| void MarkAllRegistersLive();
|
|
|
| - void BindAccumulator(Node* node, FrameStateBeforeAndAfter* states = nullptr);
|
| + void BindAccumulator(Node* node,
|
| + FrameStateAttachmentMode mode = kDontAttachFrameState);
|
| void BindRegister(interpreter::Register the_register, Node* node,
|
| - FrameStateBeforeAndAfter* states = nullptr);
|
| - void BindRegistersToProjections(interpreter::Register first_reg, Node* node,
|
| - FrameStateBeforeAndAfter* states = nullptr);
|
| - void RecordAfterState(Node* node, FrameStateBeforeAndAfter* states);
|
| + FrameStateAttachmentMode mode = kDontAttachFrameState);
|
| + void BindRegistersToProjections(
|
| + interpreter::Register first_reg, Node* node,
|
| + FrameStateAttachmentMode mode = kDontAttachFrameState);
|
| + void RecordAfterState(Node* node,
|
| + FrameStateAttachmentMode mode = kDontAttachFrameState);
|
|
|
| // Effect dependency tracked by this environment.
|
| Node* GetEffectDependency() { return effect_dependency_; }
|
| @@ -113,69 +121,6 @@ class BytecodeGraphBuilder::Environment : public ZoneObject {
|
| int accumulator_base_;
|
| };
|
|
|
| -// Helper for generating frame states for before and after a bytecode.
|
| -class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
|
| - public:
|
| - explicit FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder)
|
| - : builder_(builder),
|
| - id_after_(BailoutId::None()),
|
| - added_to_node_(false),
|
| - frame_states_unused_(false),
|
| - output_poke_offset_(0),
|
| - output_poke_count_(0) {
|
| - BailoutId id_before(builder->bytecode_iterator().current_offset());
|
| - frame_state_before_ = builder_->environment()->Checkpoint(
|
| - id_before, OutputFrameStateCombine::Ignore(), false);
|
| - id_after_ = BailoutId(id_before.ToInt() +
|
| - builder->bytecode_iterator().current_bytecode_size());
|
| - // Create an explicit checkpoint node for before the operation.
|
| - Node* node = builder_->NewNode(builder_->common()->Checkpoint());
|
| - DCHECK_EQ(IrOpcode::kDead,
|
| - NodeProperties::GetFrameStateInput(node)->opcode());
|
| - NodeProperties::ReplaceFrameStateInput(node, frame_state_before_);
|
| - }
|
| -
|
| - ~FrameStateBeforeAndAfter() {
|
| - DCHECK(added_to_node_);
|
| - DCHECK(frame_states_unused_ ||
|
| - builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
|
| - output_poke_count_));
|
| - }
|
| -
|
| - private:
|
| - friend class Environment;
|
| -
|
| - void AddToNode(Node* node, OutputFrameStateCombine combine) {
|
| - DCHECK(!added_to_node_);
|
| - 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)->opcode());
|
| - bool has_exception = NodeProperties::IsExceptionalCall(node);
|
| - Node* frame_state_after = builder_->environment()->Checkpoint(
|
| - id_after_, combine, has_exception);
|
| - 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_ = !has_frame_state;
|
| - added_to_node_ = true;
|
| - }
|
| -
|
| - BytecodeGraphBuilder* builder_;
|
| - Node* frame_state_before_;
|
| - BailoutId id_after_;
|
| -
|
| - bool added_to_node_;
|
| - bool frame_states_unused_;
|
| - int output_poke_offset_;
|
| - int output_poke_count_;
|
| -};
|
| -
|
|
|
| // Issues:
|
| // - Scopes - intimately tied to AST. Need to eval what is needed.
|
| @@ -295,9 +240,9 @@ void BytecodeGraphBuilder::Environment::MarkAllRegistersLive() {
|
| }
|
|
|
| void BytecodeGraphBuilder::Environment::BindAccumulator(
|
| - Node* node, FrameStateBeforeAndAfter* states) {
|
| - if (states) {
|
| - states->AddToNode(node, OutputFrameStateCombine::PokeAt(0));
|
| + Node* node, FrameStateAttachmentMode mode) {
|
| + if (mode == FrameStateAttachmentMode::kAttachFrameState) {
|
| + builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0));
|
| }
|
| DCHECK(IsLivenessBlockConsistent());
|
| if (liveness_block() != nullptr) {
|
| @@ -306,14 +251,13 @@ void BytecodeGraphBuilder::Environment::BindAccumulator(
|
| values()->at(accumulator_base_) = node;
|
| }
|
|
|
| -
|
| void BytecodeGraphBuilder::Environment::BindRegister(
|
| interpreter::Register the_register, Node* node,
|
| - FrameStateBeforeAndAfter* states) {
|
| + FrameStateAttachmentMode mode) {
|
| int values_index = RegisterToValuesIndex(the_register);
|
| - if (states) {
|
| - states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
|
| - values_index));
|
| + if (mode == FrameStateAttachmentMode::kAttachFrameState) {
|
| + builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
|
| + accumulator_base_ - values_index));
|
| }
|
| values()->at(values_index) = node;
|
| if (liveness_block() != nullptr && !the_register.is_parameter()) {
|
| @@ -322,14 +266,13 @@ void BytecodeGraphBuilder::Environment::BindRegister(
|
| }
|
| }
|
|
|
| -
|
| void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
|
| interpreter::Register first_reg, Node* node,
|
| - FrameStateBeforeAndAfter* states) {
|
| + FrameStateAttachmentMode mode) {
|
| int values_index = RegisterToValuesIndex(first_reg);
|
| - if (states) {
|
| - states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
|
| - values_index));
|
| + if (mode == FrameStateAttachmentMode::kAttachFrameState) {
|
| + builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
|
| + accumulator_base_ - values_index));
|
| }
|
| for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
|
| values()->at(values_index + i) =
|
| @@ -337,10 +280,11 @@ void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
|
| }
|
| }
|
|
|
| -
|
| void BytecodeGraphBuilder::Environment::RecordAfterState(
|
| - Node* node, FrameStateBeforeAndAfter* states) {
|
| - states->AddToNode(node, OutputFrameStateCombine::Ignore());
|
| + Node* node, FrameStateAttachmentMode mode) {
|
| + if (mode == FrameStateAttachmentMode::kAttachFrameState) {
|
| + builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore());
|
| + }
|
| }
|
|
|
|
|
| @@ -701,6 +645,38 @@ bool BytecodeGraphBuilder::CreateGraph() {
|
| return true;
|
| }
|
|
|
| +void BytecodeGraphBuilder::PrepareEagerCheckpoint() {
|
| + if (environment()->GetEffectDependency()->opcode() != IrOpcode::kCheckpoint) {
|
| + // Create an explicit checkpoint node for before the operation. This only
|
| + // needs to happen if we aren't effect-dominated by a {Checkpoint} already.
|
| + Node* node = NewNode(common()->Checkpoint());
|
| + DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
|
| + DCHECK_EQ(IrOpcode::kDead,
|
| + NodeProperties::GetFrameStateInput(node)->opcode());
|
| + BailoutId bailout_id_before(bytecode_iterator().current_offset());
|
| + Node* frame_state_before = environment()->Checkpoint(
|
| + bailout_id_before, OutputFrameStateCombine::Ignore(), false);
|
| + NodeProperties::ReplaceFrameStateInput(node, frame_state_before);
|
| + }
|
| +}
|
| +
|
| +void BytecodeGraphBuilder::PrepareFrameState(Node* node,
|
| + OutputFrameStateCombine combine) {
|
| + if (OperatorProperties::HasFrameStateInput(node->op())) {
|
| + // Add the frame state for after the operation. The node in question has
|
| + // already been created and had a {Dead} frame state input up until now.
|
| + DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
|
| + DCHECK_EQ(IrOpcode::kDead,
|
| + NodeProperties::GetFrameStateInput(node)->opcode());
|
| + BailoutId bailout_id_after(bytecode_iterator().current_offset() +
|
| + bytecode_iterator().current_bytecode_size());
|
| + bool has_exception = NodeProperties::IsExceptionalCall(node);
|
| + Node* frame_state_after =
|
| + environment()->Checkpoint(bailout_id_after, combine, has_exception);
|
| + NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
|
| + }
|
| +}
|
| +
|
| void BytecodeGraphBuilder::ClearNonLiveSlotsInFrameStates() {
|
| if (!IsLivenessAnalysisEnabled()) {
|
| return;
|
| @@ -829,29 +805,29 @@ Node* BytecodeGraphBuilder::BuildLoadGlobal(uint32_t feedback_slot_index,
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitLdaGlobal() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0),
|
| TypeofMode::NOT_INSIDE_TYPEOF);
|
| - environment()->BindAccumulator(node, &states);
|
| + environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitLdrGlobal() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0),
|
| TypeofMode::NOT_INSIDE_TYPEOF);
|
| environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node,
|
| - &states);
|
| + Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0),
|
| TypeofMode::INSIDE_TYPEOF);
|
| - environment()->BindAccumulator(node, &states);
|
| + environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Handle<Name> name =
|
| Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
|
| VectorSlotPair feedback =
|
| @@ -860,7 +836,7 @@ void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) {
|
|
|
| const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
|
| Node* node = NewNode(op, value, GetFunctionClosure());
|
| - environment()->RecordAfterState(node, &states);
|
| + environment()->RecordAfterState(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitStaGlobalSloppy() {
|
| @@ -904,7 +880,7 @@ void BytecodeGraphBuilder::VisitStaContextSlot() {
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* name =
|
| jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
|
| const Operator* op =
|
| @@ -912,7 +888,7 @@ void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
|
| ? Runtime::kLoadLookupSlot
|
| : Runtime::kLoadLookupSlotInsideTypeof);
|
| Node* value = NewNode(op, name);
|
| - environment()->BindAccumulator(value, &states);
|
| + environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitLdaLookupSlot() {
|
| @@ -992,8 +968,6 @@ void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) {
|
| // Slow path, do a runtime load lookup.
|
| set_environment(slow_environment);
|
| {
|
| - FrameStateBeforeAndAfter states(this);
|
| -
|
| Node* name = jsgraph()->Constant(
|
| bytecode_iterator().GetConstantForIndexOperand(0));
|
|
|
| @@ -1002,7 +976,7 @@ void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) {
|
| ? Runtime::kLoadLookupSlot
|
| : Runtime::kLoadLookupSlotInsideTypeof);
|
| Node* value = NewNode(op, name);
|
| - environment()->BindAccumulator(value, &states);
|
| + environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
| }
|
|
|
| fast_environment->Merge(environment());
|
| @@ -1026,10 +1000,10 @@ void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) {
|
|
|
| // Fast path, do a global load.
|
| {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* node =
|
| BuildLoadGlobal(bytecode_iterator().GetIndexOperand(1), typeof_mode);
|
| - environment()->BindAccumulator(node, &states);
|
| + environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
| }
|
|
|
| // Only build the slow path if there were any slow-path checks.
|
| @@ -1041,8 +1015,6 @@ void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) {
|
| // Slow path, do a runtime load lookup.
|
| set_environment(slow_environment);
|
| {
|
| - FrameStateBeforeAndAfter states(this);
|
| -
|
| Node* name = jsgraph()->Constant(
|
| bytecode_iterator().GetConstantForIndexOperand(0));
|
|
|
| @@ -1051,7 +1023,7 @@ void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) {
|
| ? Runtime::kLoadLookupSlot
|
| : Runtime::kLoadLookupSlotInsideTypeof);
|
| Node* value = NewNode(op, name);
|
| - environment()->BindAccumulator(value, &states);
|
| + environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
| }
|
|
|
| fast_environment->Merge(environment());
|
| @@ -1068,7 +1040,7 @@ void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() {
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildStaLookupSlot(LanguageMode language_mode) {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* value = environment()->LookupAccumulator();
|
| Node* name =
|
| jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
|
| @@ -1076,7 +1048,7 @@ void BytecodeGraphBuilder::BuildStaLookupSlot(LanguageMode language_mode) {
|
| is_strict(language_mode) ? Runtime::kStoreLookupSlot_Strict
|
| : Runtime::kStoreLookupSlot_Sloppy);
|
| Node* store = NewNode(op, name, value);
|
| - environment()->BindAccumulator(store, &states);
|
| + environment()->BindAccumulator(store, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitStaLookupSlotSloppy() {
|
| @@ -1100,16 +1072,16 @@ Node* BytecodeGraphBuilder::BuildNamedLoad() {
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitLdaNamedProperty() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* node = BuildNamedLoad();
|
| - environment()->BindAccumulator(node, &states);
|
| + environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitLdrNamedProperty() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* node = BuildNamedLoad();
|
| environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), node,
|
| - &states);
|
| + Environment::kAttachFrameState);
|
| }
|
|
|
| Node* BytecodeGraphBuilder::BuildKeyedLoad() {
|
| @@ -1124,20 +1096,20 @@ Node* BytecodeGraphBuilder::BuildKeyedLoad() {
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitLdaKeyedProperty() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* node = BuildKeyedLoad();
|
| - environment()->BindAccumulator(node, &states);
|
| + environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitLdrKeyedProperty() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* node = BuildKeyedLoad();
|
| environment()->BindRegister(bytecode_iterator().GetRegisterOperand(2), node,
|
| - &states);
|
| + Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode) {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* value = environment()->LookupAccumulator();
|
| Node* object =
|
| environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
| @@ -1148,7 +1120,7 @@ void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode) {
|
|
|
| const Operator* op = javascript()->StoreNamed(language_mode, name, feedback);
|
| Node* node = NewNode(op, object, value, GetFunctionClosure());
|
| - environment()->RecordAfterState(node, &states);
|
| + environment()->RecordAfterState(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitStaNamedPropertySloppy() {
|
| @@ -1160,7 +1132,7 @@ void BytecodeGraphBuilder::VisitStaNamedPropertyStrict() {
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* value = environment()->LookupAccumulator();
|
| Node* object =
|
| environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
| @@ -1171,7 +1143,7 @@ void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
|
|
|
| const Operator* op = javascript()->StoreProperty(language_mode, feedback);
|
| Node* node = NewNode(op, object, key, value, GetFunctionClosure());
|
| - environment()->RecordAfterState(node, &states);
|
| + environment()->RecordAfterState(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitStaKeyedPropertySloppy() {
|
| @@ -1250,10 +1222,9 @@ void BytecodeGraphBuilder::VisitCreateWithContext() {
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
|
| - FrameStateBeforeAndAfter states(this);
|
| const Operator* op = javascript()->CreateArguments(type);
|
| Node* object = NewNode(op, GetFunctionClosure());
|
| - environment()->BindAccumulator(object, &states);
|
| + environment()->BindAccumulator(object, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitCreateMappedArguments() {
|
| @@ -1268,20 +1239,15 @@ void BytecodeGraphBuilder::VisitCreateRestParameter() {
|
| BuildCreateArguments(CreateArgumentsType::kRestParameter);
|
| }
|
|
|
| -void BytecodeGraphBuilder::BuildCreateLiteral(const Operator* op) {
|
| - FrameStateBeforeAndAfter states(this);
|
| - Node* literal = NewNode(op, GetFunctionClosure());
|
| - environment()->BindAccumulator(literal, &states);
|
| -}
|
| -
|
| void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
|
| Handle<String> constant_pattern =
|
| Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
|
| int literal_index = bytecode_iterator().GetIndexOperand(1);
|
| int literal_flags = bytecode_iterator().GetFlagOperand(2);
|
| - const Operator* op = javascript()->CreateLiteralRegExp(
|
| - constant_pattern, literal_flags, literal_index);
|
| - BuildCreateLiteral(op);
|
| + Node* literal = NewNode(javascript()->CreateLiteralRegExp(
|
| + constant_pattern, literal_flags, literal_index),
|
| + GetFunctionClosure());
|
| + environment()->BindAccumulator(literal, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
|
| @@ -1295,13 +1261,15 @@ void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
|
| // code. We can revisit this when we have data to the contrary.
|
| literal_flags |= ArrayLiteral::kDisableMementos;
|
| int number_of_elements = constant_elements->length();
|
| - const Operator* op = javascript()->CreateLiteralArray(
|
| - constant_elements, literal_flags, literal_index, number_of_elements);
|
| - BuildCreateLiteral(op);
|
| + Node* literal = NewNode(
|
| + javascript()->CreateLiteralArray(constant_elements, literal_flags,
|
| + literal_index, number_of_elements),
|
| + GetFunctionClosure());
|
| + environment()->BindAccumulator(literal, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Handle<FixedArray> constant_properties = Handle<FixedArray>::cast(
|
| bytecode_iterator().GetConstantForIndexOperand(0));
|
| int literal_index = bytecode_iterator().GetIndexOperand(1);
|
| @@ -1315,7 +1283,7 @@ void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
|
| literal_index, number_of_properties),
|
| GetFunctionClosure());
|
| environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3),
|
| - literal, &states);
|
| + literal, Environment::kAttachFrameState);
|
| }
|
|
|
| Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
|
| @@ -1335,7 +1303,7 @@ Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode) {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
|
| Node* callee =
|
| environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
| @@ -1352,7 +1320,7 @@ void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode) {
|
| const Operator* call = javascript()->CallFunction(
|
| arg_count + 1, frequency, feedback, receiver_hint, tail_call_mode);
|
| Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
|
| - environment()->BindAccumulator(value, &states);
|
| + environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitCall() { BuildCall(TailCallMode::kDisallow); }
|
| @@ -1366,7 +1334,7 @@ void BytecodeGraphBuilder::VisitTailCall() {
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitCallJSRuntime() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* callee =
|
| BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0));
|
| interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
|
| @@ -1375,7 +1343,7 @@ void BytecodeGraphBuilder::VisitCallJSRuntime() {
|
| // Create node to perform the JS runtime call.
|
| const Operator* call = javascript()->CallFunction(arg_count + 1);
|
| Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
|
| - environment()->BindAccumulator(value, &states);
|
| + environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
| }
|
|
|
| Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
|
| @@ -1392,7 +1360,7 @@ Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitCallRuntime() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
|
| interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
|
| size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
| @@ -1400,11 +1368,11 @@ 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);
|
| - environment()->BindAccumulator(value, &states);
|
| + environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
|
| interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
|
| size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
| @@ -1414,11 +1382,12 @@ void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
|
| // Create node to perform the runtime call.
|
| const Operator* call = javascript()->CallRuntime(functionId, arg_count);
|
| Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
|
| - environment()->BindRegistersToProjections(first_return, return_pair, &states);
|
| + environment()->BindRegistersToProjections(first_return, return_pair,
|
| + Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
|
| interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
|
| size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
| @@ -1427,7 +1396,7 @@ void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
|
| // lowering.
|
| const Operator* call = javascript()->CallRuntime(functionId, arg_count);
|
| Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
|
| - environment()->BindAccumulator(value, &states);
|
| + environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
| }
|
|
|
| Node* BytecodeGraphBuilder::ProcessCallNewArguments(
|
| @@ -1446,7 +1415,7 @@ Node* BytecodeGraphBuilder::ProcessCallNewArguments(
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitNew() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
|
| interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
|
| size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
|
| @@ -1464,14 +1433,14 @@ void BytecodeGraphBuilder::VisitNew() {
|
| static_cast<int>(arg_count) + 2, frequency, feedback);
|
| Node* value = ProcessCallNewArguments(call, callee, new_target, first_arg,
|
| arg_count + 2);
|
| - environment()->BindAccumulator(value, &states);
|
| + environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildThrow() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* value = environment()->LookupAccumulator();
|
| Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
|
| - environment()->BindAccumulator(call, &states);
|
| + environment()->BindAccumulator(call, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitThrow() {
|
| @@ -1491,12 +1460,12 @@ void BytecodeGraphBuilder::VisitReThrow() {
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* left =
|
| environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
| Node* right = environment()->LookupAccumulator();
|
| Node* node = NewNode(js_op, left, right);
|
| - environment()->BindAccumulator(node, &states);
|
| + environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
| }
|
|
|
| // Helper function to create binary operation hint from the recorded type
|
| @@ -1590,12 +1559,12 @@ void BytecodeGraphBuilder::VisitShiftRightLogical() {
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* js_op) {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* left =
|
| environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
|
| Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
|
| Node* node = NewNode(js_op, left, right);
|
| - environment()->BindAccumulator(node, &states);
|
| + environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitAddSmi() {
|
| @@ -1629,23 +1598,23 @@ void BytecodeGraphBuilder::VisitShiftRightSmi() {
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitInc() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| // Note: Use subtract -1 here instead of add 1 to ensure we always convert to
|
| // a number, not a string.
|
| const Operator* js_op =
|
| javascript()->Subtract(GetBinaryOperationHint(kCountOperationHintIndex));
|
| Node* node = NewNode(js_op, environment()->LookupAccumulator(),
|
| jsgraph()->Constant(-1));
|
| - environment()->BindAccumulator(node, &states);
|
| + environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitDec() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| const Operator* js_op =
|
| javascript()->Subtract(GetBinaryOperationHint(kCountOperationHintIndex));
|
| Node* node = NewNode(js_op, environment()->LookupAccumulator(),
|
| jsgraph()->OneConstant());
|
| - environment()->BindAccumulator(node, &states);
|
| + environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitLogicalNot() {
|
| @@ -1670,13 +1639,13 @@ void BytecodeGraphBuilder::VisitTypeOf() {
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* key = environment()->LookupAccumulator();
|
| Node* object =
|
| environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
| Node* node =
|
| NewNode(javascript()->DeleteProperty(language_mode), object, key);
|
| - environment()->BindAccumulator(node, &states);
|
| + environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
|
| @@ -1688,12 +1657,12 @@ void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* left =
|
| environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
| Node* right = environment()->LookupAccumulator();
|
| Node* node = NewNode(js_op, left, right);
|
| - environment()->BindAccumulator(node, &states);
|
| + environment()->BindAccumulator(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitTestEqual() {
|
| @@ -1733,10 +1702,10 @@ void BytecodeGraphBuilder::VisitTestInstanceOf() {
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* value = NewNode(js_op, environment()->LookupAccumulator());
|
| environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value,
|
| - &states);
|
| + Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitToName() {
|
| @@ -1804,9 +1773,9 @@ void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
|
| void BytecodeGraphBuilder::VisitJumpLoop() { BuildJump(); }
|
|
|
| void BytecodeGraphBuilder::VisitStackCheck() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* node = NewNode(javascript()->StackCheck());
|
| - environment()->RecordAfterState(node, &states);
|
| + environment()->RecordAfterState(node, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitReturn() {
|
| @@ -1817,10 +1786,10 @@ void BytecodeGraphBuilder::VisitReturn() {
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitDebugger() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* call =
|
| NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
|
| - environment()->BindAccumulator(call, &states);
|
| + environment()->BindAccumulator(call, Environment::kAttachFrameState);
|
| environment()->MarkAllRegistersLive();
|
| }
|
|
|
| @@ -1831,18 +1800,19 @@ DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
|
| #undef DEBUG_BREAK
|
|
|
| void BytecodeGraphBuilder::BuildForInPrepare() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* receiver =
|
| environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
| Node* prepare = NewNode(javascript()->ForInPrepare(), receiver);
|
| environment()->BindRegistersToProjections(
|
| - bytecode_iterator().GetRegisterOperand(1), prepare, &states);
|
| + bytecode_iterator().GetRegisterOperand(1), prepare,
|
| + Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitForInPrepare() { BuildForInPrepare(); }
|
|
|
| void BytecodeGraphBuilder::VisitForInContinue() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* index =
|
| environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
| Node* cache_length =
|
| @@ -1850,11 +1820,11 @@ void BytecodeGraphBuilder::VisitForInContinue() {
|
| Node* exit_cond =
|
| NewNode(javascript()->LessThan(CompareOperationHint::kSignedSmall), index,
|
| cache_length);
|
| - environment()->BindAccumulator(exit_cond, &states);
|
| + environment()->BindAccumulator(exit_cond, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::BuildForInNext() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* receiver =
|
| environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
| Node* index =
|
| @@ -1867,18 +1837,18 @@ void BytecodeGraphBuilder::BuildForInNext() {
|
|
|
| Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
|
| cache_type, index);
|
| - environment()->BindAccumulator(value, &states);
|
| + environment()->BindAccumulator(value, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitForInNext() { BuildForInNext(); }
|
|
|
| void BytecodeGraphBuilder::VisitForInStep() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
| Node* index =
|
| environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
| index = NewNode(javascript()->Add(BinaryOperationHint::kSignedSmall), index,
|
| jsgraph()->OneConstant());
|
| - environment()->BindAccumulator(index, &states);
|
| + environment()->BindAccumulator(index, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitSuspendGenerator() {
|
| @@ -1908,7 +1878,7 @@ void BytecodeGraphBuilder::VisitSuspendGenerator() {
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitResumeGenerator() {
|
| - FrameStateBeforeAndAfter states(this);
|
| + PrepareEagerCheckpoint();
|
|
|
| Node* generator = environment()->LookupRegister(
|
| bytecode_iterator().GetRegisterOperand(0));
|
| @@ -1923,7 +1893,7 @@ void BytecodeGraphBuilder::VisitResumeGenerator() {
|
| Node* state =
|
| NewNode(javascript()->GeneratorRestoreContinuation(), generator);
|
|
|
| - environment()->BindAccumulator(state, &states);
|
| + environment()->BindAccumulator(state, Environment::kAttachFrameState);
|
| }
|
|
|
| void BytecodeGraphBuilder::VisitWide() {
|
| @@ -2146,9 +2116,9 @@ Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
|
| *current_input++ = environment()->Context();
|
| }
|
| 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.
|
| + // 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 by the
|
| + // calls to {PrepareFrameState} within individual visitor methods.
|
| *current_input++ = jsgraph()->Dead();
|
| }
|
| if (has_effect) {
|
|
|