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) {
}
// 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
FieldAccess AccessBuilder::ForJSRegExpFlags() {
FieldAccess access = {kTaggedBase, JSRegExp::kFlagsOffset,
......
......@@ -55,6 +55,12 @@ class AccessBuilder final : public AllStatic {
// Provides access to JSDate fields.
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.
static FieldAccess ForJSRegExpFlags();
......
......@@ -498,6 +498,11 @@ void JSGenericLowering::LowerJSCreateClosure(Node* node) {
}
void JSGenericLowering::LowerJSCreateIterResultObject(Node* node) {
ReplaceWithRuntimeCall(node, Runtime::kCreateIterResultObject);
}
void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
......
......@@ -37,6 +37,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
switch (f->function_id) {
case Runtime::kInlineConstructDouble:
return ReduceConstructDouble(node);
case Runtime::kInlineCreateIterResultObject:
return ReduceCreateIterResultObject(node);
case Runtime::kInlineDateField:
return ReduceDateField(node);
case Runtime::kInlineDeoptimizeNow:
......@@ -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) {
Node* high = NodeProperties::GetValueInput(node, 0);
Node* low = NodeProperties::GetValueInput(node, 1);
......
......@@ -39,6 +39,7 @@ class JSIntrinsicLowering final : public AdvancedReducer {
private:
Reduction ReduceConstructDouble(Node* node);
Reduction ReduceCreateIterResultObject(Node* node);
Reduction ReduceDateField(Node* node);
Reduction ReduceDeoptimizeNow(Node* node);
Reduction ReduceDoubleHi(Node* node);
......
......@@ -487,28 +487,29 @@ const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
}
#define CACHED_OP_LIST(V) \
V(Equal, Operator::kNoProperties, 2, 1) \
V(NotEqual, Operator::kNoProperties, 2, 1) \
V(StrictEqual, Operator::kNoThrow, 2, 1) \
V(StrictNotEqual, Operator::kNoThrow, 2, 1) \
V(ToNumber, Operator::kNoProperties, 1, 1) \
V(ToString, Operator::kNoProperties, 1, 1) \
V(ToName, Operator::kNoProperties, 1, 1) \
V(ToObject, Operator::kNoProperties, 1, 1) \
V(Yield, Operator::kNoProperties, 1, 1) \
V(Create, Operator::kEliminatable, 2, 1) \
V(HasProperty, Operator::kNoProperties, 2, 1) \
V(TypeOf, Operator::kEliminatable, 1, 1) \
V(InstanceOf, Operator::kNoProperties, 2, 1) \
V(ForInDone, Operator::kPure, 2, 1) \
V(ForInNext, Operator::kNoProperties, 4, 1) \
V(ForInPrepare, Operator::kNoProperties, 1, 3) \
V(ForInStep, Operator::kPure, 1, 1) \
V(LoadMessage, Operator::kNoThrow, 0, 1) \
V(StoreMessage, Operator::kNoThrow, 1, 0) \
V(StackCheck, Operator::kNoProperties, 0, 0) \
V(CreateWithContext, Operator::kNoProperties, 2, 1) \
#define CACHED_OP_LIST(V) \
V(Equal, Operator::kNoProperties, 2, 1) \
V(NotEqual, Operator::kNoProperties, 2, 1) \
V(StrictEqual, Operator::kNoThrow, 2, 1) \
V(StrictNotEqual, Operator::kNoThrow, 2, 1) \
V(ToNumber, Operator::kNoProperties, 1, 1) \
V(ToString, Operator::kNoProperties, 1, 1) \
V(ToName, Operator::kNoProperties, 1, 1) \
V(ToObject, Operator::kNoProperties, 1, 1) \
V(Yield, Operator::kNoProperties, 1, 1) \
V(Create, Operator::kEliminatable, 2, 1) \
V(CreateIterResultObject, Operator::kEliminatable, 2, 1) \
V(HasProperty, Operator::kNoProperties, 2, 1) \
V(TypeOf, Operator::kEliminatable, 1, 1) \
V(InstanceOf, Operator::kNoProperties, 2, 1) \
V(ForInDone, Operator::kPure, 2, 1) \
V(ForInNext, Operator::kNoProperties, 4, 1) \
V(ForInPrepare, Operator::kNoProperties, 1, 3) \
V(ForInStep, Operator::kPure, 1, 1) \
V(LoadMessage, Operator::kNoThrow, 0, 1) \
V(StoreMessage, Operator::kNoThrow, 1, 0) \
V(StackCheck, Operator::kNoProperties, 0, 0) \
V(CreateWithContext, Operator::kNoProperties, 2, 1) \
V(CreateModuleContext, Operator::kNoProperties, 2, 1)
......
......@@ -514,6 +514,7 @@ class JSOperatorBuilder final : public ZoneObject {
const Operator* CreateArray(size_t arity, Handle<AllocationSite> site);
const Operator* CreateClosure(Handle<SharedFunctionInfo> shared_info,
PretenureFlag pretenure);
const Operator* CreateIterResultObject();
const Operator* CreateLiteralArray(Handle<FixedArray> constant_elements,
int literal_flags, int literal_index);
const Operator* CreateLiteralObject(Handle<FixedArray> constant_properties,
......
......@@ -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) {
DCHECK_EQ(IrOpcode::kJSCreateLiteralArray, node->opcode());
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
......@@ -2515,6 +2546,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
return ReduceJSCreateArray(node);
case IrOpcode::kJSCreateClosure:
return ReduceJSCreateClosure(node);
case IrOpcode::kJSCreateIterResultObject:
return ReduceJSCreateIterResultObject(node);
case IrOpcode::kJSCreateLiteralArray:
return ReduceJSCreateLiteralArray(node);
case IrOpcode::kJSCreateLiteralObject:
......
......@@ -71,6 +71,7 @@ class JSTypedLowering final : public AdvancedReducer {
Reduction ReduceJSCreateArguments(Node* node);
Reduction ReduceJSCreateArray(Node* node);
Reduction ReduceJSCreateClosure(Node* node);
Reduction ReduceJSCreateIterResultObject(Node* node);
Reduction ReduceJSCreateLiteralArray(Node* node);
Reduction ReduceJSCreateLiteralObject(Node* node);
Reduction ReduceJSCreateFunctionContext(Node* node);
......
......@@ -154,6 +154,7 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
// are blacklisted here and can be called without a FrameState.
switch (function) {
case Runtime::kAllocateInTargetSpace:
case Runtime::kCreateIterResultObject:
case Runtime::kDateField:
case Runtime::kDefineClassMethod: // TODO(jarin): Is it safe?
case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe?
......
......@@ -105,22 +105,23 @@
JS_CONVERSION_UNOP_LIST(V) \
JS_OTHER_UNOP_LIST(V)
#define JS_OBJECT_OP_LIST(V) \
V(JSCreate) \
V(JSCreateArguments) \
V(JSCreateArray) \
V(JSCreateClosure) \
V(JSCreateLiteralArray) \
V(JSCreateLiteralObject) \
V(JSCreateLiteralRegExp) \
V(JSLoadProperty) \
V(JSLoadNamed) \
V(JSLoadGlobal) \
V(JSStoreProperty) \
V(JSStoreNamed) \
V(JSStoreGlobal) \
V(JSDeleteProperty) \
V(JSHasProperty) \
#define JS_OBJECT_OP_LIST(V) \
V(JSCreate) \
V(JSCreateArguments) \
V(JSCreateArray) \
V(JSCreateClosure) \
V(JSCreateIterResultObject) \
V(JSCreateLiteralArray) \
V(JSCreateLiteralObject) \
V(JSCreateLiteralRegExp) \
V(JSLoadProperty) \
V(JSLoadNamed) \
V(JSLoadGlobal) \
V(JSStoreProperty) \
V(JSStoreNamed) \
V(JSStoreGlobal) \
V(JSDeleteProperty) \
V(JSHasProperty) \
V(JSInstanceOf)
#define JS_CONTEXT_OP_LIST(V) \
......
......@@ -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) {
return Type::OtherObject();
}
......@@ -1563,6 +1568,7 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
return Type::Number();
case Runtime::kInlineMathClz32:
return Type::Range(0, 32, zone());
case Runtime::kInlineCreateIterResultObject:
case Runtime::kInlineRegExpConstructResult:
return Type::OtherObject();
case Runtime::kInlineSubString:
......
......@@ -518,6 +518,10 @@ void Verifier::Visitor::Check(Node* node) {
// Type is Function.
CheckUpperIs(node, Type::Function());
break;
case IrOpcode::kJSCreateIterResultObject:
// Type is OtherObject.
CheckUpperIs(node, Type::OtherObject());
break;
case IrOpcode::kJSCreateLiteralArray:
case IrOpcode::kJSCreateLiteralObject:
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