diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index 68c29a3dc7..cdfea6a4e4 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -410,8 +410,8 @@ AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, Node* AstGraphBuilder::GetFunctionClosure() { if (!function_closure_.is_set()) { - const Operator* op = - common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex); + const Operator* op = common()->Parameter( + Linkage::kJSFunctionCallClosureParamIndex, "%closure"); Node* node = NewNode(op, graph()->start()); function_closure_.set(node); } @@ -428,7 +428,8 @@ void AstGraphBuilder::CreateFunctionContext(bool constant_context) { Node* AstGraphBuilder::NewOuterContextParam() { // Parameter (arity + 1) is special for the outer context of the function - const Operator* op = common()->Parameter(info()->num_parameters() + 1); + const Operator* op = + common()->Parameter(info()->num_parameters() + 1, "%context"); return NewNode(op, graph()->start()); } @@ -436,7 +437,8 @@ Node* AstGraphBuilder::NewOuterContextParam() { Node* AstGraphBuilder::NewCurrentContextOsrValue() { // TODO(titzer): use a real OSR value here; a parameter works by accident. // Parameter (arity + 1) is special for the outer context of the function - const Operator* op = common()->Parameter(info()->num_parameters() + 1); + const Operator* op = + common()->Parameter(info()->num_parameters() + 1, "%osr-context"); return NewNode(op, graph()->start()); } @@ -575,6 +577,20 @@ static LhsKind DetermineLhsKind(Expression* expr) { } +static const char* GetDebugParameterName(Zone* zone, Scope* scope, int index) { +#if DEBUG + const AstRawString* name = scope->parameter(index)->raw_name(); + if (name && name->length() > 0) { + char* data = zone->NewArray(name->length() + 1); + data[name->length()] = 0; + memcpy(data, name->raw_data(), name->length()); + return data; + } +#endif + return nullptr; +} + + AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, Scope* scope, Node* control_dependency) @@ -592,15 +608,16 @@ AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); // Bind the receiver variable. - Node* receiver = builder->graph()->NewNode(common()->Parameter(0), + Node* receiver = builder->graph()->NewNode(common()->Parameter(0, "%this"), builder->graph()->start()); values()->push_back(receiver); // Bind all parameter variables. The parameter indices are shifted by 1 // (receiver is parameter index -1 but environment index 0). for (int i = 0; i < scope->num_parameters(); ++i) { - Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1), - builder->graph()->start()); + const char* debug_name = GetDebugParameterName(graph()->zone(), scope, i); + Node* parameter = builder->graph()->NewNode( + common()->Parameter(i + 1, debug_name), builder->graph()->start()); values()->push_back(parameter); } diff --git a/src/compiler/common-operator.cc b/src/compiler/common-operator.cc index 932acc30b4..0c1361511a 100644 --- a/src/compiler/common-operator.cc +++ b/src/compiler/common-operator.cc @@ -109,6 +109,38 @@ size_t ProjectionIndexOf(const Operator* const op) { } +int ParameterIndexOf(const Operator* const op) { + DCHECK_EQ(IrOpcode::kParameter, op->opcode()); + return OpParameter(op).index(); +} + + +const ParameterInfo& ParameterInfoOf(const Operator* const op) { + DCHECK_EQ(IrOpcode::kParameter, op->opcode()); + return OpParameter(op); +} + + +bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) { + return lhs.index() == rhs.index(); +} + + +bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) { + return !(lhs == rhs); +} + + +size_t hash_value(ParameterInfo const& p) { return p.index(); } + + +std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) { + if (i.debug_name()) os << i.debug_name() << '#'; + os << i.index(); + return os; +} + + #define CACHED_OP_LIST(V) \ V(Always, Operator::kPure, 0, 0, 0, 1, 0, 0) \ V(Dead, Operator::kFoldable, 0, 0, 0, 0, 0, 1) \ @@ -276,13 +308,13 @@ struct CommonOperatorGlobalCache final { #undef CACHED_PHI template - struct ParameterOperator final : public Operator1 { + struct ParameterOperator final : public Operator1 { ParameterOperator() - : Operator1( // -- + : Operator1( // -- IrOpcode::kParameter, Operator::kPure, // opcode "Parameter", // name 1, 0, 0, 1, 0, 0, // counts, - kIndex) {} // parameter + ParameterInfo(kIndex, nullptr)) {} // parameter and name }; #define CACHED_PARAMETER(index) \ ParameterOperator kParameter##index##Operator; @@ -416,22 +448,25 @@ const Operator* CommonOperatorBuilder::Merge(int control_input_count) { } -const Operator* CommonOperatorBuilder::Parameter(int index) { - switch (index) { +const Operator* CommonOperatorBuilder::Parameter(int index, + const char* debug_name) { + if (!debug_name) { + switch (index) { #define CACHED_PARAMETER(index) \ case index: \ return &cache_.kParameter##index##Operator; - CACHED_PARAMETER_LIST(CACHED_PARAMETER) + CACHED_PARAMETER_LIST(CACHED_PARAMETER) #undef CACHED_PARAMETER - default: - break; + default: + break; + } } // Uncached. - return new (zone()) Operator1( // -- - IrOpcode::kParameter, Operator::kPure, // opcode - "Parameter", // name - 1, 0, 0, 1, 0, 0, // counts - index); // parameter + return new (zone()) Operator1( // -- + IrOpcode::kParameter, Operator::kPure, // opcode + "Parameter", // name + 1, 0, 0, 1, 0, 0, // counts + ParameterInfo(index, debug_name)); // parameter info } diff --git a/src/compiler/common-operator.h b/src/compiler/common-operator.h index 2d90e64899..a453b8159d 100644 --- a/src/compiler/common-operator.h +++ b/src/compiler/common-operator.h @@ -156,6 +156,27 @@ std::ostream& operator<<(std::ostream&, FrameStateCallInfo const&); size_t ProjectionIndexOf(const Operator* const); +// The {IrOpcode::kParameter} opcode represents an incoming parameter to the +// function. This class bundles the index and a debug name for such operators. +class ParameterInfo final { + public: + ParameterInfo(int index, const char* debug_name) + : index_(index), debug_name_(debug_name) {} + + int index() const { return index_; } + const char* debug_name() const { return debug_name_; } + + private: + int index_; + const char* debug_name_; +}; + +std::ostream& operator<<(std::ostream&, ParameterInfo const&); + +int ParameterIndexOf(const Operator* const); +const ParameterInfo& ParameterInfoOf(const Operator* const); + + // Interface for building common operators that can be used at any level of IR, // including JavaScript, mid-level, and low-level. class CommonOperatorBuilder final : public ZoneObject { @@ -184,7 +205,7 @@ class CommonOperatorBuilder final : public ZoneObject { const Operator* Start(int num_formal_parameters); const Operator* Loop(int control_input_count); const Operator* Merge(int control_input_count); - const Operator* Parameter(int index); + const Operator* Parameter(int index, const char* debug_name = nullptr); const Operator* OsrNormalEntry(); const Operator* OsrLoopEntry(); diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc index 8c94129713..29f8ed4dc7 100644 --- a/src/compiler/instruction-selector.cc +++ b/src/compiler/instruction-selector.cc @@ -609,7 +609,8 @@ void InstructionSelector::VisitNode(Node* node) { case IrOpcode::kFinish: return MarkAsReference(node), VisitFinish(node); case IrOpcode::kParameter: { - MachineType type = linkage()->GetParameterType(OpParameter(node)); + MachineType type = + linkage()->GetParameterType(ParameterIndexOf(node->op())); MarkAsRepresentation(type, node); return VisitParameter(node); } @@ -968,7 +969,7 @@ void InstructionSelector::VisitFinish(Node* node) { void InstructionSelector::VisitParameter(Node* node) { OperandGenerator g(this); - int index = OpParameter(node); + int index = ParameterIndexOf(node->op()); Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetParameterLocation(index), linkage()->GetParameterType(index))); diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc index 6c7b66681d..947f720c87 100644 --- a/src/compiler/js-inlining.cc +++ b/src/compiler/js-inlining.cc @@ -235,7 +235,7 @@ Reduction Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) { Node* use = edge.from(); switch (use->opcode()) { case IrOpcode::kParameter: { - int index = 1 + OpParameter(use->op()); + int index = 1 + ParameterIndexOf(use->op()); if (index < inliner_inputs && index < inlinee_context_index) { // There is an input from the call, and the index is a value // projection but not the context, so rewire the input. diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc index fb017166dc..e216428c96 100644 --- a/src/compiler/verifier.cc +++ b/src/compiler/verifier.cc @@ -55,16 +55,6 @@ class Verifier::Visitor { Node* ValueInput(Node* node, int i = 0) { return NodeProperties::GetValueInput(node, i); } - FieldAccess Field(Node* node) { - DCHECK(node->opcode() == IrOpcode::kLoadField || - node->opcode() == IrOpcode::kStoreField); - return OpParameter(node); - } - ElementAccess Element(Node* node) { - DCHECK(node->opcode() == IrOpcode::kLoadElement || - node->opcode() == IrOpcode::kStoreElement); - return OpParameter(node); - } void CheckNotTyped(Node* node) { if (NodeProperties::IsTyped(node)) { std::ostringstream str; @@ -714,7 +704,7 @@ void Verifier::Visitor::Check(Node* node) { // Object -> fieldtype // TODO(rossberg): activate once machine ops are typed. // CheckValueInputIs(node, 0, Type::Object()); - // CheckUpperIs(node, Field(node).type)); + // CheckUpperIs(node, FieldAccessOf(node->op()).type)); break; case IrOpcode::kLoadBuffer: break; @@ -722,13 +712,13 @@ void Verifier::Visitor::Check(Node* node) { // Object -> elementtype // TODO(rossberg): activate once machine ops are typed. // CheckValueInputIs(node, 0, Type::Object()); - // CheckUpperIs(node, Element(node).type)); + // CheckUpperIs(node, ElementAccessOf(node->op()).type)); break; case IrOpcode::kStoreField: // (Object, fieldtype) -> _|_ // TODO(rossberg): activate once machine ops are typed. // CheckValueInputIs(node, 0, Type::Object()); - // CheckValueInputIs(node, 1, Field(node).type)); + // CheckValueInputIs(node, 1, FieldAccessOf(node->op()).type)); CheckNotTyped(node); break; case IrOpcode::kStoreBuffer: @@ -737,7 +727,7 @@ void Verifier::Visitor::Check(Node* node) { // (Object, elementtype) -> _|_ // TODO(rossberg): activate once machine ops are typed. // CheckValueInputIs(node, 0, Type::Object()); - // CheckValueInputIs(node, 1, Element(node).type)); + // CheckValueInputIs(node, 1, ElementAccessOf(node->op()).type)); CheckNotTyped(node); break;