Commit 291ab70f authored by petermarshall's avatar petermarshall Committed by Commit bot

[Turbofan] Add CallConstructWithSpread JSOperator.

Add the operator in preparation for actual perf work. The operator is replaced
by the same runtime call as before, during lowering.

The CallConstructWithSpreadParameters is a bit silly at the moment, but will
hold more once we add feedback.

BUG=v8:5659

Review-Url: https://codereview.chromium.org/2561103003
Cr-Commit-Position: refs/heads/master@{#41636}
parent 80567914
......@@ -1340,9 +1340,9 @@ void BytecodeGraphBuilder::VisitNewWithSpread() {
interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(0);
size_t arg_count = bytecode_iterator().GetRegisterCountOperand(1);
const Operator* call =
javascript()->CallRuntime(Runtime::kNewWithSpread, arg_count);
Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
const Operator* op =
javascript()->CallConstructWithSpread(static_cast<int>(arg_count));
Node* value = ProcessCallRuntimeArguments(op, first_arg, arg_count);
environment()->BindAccumulator(value, Environment::kAttachFrameState);
}
......
......@@ -474,6 +474,12 @@ void JSGenericLowering::LowerJSCallConstruct(Node* node) {
NodeProperties::ChangeOp(node, common()->Call(desc));
}
void JSGenericLowering::LowerJSCallConstructWithSpread(Node* node) {
CallConstructWithSpreadParameters const& p =
CallConstructWithSpreadParametersOf(node->op());
ReplaceWithRuntimeCall(node, Runtime::kNewWithSpread,
static_cast<int>(p.arity()));
}
void JSGenericLowering::LowerJSCallFunction(Node* node) {
CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
......
......@@ -80,6 +80,30 @@ CallConstructParameters const& CallConstructParametersOf(Operator const* op) {
return OpParameter<CallConstructParameters>(op);
}
bool operator==(CallConstructWithSpreadParameters const& lhs,
CallConstructWithSpreadParameters const& rhs) {
return lhs.arity() == rhs.arity();
}
bool operator!=(CallConstructWithSpreadParameters const& lhs,
CallConstructWithSpreadParameters const& rhs) {
return !(lhs == rhs);
}
size_t hash_value(CallConstructWithSpreadParameters const& p) {
return base::hash_combine(p.arity());
}
std::ostream& operator<<(std::ostream& os,
CallConstructWithSpreadParameters const& p) {
return os << p.arity();
}
CallConstructWithSpreadParameters const& CallConstructWithSpreadParametersOf(
Operator const* op) {
DCHECK_EQ(IrOpcode::kJSCallConstructWithSpread, op->opcode());
return OpParameter<CallConstructWithSpreadParameters>(op);
}
std::ostream& operator<<(std::ostream& os, CallFunctionParameters const& p) {
os << p.arity() << ", " << p.frequency() << ", " << p.convert_mode() << ", "
......@@ -647,6 +671,14 @@ const Operator* JSOperatorBuilder::CallConstruct(
parameters); // parameter
}
const Operator* JSOperatorBuilder::CallConstructWithSpread(uint32_t arity) {
CallConstructWithSpreadParameters parameters(arity);
return new (zone()) Operator1<CallConstructWithSpreadParameters>( // --
IrOpcode::kJSCallConstructWithSpread, Operator::kNoProperties, // opcode
"JSCallConstructWithSpread", // name
parameters.arity(), 1, 1, 1, 1, 2, // counts
parameters); // parameter
}
const Operator* JSOperatorBuilder::ConvertReceiver(
ConvertReceiverMode convert_mode) {
......
......@@ -80,6 +80,31 @@ std::ostream& operator<<(std::ostream&, CallConstructParameters const&);
CallConstructParameters const& CallConstructParametersOf(Operator const*);
// Defines the arity for a JavaScript constructor call with a spread as the last
// parameters. This is used as a parameter by JSCallConstructWithSpread
// operators.
class CallConstructWithSpreadParameters final {
public:
explicit CallConstructWithSpreadParameters(uint32_t arity) : arity_(arity) {}
uint32_t arity() const { return arity_; }
private:
uint32_t const arity_;
};
bool operator==(CallConstructWithSpreadParameters const&,
CallConstructWithSpreadParameters const&);
bool operator!=(CallConstructWithSpreadParameters const&,
CallConstructWithSpreadParameters const&);
size_t hash_value(CallConstructWithSpreadParameters const&);
std::ostream& operator<<(std::ostream&,
CallConstructWithSpreadParameters const&);
CallConstructWithSpreadParameters const& CallConstructWithSpreadParametersOf(
Operator const*);
// Defines the arity and the call flags for a JavaScript function call. This is
// used as a parameter by JSCallFunction operators.
......@@ -478,6 +503,7 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* CallRuntime(const Runtime::Function* function, size_t arity);
const Operator* CallConstruct(uint32_t arity, float frequency,
VectorSlotPair const& feedback);
const Operator* CallConstructWithSpread(uint32_t arity);
const Operator* ConvertReceiver(ConvertReceiverMode convert_mode);
......
......@@ -155,6 +155,7 @@
#define JS_OTHER_OP_LIST(V) \
V(JSCallConstruct) \
V(JSCallConstructWithSpread) \
V(JSCallFunction) \
V(JSCallRuntime) \
V(JSConvertReceiver) \
......
......@@ -94,6 +94,7 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
// Call operations
case IrOpcode::kJSCallConstruct:
case IrOpcode::kJSCallConstructWithSpread:
case IrOpcode::kJSCallFunction:
// Misc operations
......
......@@ -1305,6 +1305,10 @@ Type* Typer::Visitor::TypeJSCallConstruct(Node* node) {
return Type::Receiver();
}
Type* Typer::Visitor::TypeJSCallConstructWithSpread(Node* node) {
return Type::Receiver();
}
Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
if (fun->IsHeapConstant() && fun->AsHeapConstant()->Value()->IsJSFunction()) {
Handle<JSFunction> function =
......
......@@ -659,6 +659,7 @@ void Verifier::Visitor::Check(Node* node) {
}
case IrOpcode::kJSCallConstruct:
case IrOpcode::kJSCallConstructWithSpread:
case IrOpcode::kJSConvertReceiver:
// Type is Receiver.
CheckTypeIs(node, Type::Receiver());
......
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