Commit 01662f1b authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Add support for CreateIterResultObject.

Introduce JSCreateIterResultObject operator, as a way to optimize the
%_CreateIterResultObject intrinsic, which is used to provide uniform,
non-polymorphic result objects for iterators (and generators).  We
cannot utilize the existing JSCreate operator here, because there's no
constructor function for iterator result objects (as required by the
spec).

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/1531753002

Cr-Commit-Position: refs/heads/master@{#32901}
parent d0ef84b3
...@@ -128,6 +128,24 @@ FieldAccess AccessBuilder::ForJSDateField(JSDate::FieldIndex index) { ...@@ -128,6 +128,24 @@ FieldAccess AccessBuilder::ForJSDateField(JSDate::FieldIndex index) {
} }
// static
FieldAccess AccessBuilder::ForJSIteratorResultDone() {
FieldAccess access = {kTaggedBase, JSIteratorResult::kDoneOffset,
MaybeHandle<Name>(), Type::Any(),
MachineType::AnyTagged()};
return access;
}
// static
FieldAccess AccessBuilder::ForJSIteratorResultValue() {
FieldAccess access = {kTaggedBase, JSIteratorResult::kValueOffset,
MaybeHandle<Name>(), Type::Any(),
MachineType::AnyTagged()};
return access;
}
// static // static
FieldAccess AccessBuilder::ForJSRegExpFlags() { FieldAccess AccessBuilder::ForJSRegExpFlags() {
FieldAccess access = {kTaggedBase, JSRegExp::kFlagsOffset, FieldAccess access = {kTaggedBase, JSRegExp::kFlagsOffset,
......
...@@ -55,6 +55,12 @@ class AccessBuilder final : public AllStatic { ...@@ -55,6 +55,12 @@ class AccessBuilder final : public AllStatic {
// Provides access to JSDate fields. // Provides access to JSDate fields.
static FieldAccess ForJSDateField(JSDate::FieldIndex index); static FieldAccess ForJSDateField(JSDate::FieldIndex index);
// Provides access to JSIteratorResult::done() field.
static FieldAccess ForJSIteratorResultDone();
// Provides access to JSIteratorResult::value() field.
static FieldAccess ForJSIteratorResultValue();
// Provides access to JSRegExp::flags() field. // Provides access to JSRegExp::flags() field.
static FieldAccess ForJSRegExpFlags(); static FieldAccess ForJSRegExpFlags();
......
...@@ -498,6 +498,11 @@ void JSGenericLowering::LowerJSCreateClosure(Node* node) { ...@@ -498,6 +498,11 @@ void JSGenericLowering::LowerJSCreateClosure(Node* node) {
} }
void JSGenericLowering::LowerJSCreateIterResultObject(Node* node) {
ReplaceWithRuntimeCall(node, Runtime::kCreateIterResultObject);
}
void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) { void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index())); node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
......
...@@ -37,6 +37,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) { ...@@ -37,6 +37,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
switch (f->function_id) { switch (f->function_id) {
case Runtime::kInlineConstructDouble: case Runtime::kInlineConstructDouble:
return ReduceConstructDouble(node); return ReduceConstructDouble(node);
case Runtime::kInlineCreateIterResultObject:
return ReduceCreateIterResultObject(node);
case Runtime::kInlineDateField: case Runtime::kInlineDateField:
return ReduceDateField(node); return ReduceDateField(node);
case Runtime::kInlineDeoptimizeNow: case Runtime::kInlineDeoptimizeNow:
...@@ -116,6 +118,16 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) { ...@@ -116,6 +118,16 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
} }
Reduction JSIntrinsicLowering::ReduceCreateIterResultObject(Node* node) {
Node* const value = NodeProperties::GetValueInput(node, 0);
Node* const done = NodeProperties::GetValueInput(node, 1);
Node* const context = NodeProperties::GetContextInput(node);
Node* const effect = NodeProperties::GetEffectInput(node);
return Change(node, javascript()->CreateIterResultObject(), value, done,
context, effect);
}
Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) { Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) {
Node* high = NodeProperties::GetValueInput(node, 0); Node* high = NodeProperties::GetValueInput(node, 0);
Node* low = NodeProperties::GetValueInput(node, 1); Node* low = NodeProperties::GetValueInput(node, 1);
......
...@@ -39,6 +39,7 @@ class JSIntrinsicLowering final : public AdvancedReducer { ...@@ -39,6 +39,7 @@ class JSIntrinsicLowering final : public AdvancedReducer {
private: private:
Reduction ReduceConstructDouble(Node* node); Reduction ReduceConstructDouble(Node* node);
Reduction ReduceCreateIterResultObject(Node* node);
Reduction ReduceDateField(Node* node); Reduction ReduceDateField(Node* node);
Reduction ReduceDeoptimizeNow(Node* node); Reduction ReduceDeoptimizeNow(Node* node);
Reduction ReduceDoubleHi(Node* node); Reduction ReduceDoubleHi(Node* node);
......
...@@ -487,28 +487,29 @@ const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) { ...@@ -487,28 +487,29 @@ const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
} }
#define CACHED_OP_LIST(V) \ #define CACHED_OP_LIST(V) \
V(Equal, Operator::kNoProperties, 2, 1) \ V(Equal, Operator::kNoProperties, 2, 1) \
V(NotEqual, Operator::kNoProperties, 2, 1) \ V(NotEqual, Operator::kNoProperties, 2, 1) \
V(StrictEqual, Operator::kNoThrow, 2, 1) \ V(StrictEqual, Operator::kNoThrow, 2, 1) \
V(StrictNotEqual, Operator::kNoThrow, 2, 1) \ V(StrictNotEqual, Operator::kNoThrow, 2, 1) \
V(ToNumber, Operator::kNoProperties, 1, 1) \ V(ToNumber, Operator::kNoProperties, 1, 1) \
V(ToString, Operator::kNoProperties, 1, 1) \ V(ToString, Operator::kNoProperties, 1, 1) \
V(ToName, Operator::kNoProperties, 1, 1) \ V(ToName, Operator::kNoProperties, 1, 1) \
V(ToObject, Operator::kNoProperties, 1, 1) \ V(ToObject, Operator::kNoProperties, 1, 1) \
V(Yield, Operator::kNoProperties, 1, 1) \ V(Yield, Operator::kNoProperties, 1, 1) \
V(Create, Operator::kEliminatable, 2, 1) \ V(Create, Operator::kEliminatable, 2, 1) \
V(HasProperty, Operator::kNoProperties, 2, 1) \ V(CreateIterResultObject, Operator::kEliminatable, 2, 1) \
V(TypeOf, Operator::kEliminatable, 1, 1) \ V(HasProperty, Operator::kNoProperties, 2, 1) \
V(InstanceOf, Operator::kNoProperties, 2, 1) \ V(TypeOf, Operator::kEliminatable, 1, 1) \
V(ForInDone, Operator::kPure, 2, 1) \ V(InstanceOf, Operator::kNoProperties, 2, 1) \
V(ForInNext, Operator::kNoProperties, 4, 1) \ V(ForInDone, Operator::kPure, 2, 1) \
V(ForInPrepare, Operator::kNoProperties, 1, 3) \ V(ForInNext, Operator::kNoProperties, 4, 1) \
V(ForInStep, Operator::kPure, 1, 1) \ V(ForInPrepare, Operator::kNoProperties, 1, 3) \
V(LoadMessage, Operator::kNoThrow, 0, 1) \ V(ForInStep, Operator::kPure, 1, 1) \
V(StoreMessage, Operator::kNoThrow, 1, 0) \ V(LoadMessage, Operator::kNoThrow, 0, 1) \
V(StackCheck, Operator::kNoProperties, 0, 0) \ V(StoreMessage, Operator::kNoThrow, 1, 0) \
V(CreateWithContext, Operator::kNoProperties, 2, 1) \ V(StackCheck, Operator::kNoProperties, 0, 0) \
V(CreateWithContext, Operator::kNoProperties, 2, 1) \
V(CreateModuleContext, Operator::kNoProperties, 2, 1) V(CreateModuleContext, Operator::kNoProperties, 2, 1)
......
...@@ -514,6 +514,7 @@ class JSOperatorBuilder final : public ZoneObject { ...@@ -514,6 +514,7 @@ class JSOperatorBuilder final : public ZoneObject {
const Operator* CreateArray(size_t arity, Handle<AllocationSite> site); const Operator* CreateArray(size_t arity, Handle<AllocationSite> site);
const Operator* CreateClosure(Handle<SharedFunctionInfo> shared_info, const Operator* CreateClosure(Handle<SharedFunctionInfo> shared_info,
PretenureFlag pretenure); PretenureFlag pretenure);
const Operator* CreateIterResultObject();
const Operator* CreateLiteralArray(Handle<FixedArray> constant_elements, const Operator* CreateLiteralArray(Handle<FixedArray> constant_elements,
int literal_flags, int literal_index); int literal_flags, int literal_index);
const Operator* CreateLiteralObject(Handle<FixedArray> constant_properties, const Operator* CreateLiteralObject(Handle<FixedArray> constant_properties,
......
...@@ -1737,6 +1737,37 @@ Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) { ...@@ -1737,6 +1737,37 @@ Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) {
} }
Reduction JSTypedLowering::ReduceJSCreateIterResultObject(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode());
Node* value = NodeProperties::GetValueInput(node, 0);
Node* done = NodeProperties::GetValueInput(node, 1);
Node* context = NodeProperties::GetContextInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
// Load the JSIteratorResult map for the {context}.
Node* native_context = effect = graph()->NewNode(
javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
context, context, effect);
Node* iterator_result_map = effect = graph()->NewNode(
javascript()->LoadContext(0, Context::ITERATOR_RESULT_MAP_INDEX, true),
native_context, native_context, effect);
// Emit code to allocate the JSIteratorResult instance.
AllocationBuilder a(jsgraph(), effect, graph()->start());
a.Allocate(JSIteratorResult::kSize);
a.Store(AccessBuilder::ForMap(), iterator_result_map);
a.Store(AccessBuilder::ForJSObjectProperties(),
jsgraph()->EmptyFixedArrayConstant());
a.Store(AccessBuilder::ForJSObjectElements(),
jsgraph()->EmptyFixedArrayConstant());
a.Store(AccessBuilder::ForJSIteratorResultValue(), value);
a.Store(AccessBuilder::ForJSIteratorResultDone(), done);
STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
a.FinishAndChange(node);
return Changed(node);
}
Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) { Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateLiteralArray, node->opcode()); DCHECK_EQ(IrOpcode::kJSCreateLiteralArray, node->opcode());
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
...@@ -2515,6 +2546,8 @@ Reduction JSTypedLowering::Reduce(Node* node) { ...@@ -2515,6 +2546,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
return ReduceJSCreateArray(node); return ReduceJSCreateArray(node);
case IrOpcode::kJSCreateClosure: case IrOpcode::kJSCreateClosure:
return ReduceJSCreateClosure(node); return ReduceJSCreateClosure(node);
case IrOpcode::kJSCreateIterResultObject:
return ReduceJSCreateIterResultObject(node);
case IrOpcode::kJSCreateLiteralArray: case IrOpcode::kJSCreateLiteralArray:
return ReduceJSCreateLiteralArray(node); return ReduceJSCreateLiteralArray(node);
case IrOpcode::kJSCreateLiteralObject: case IrOpcode::kJSCreateLiteralObject:
......
...@@ -71,6 +71,7 @@ class JSTypedLowering final : public AdvancedReducer { ...@@ -71,6 +71,7 @@ class JSTypedLowering final : public AdvancedReducer {
Reduction ReduceJSCreateArguments(Node* node); Reduction ReduceJSCreateArguments(Node* node);
Reduction ReduceJSCreateArray(Node* node); Reduction ReduceJSCreateArray(Node* node);
Reduction ReduceJSCreateClosure(Node* node); Reduction ReduceJSCreateClosure(Node* node);
Reduction ReduceJSCreateIterResultObject(Node* node);
Reduction ReduceJSCreateLiteralArray(Node* node); Reduction ReduceJSCreateLiteralArray(Node* node);
Reduction ReduceJSCreateLiteralObject(Node* node); Reduction ReduceJSCreateLiteralObject(Node* node);
Reduction ReduceJSCreateFunctionContext(Node* node); Reduction ReduceJSCreateFunctionContext(Node* node);
......
...@@ -154,6 +154,7 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) { ...@@ -154,6 +154,7 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
// are blacklisted here and can be called without a FrameState. // are blacklisted here and can be called without a FrameState.
switch (function) { switch (function) {
case Runtime::kAllocateInTargetSpace: case Runtime::kAllocateInTargetSpace:
case Runtime::kCreateIterResultObject:
case Runtime::kDateField: case Runtime::kDateField:
case Runtime::kDefineClassMethod: // TODO(jarin): Is it safe? case Runtime::kDefineClassMethod: // TODO(jarin): Is it safe?
case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe? case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe?
......
...@@ -105,22 +105,23 @@ ...@@ -105,22 +105,23 @@
JS_CONVERSION_UNOP_LIST(V) \ JS_CONVERSION_UNOP_LIST(V) \
JS_OTHER_UNOP_LIST(V) JS_OTHER_UNOP_LIST(V)
#define JS_OBJECT_OP_LIST(V) \ #define JS_OBJECT_OP_LIST(V) \
V(JSCreate) \ V(JSCreate) \
V(JSCreateArguments) \ V(JSCreateArguments) \
V(JSCreateArray) \ V(JSCreateArray) \
V(JSCreateClosure) \ V(JSCreateClosure) \
V(JSCreateLiteralArray) \ V(JSCreateIterResultObject) \
V(JSCreateLiteralObject) \ V(JSCreateLiteralArray) \
V(JSCreateLiteralRegExp) \ V(JSCreateLiteralObject) \
V(JSLoadProperty) \ V(JSCreateLiteralRegExp) \
V(JSLoadNamed) \ V(JSLoadProperty) \
V(JSLoadGlobal) \ V(JSLoadNamed) \
V(JSStoreProperty) \ V(JSLoadGlobal) \
V(JSStoreNamed) \ V(JSStoreProperty) \
V(JSStoreGlobal) \ V(JSStoreNamed) \
V(JSDeleteProperty) \ V(JSStoreGlobal) \
V(JSHasProperty) \ V(JSDeleteProperty) \
V(JSHasProperty) \
V(JSInstanceOf) V(JSInstanceOf)
#define JS_CONTEXT_OP_LIST(V) \ #define JS_CONTEXT_OP_LIST(V) \
......
...@@ -1221,6 +1221,11 @@ Type* Typer::Visitor::TypeJSCreateClosure(Node* node) { ...@@ -1221,6 +1221,11 @@ Type* Typer::Visitor::TypeJSCreateClosure(Node* node) {
} }
Type* Typer::Visitor::TypeJSCreateIterResultObject(Node* node) {
return Type::OtherObject();
}
Type* Typer::Visitor::TypeJSCreateLiteralArray(Node* node) { Type* Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
return Type::OtherObject(); return Type::OtherObject();
} }
...@@ -1563,6 +1568,7 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) { ...@@ -1563,6 +1568,7 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
return Type::Number(); return Type::Number();
case Runtime::kInlineMathClz32: case Runtime::kInlineMathClz32:
return Type::Range(0, 32, zone()); return Type::Range(0, 32, zone());
case Runtime::kInlineCreateIterResultObject:
case Runtime::kInlineRegExpConstructResult: case Runtime::kInlineRegExpConstructResult:
return Type::OtherObject(); return Type::OtherObject();
case Runtime::kInlineSubString: case Runtime::kInlineSubString:
......
...@@ -518,6 +518,10 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -518,6 +518,10 @@ void Verifier::Visitor::Check(Node* node) {
// Type is Function. // Type is Function.
CheckUpperIs(node, Type::Function()); CheckUpperIs(node, Type::Function());
break; break;
case IrOpcode::kJSCreateIterResultObject:
// Type is OtherObject.
CheckUpperIs(node, Type::OtherObject());
break;
case IrOpcode::kJSCreateLiteralArray: case IrOpcode::kJSCreateLiteralArray:
case IrOpcode::kJSCreateLiteralObject: case IrOpcode::kJSCreateLiteralObject:
case IrOpcode::kJSCreateLiteralRegExp: case IrOpcode::kJSCreateLiteralRegExp:
......
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