Commit 71ee0aa5 authored by mvstanton's avatar mvstanton Committed by Commit bot

[turbofan] Optimized support for CreateGeneratorObject.

Intrinsic and generic lowering for generator object creation. In a follow-on, create lowering will be addressed.

BUG=v8:6352

Review-Url: https://codereview.chromium.org/2862213002
Cr-Commit-Position: refs/heads/master@{#45171}
parent ededfcd2
......@@ -423,6 +423,13 @@ void JSGenericLowering::LowerJSCreateFunctionContext(Node* node) {
}
}
void JSGenericLowering::LowerJSCreateGeneratorObject(Node* node) {
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable =
Builtins::CallableFor(isolate(), Builtins::kCreateGeneratorObject);
node->RemoveInput(4); // control
ReplaceWithStubCall(node, callable, flags);
}
void JSGenericLowering::LowerJSCreateIterResultObject(Node* node) {
ReplaceWithRuntimeCall(node, Runtime::kCreateIterResultObject);
......
......@@ -38,6 +38,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceDeoptimizeNow(node);
case Runtime::kInlineGeneratorClose:
return ReduceGeneratorClose(node);
case Runtime::kInlineCreateJSGeneratorObject:
return ReduceCreateJSGeneratorObject(node);
case Runtime::kInlineGeneratorGetInputOrDebugPos:
return ReduceGeneratorGetInputOrDebugPos(node);
case Runtime::kInlineAsyncGeneratorGetAwaitInputOrDebugPos:
......@@ -159,6 +161,19 @@ Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
return Changed(node);
}
Reduction JSIntrinsicLowering::ReduceCreateJSGeneratorObject(Node* node) {
Node* const closure = NodeProperties::GetValueInput(node, 0);
Node* const receiver = NodeProperties::GetValueInput(node, 1);
Node* const context = NodeProperties::GetContextInput(node);
Node* const effect = NodeProperties::GetEffectInput(node);
Node* const control = NodeProperties::GetControlInput(node);
Operator const* const op = javascript()->CreateGeneratorObject();
Node* create_generator =
graph()->NewNode(op, closure, receiver, context, effect, control);
ReplaceWithValue(node, create_generator, create_generator);
return Changed(create_generator);
}
Reduction JSIntrinsicLowering::ReduceGeneratorClose(Node* node) {
Node* const generator = NodeProperties::GetValueInput(node, 0);
Node* const effect = NodeProperties::GetEffectInput(node);
......
......@@ -43,6 +43,7 @@ class V8_EXPORT_PRIVATE JSIntrinsicLowering final
Reduction ReduceCreateIterResultObject(Node* node);
Reduction ReduceDebugIsActive(Node* node);
Reduction ReduceDeoptimizeNow(Node* node);
Reduction ReduceCreateJSGeneratorObject(Node* node);
Reduction ReduceGeneratorClose(Node* node);
Reduction ReduceGeneratorGetContext(Node* node);
Reduction ReduceGeneratorGetInputOrDebugPos(Node* node);
......
......@@ -904,6 +904,12 @@ const Operator* JSOperatorBuilder::DeleteProperty() {
3, 1, 1, 1, 1, 2); // counts
}
const Operator* JSOperatorBuilder::CreateGeneratorObject() {
return new (zone()) Operator( // --
IrOpcode::kJSCreateGeneratorObject, Operator::kEliminatable, // opcode
"JSCreateGeneratorObject", // name
2, 1, 1, 1, 1, 0); // counts
}
const Operator* JSOperatorBuilder::LoadGlobal(const Handle<Name>& name,
const VectorSlotPair& feedback,
......
......@@ -701,6 +701,8 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* GetSuperConstructor();
const Operator* CreateGeneratorObject();
const Operator* LoadGlobal(const Handle<Name>& name,
const VectorSlotPair& feedback,
TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
......
......@@ -178,6 +178,7 @@ bool Linkage::NeedsFrameStateInput(Runtime::FunctionId function) {
case Runtime::kInlineGeneratorClose:
case Runtime::kInlineGeneratorGetInputOrDebugPos:
case Runtime::kInlineGeneratorGetResumeMode:
case Runtime::kInlineCreateJSGeneratorObject:
case Runtime::kInlineIsArray:
case Runtime::kInlineIsJSMap:
case Runtime::kInlineIsJSSet:
......
......@@ -146,6 +146,7 @@
V(JSStoreDataPropertyInLiteral) \
V(JSDeleteProperty) \
V(JSHasProperty) \
V(JSCreateGeneratorObject) \
V(JSGetSuperConstructor)
#define JS_CONTEXT_OP_LIST(V) \
......
......@@ -34,6 +34,10 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
case IrOpcode::kJSStrictEqual:
return false;
// Generator creation cannot call back into arbitrary JavaScript.
case IrOpcode::kJSCreateGeneratorObject:
return false;
// Binary operations
case IrOpcode::kJSAdd:
case IrOpcode::kJSSubtract:
......
......@@ -1116,6 +1116,10 @@ Type* Typer::Visitor::TypeJSCreateArguments(Node* node) {
Type* Typer::Visitor::TypeJSCreateArray(Node* node) { return Type::Array(); }
Type* Typer::Visitor::TypeJSCreateGeneratorObject(Node* node) {
return Type::OtherObject();
}
Type* Typer::Visitor::TypeJSCreateClosure(Node* node) {
return Type::Function();
}
......
......@@ -739,6 +739,10 @@ void Verifier::Visitor::Check(Node* node) {
CheckNotTyped(node);
break;
case IrOpcode::kJSCreateGeneratorObject:
CheckTypeIs(node, Type::OtherObject());
break;
case IrOpcode::kJSGeneratorRestoreContinuation:
CheckTypeIs(node, Type::SignedSmall());
break;
......@@ -1706,7 +1710,7 @@ void Verifier::VerifyNode(Node* node) {
CHECK_EQ(OperatorProperties::GetTotalInputCount(node->op()),
node->InputCount());
// If this node has no effect or no control outputs,
// we check that no its uses are effect or control inputs.
// we check that none of its uses are effect or control inputs.
bool check_no_control = node->op()->ControlOutputCount() == 0;
bool check_no_effect = node->op()->EffectOutputCount() == 0;
bool check_no_frame_state = node->opcode() != IrOpcode::kFrameState;
......
......@@ -144,6 +144,23 @@ TEST_F(JSIntrinsicLoweringTest, InlineIsJSReceiver) {
EXPECT_THAT(r.replacement(), IsObjectIsReceiver(input));
}
// -----------------------------------------------------------------------------
// %_CreateJSGeneratorObject
TEST_F(JSIntrinsicLoweringTest, InlineCreateJSGeneratorObject) {
Node* const function = Parameter(0);
Node* const receiver = Parameter(1);
Node* const context = Parameter(2);
Node* const effect = graph()->start();
Node* const control = graph()->start();
Reduction const r = Reduce(graph()->NewNode(
javascript()->CallRuntime(Runtime::kInlineCreateJSGeneratorObject, 2),
function, receiver, context, effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_EQ(IrOpcode::kJSCreateGeneratorObject,
r.replacement()->op()->opcode());
}
} // namespace compiler
} // namespace internal
} // namespace v8
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