BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
Node* literal_index = jsgraph()->Constant(expr->literal_index());
Node* constants = jsgraph()->Constant(expr->constant_properties());
- Node* flags = jsgraph()->Constant(expr->ComputeFlags(true));
const Operator* op =
- javascript()->CallRuntime(Runtime::kInlineCreateObjectLiteral, 4);
- Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
+ javascript()->CreateLiteralObject(expr->ComputeFlags(true));
+ Node* literal = NewNode(op, literals_array, literal_index, constants);
PrepareFrameState(literal, expr->CreateLiteralId(),
OutputFrameStateCombine::Push());
BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
Node* literal_index = jsgraph()->Constant(expr->literal_index());
Node* constants = jsgraph()->Constant(expr->constant_elements());
- Node* flags = jsgraph()->Constant(expr->ComputeFlags(true));
const Operator* op =
- javascript()->CallRuntime(Runtime::kInlineCreateArrayLiteral, 4);
- Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
+ javascript()->CreateLiteralArray(expr->ComputeFlags(true));
+ Node* literal = NewNode(op, literals_array, literal_index, constants);
PrepareFrameState(literal, expr->CreateLiteralId(),
OutputFrameStateCombine::Push());
}
+void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
+ int literal_flags = OpParameter<int>(node->op());
+ node->InsertInput(zone(), 3, jsgraph()->SmiConstant(literal_flags));
+ ReplaceWithRuntimeCall(node, Runtime::kCreateArrayLiteral);
+}
+
+
+void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
+ int literal_flags = OpParameter<int>(node->op());
+ node->InsertInput(zone(), 3, jsgraph()->SmiConstant(literal_flags));
+ ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral);
+}
+
+
void JSGenericLowering::LowerJSCreateCatchContext(Node* node) {
Unique<String> name = OpParameter<Unique<String>>(node);
node->InsertInput(zone(), 0, jsgraph()->HeapConstant(name));
#include <stack>
-#include "src/code-factory.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/js-graph.h"
-#include "src/compiler/linkage.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/operator-properties.h"
switch (f->function_id) {
case Runtime::kInlineConstructDouble:
return ReduceConstructDouble(node);
- case Runtime::kInlineCreateArrayLiteral:
- return ReduceCreateArrayLiteral(node);
- case Runtime::kInlineCreateObjectLiteral:
- return ReduceCreateObjectLiteral(node);
case Runtime::kInlineDeoptimizeNow:
return ReduceDeoptimizeNow(node);
case Runtime::kInlineDoubleHi:
}
-Reduction JSIntrinsicLowering::ReduceCreateArrayLiteral(Node* node) {
- HeapObjectMatcher<FixedArray> mconst(NodeProperties::GetValueInput(node, 2));
- NumberMatcher mflags(NodeProperties::GetValueInput(node, 3));
- int length = mconst.Value().handle()->length();
- int flags = FastD2I(mflags.Value());
-
- // Use the FastCloneShallowArrayStub only for shallow boilerplates up to the
- // initial length limit for arrays with "fast" elements kind.
- if ((flags & ArrayLiteral::kShallowElements) != 0 &&
- length < JSObject::kInitialMaxFastElementArray) {
- Isolate* isolate = jsgraph()->isolate();
- Callable callable = CodeFactory::FastCloneShallowArray(isolate);
- CallDescriptor* desc = Linkage::GetStubCallDescriptor(
- isolate, graph()->zone(), callable.descriptor(), 0,
- (OperatorProperties::GetFrameStateInputCount(node->op()) != 0)
- ? CallDescriptor::kNeedsFrameState
- : CallDescriptor::kNoFlags);
- const Operator* new_op = common()->Call(desc);
- Node* stub_code = jsgraph()->HeapConstant(callable.code());
- node->RemoveInput(3); // Remove flags input from node.
- node->InsertInput(graph()->zone(), 0, stub_code);
- node->set_op(new_op);
- return Changed(node);
- }
-
- return NoChange();
-}
-
-
-Reduction JSIntrinsicLowering::ReduceCreateObjectLiteral(Node* node) {
- HeapObjectMatcher<FixedArray> mconst(NodeProperties::GetValueInput(node, 2));
- NumberMatcher mflags(NodeProperties::GetValueInput(node, 3));
- // Constants are pairs, see ObjectLiteral::properties_count().
- int length = mconst.Value().handle()->length() / 2;
- int flags = FastD2I(mflags.Value());
-
- // Use the FastCloneShallowObjectStub only for shallow boilerplates without
- // elements up to the number of properties that the stubs can handle.
- if ((flags & ObjectLiteral::kShallowProperties) != 0 &&
- length <= FastCloneShallowObjectStub::kMaximumClonedProperties) {
- Isolate* isolate = jsgraph()->isolate();
- Callable callable = CodeFactory::FastCloneShallowObject(isolate, length);
- CallDescriptor* desc = Linkage::GetStubCallDescriptor(
- isolate, graph()->zone(), callable.descriptor(), 0,
- (OperatorProperties::GetFrameStateInputCount(node->op()) != 0)
- ? CallDescriptor::kNeedsFrameState
- : CallDescriptor::kNoFlags);
- const Operator* new_op = common()->Call(desc);
- Node* stub_code = jsgraph()->HeapConstant(callable.code());
- node->InsertInput(graph()->zone(), 0, stub_code);
- node->set_op(new_op);
- return Changed(node);
- }
-
- return NoChange();
-}
-
-
Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
// TODO(jarin): This should not depend on the global flag.
if (!FLAG_turbo_deoptimization) return NoChange();
private:
Reduction ReduceConstructDouble(Node* node);
- Reduction ReduceCreateArrayLiteral(Node* node);
- Reduction ReduceCreateObjectLiteral(Node* node);
Reduction ReduceDeoptimizeNow(Node* node);
Reduction ReduceDoubleHi(Node* node);
Reduction ReduceDoubleLo(Node* node);
}
+const Operator* JSOperatorBuilder::CreateLiteralArray(int literal_flags) {
+ return new (zone()) Operator1<int>( // --
+ IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties, // opcode
+ "JSCreateLiteralArray", // name
+ 3, 1, 1, 1, 1, 2, // counts
+ literal_flags); // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CreateLiteralObject(int literal_flags) {
+ return new (zone()) Operator1<int>( // --
+ IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties, // opcode
+ "JSCreateLiteralObject", // name
+ 3, 1, 1, 1, 1, 2, // counts
+ literal_flags); // parameter
+}
+
+
const Operator* JSOperatorBuilder::CreateCatchContext(
const Unique<String>& name) {
return new (zone()) Operator1<Unique<String>>( // --
const Operator* Create();
const Operator* CreateClosure(Handle<SharedFunctionInfo> shared_info,
PretenureFlag pretenure);
+ const Operator* CreateLiteralArray(int literal_flags);
+ const Operator* CreateLiteralObject(int literal_flags);
const Operator* CallFunction(size_t arity, CallFunctionFlags flags);
const Operator* CallRuntime(Runtime::FunctionId id, size_t arity);
}
+Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) {
+ DCHECK_EQ(IrOpcode::kJSCreateLiteralArray, node->opcode());
+ HeapObjectMatcher<FixedArray> mconst(NodeProperties::GetValueInput(node, 2));
+ int length = mconst.Value().handle()->length();
+ int flags = OpParameter<int>(node->op());
+
+ // Use the FastCloneShallowArrayStub only for shallow boilerplates up to the
+ // initial length limit for arrays with "fast" elements kind.
+ if ((flags & ArrayLiteral::kShallowElements) != 0 &&
+ length < JSObject::kInitialMaxFastElementArray) {
+ Isolate* isolate = jsgraph()->isolate();
+ Callable callable = CodeFactory::FastCloneShallowArray(isolate);
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+ isolate, graph()->zone(), callable.descriptor(), 0,
+ (OperatorProperties::GetFrameStateInputCount(node->op()) != 0)
+ ? CallDescriptor::kNeedsFrameState
+ : CallDescriptor::kNoFlags);
+ const Operator* new_op = common()->Call(desc);
+ Node* stub_code = jsgraph()->HeapConstant(callable.code());
+ node->InsertInput(graph()->zone(), 0, stub_code);
+ node->set_op(new_op);
+ return Changed(node);
+ }
+
+ return NoChange();
+}
+
+
+Reduction JSTypedLowering::ReduceJSCreateLiteralObject(Node* node) {
+ DCHECK_EQ(IrOpcode::kJSCreateLiteralObject, node->opcode());
+ HeapObjectMatcher<FixedArray> mconst(NodeProperties::GetValueInput(node, 2));
+ // Constants are pairs, see ObjectLiteral::properties_count().
+ int length = mconst.Value().handle()->length() / 2;
+ int flags = OpParameter<int>(node->op());
+
+ // Use the FastCloneShallowObjectStub only for shallow boilerplates without
+ // elements up to the number of properties that the stubs can handle.
+ if ((flags & ObjectLiteral::kShallowProperties) != 0 &&
+ length <= FastCloneShallowObjectStub::kMaximumClonedProperties) {
+ Isolate* isolate = jsgraph()->isolate();
+ Callable callable = CodeFactory::FastCloneShallowObject(isolate, length);
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+ isolate, graph()->zone(), callable.descriptor(), 0,
+ (OperatorProperties::GetFrameStateInputCount(node->op()) != 0)
+ ? CallDescriptor::kNeedsFrameState
+ : CallDescriptor::kNoFlags);
+ const Operator* new_op = common()->Call(desc);
+ Node* stub_code = jsgraph()->HeapConstant(callable.code());
+ node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(flags));
+ node->InsertInput(graph()->zone(), 0, stub_code);
+ node->set_op(new_op);
+ return Changed(node);
+ }
+
+ return NoChange();
+}
+
+
Reduction JSTypedLowering::Reduce(Node* node) {
// Check if the output type is a singleton. In that case we already know the
// result value and can simply replace the node if it's eliminable.
return ReduceJSStoreContext(node);
case IrOpcode::kJSCreateClosure:
return ReduceJSCreateClosure(node);
+ case IrOpcode::kJSCreateLiteralArray:
+ return ReduceJSCreateLiteralArray(node);
+ case IrOpcode::kJSCreateLiteralObject:
+ return ReduceJSCreateLiteralObject(node);
default:
break;
}
Reduction ReduceJSToStringInput(Node* input);
Reduction ReduceJSToString(Node* node);
Reduction ReduceJSCreateClosure(Node* node);
+ Reduction ReduceJSCreateLiteralArray(Node* node);
+ Reduction ReduceJSCreateLiteralObject(Node* node);
Reduction ReduceNumberBinop(Node* node, const Operator* numberOp);
Reduction ReduceInt32Binop(Node* node, const Operator* intOp);
Reduction ReduceUI32Shift(Node* node, Signedness left_signedness,
return false;
case Runtime::kInlineArguments:
case Runtime::kInlineCallFunction:
- case Runtime::kInlineCreateArrayLiteral:
- case Runtime::kInlineCreateObjectLiteral:
case Runtime::kInlineDateField:
case Runtime::kInlineDeoptimizeNow:
case Runtime::kInlineGetPrototype:
#define JS_OBJECT_OP_LIST(V) \
V(JSCreate) \
V(JSCreateClosure) \
+ V(JSCreateLiteralArray) \
+ V(JSCreateLiteralObject) \
V(JSLoadProperty) \
V(JSLoadNamed) \
V(JSStoreProperty) \
case IrOpcode::kJSLessThanOrEqual:
case IrOpcode::kJSNotEqual:
+ // Object operations
+ case IrOpcode::kJSCreateLiteralArray:
+ case IrOpcode::kJSCreateLiteralObject:
+
// Context operations
case IrOpcode::kJSCreateScriptContext:
case IrOpcode::kJSCreateWithContext:
}
+Bounds Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
+ return Bounds(Type::None(), Type::OtherObject());
+}
+
+
+Bounds Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
+ return Bounds(Type::None(), Type::OtherObject());
+}
+
+
Type* Typer::Visitor::JSLoadPropertyTyper(Type* object, Type* name, Typer* t) {
// TODO(rossberg): Use range types and sized array types to filter undefined.
if (object->IsArray() && name->Is(Type::Integral32())) {
// Type is Function.
CheckUpperIs(node, Type::OtherObject());
break;
+ case IrOpcode::kJSCreateLiteralArray:
+ case IrOpcode::kJSCreateLiteralObject:
+ // Type is OtherObject.
+ CheckUpperIs(node, Type::OtherObject());
+ break;
case IrOpcode::kJSLoadProperty:
case IrOpcode::kJSLoadNamed:
// Type can be anything.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "src/code-factory.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/diamond.h"
#include "src/compiler/js-graph.h"
// -----------------------------------------------------------------------------
-// %_CreateArrayLiteral
-
-
-TEST_F(JSIntrinsicLoweringTest, InlineCreateArrayLiteral) {
- Node* const input0 = Parameter(0);
- Node* const input1 = Parameter(1);
- Node* const input2 = HeapConstant(factory()->NewFixedArray(12));
- Node* const input3 = NumberConstant(ArrayLiteral::kShallowElements);
- Node* const context = Parameter(2);
- Node* const frame_state = EmptyFrameState();
- Node* const effect = graph()->start();
- Node* const control = graph()->start();
- Reduction const r = Reduce(graph()->NewNode(
- javascript()->CallRuntime(Runtime::kInlineCreateArrayLiteral, 4), input0,
- input1, input2, input3, context, frame_state, effect, control));
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(
- r.replacement(),
- IsCall(_, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
- CodeFactory::FastCloneShallowArray(isolate()).code())),
- input0, input1, input2, context, frame_state, effect, control));
-}
-
-
-// -----------------------------------------------------------------------------
-// %_CreateObjectLiteral
-
-
-TEST_F(JSIntrinsicLoweringTest, InlineCreateObjectLiteral) {
- Node* const input0 = Parameter(0);
- Node* const input1 = Parameter(1);
- Node* const input2 = HeapConstant(factory()->NewFixedArray(2 * 6));
- Node* const input3 = NumberConstant(ObjectLiteral::kShallowProperties);
- Node* const context = Parameter(2);
- Node* const frame_state = EmptyFrameState();
- Node* const effect = graph()->start();
- Node* const control = graph()->start();
- Reduction const r = Reduce(graph()->NewNode(
- javascript()->CallRuntime(Runtime::kInlineCreateObjectLiteral, 4), input0,
- input1, input2, input3, context, frame_state, effect, control));
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(
- r.replacement(),
- IsCall(_, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
- CodeFactory::FastCloneShallowObject(isolate(), 6).code())),
- input0, input1, input2, input3, context, frame_state, effect,
- control));
-}
-
-
-// -----------------------------------------------------------------------------
// %_DoubleLo
effect, control));
}
+
+// -----------------------------------------------------------------------------
+// JSCreateLiteralArray
+
+
+TEST_F(JSTypedLoweringTest, JSCreateLiteralArray) {
+ Node* const input0 = Parameter(0);
+ Node* const input1 = Parameter(1);
+ Node* const input2 = HeapConstant(factory()->NewFixedArray(12));
+ Node* const context = UndefinedConstant();
+ Node* const frame_state = EmptyFrameState();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Reduction const r = Reduce(graph()->NewNode(
+ javascript()->CreateLiteralArray(ArrayLiteral::kShallowElements), input0,
+ input1, input2, context, frame_state, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsCall(_, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
+ CodeFactory::FastCloneShallowArray(isolate()).code())),
+ input0, input1, input2, context, frame_state, effect, control));
+}
+
+
+// -----------------------------------------------------------------------------
+// JSCreateLiteralObject
+
+
+TEST_F(JSTypedLoweringTest, JSCreateLiteralObject) {
+ Node* const input0 = Parameter(0);
+ Node* const input1 = Parameter(1);
+ Node* const input2 = HeapConstant(factory()->NewFixedArray(2 * 6));
+ Node* const context = UndefinedConstant();
+ Node* const frame_state = EmptyFrameState();
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ Reduction const r = Reduce(graph()->NewNode(
+ javascript()->CreateLiteralObject(ObjectLiteral::kShallowProperties),
+ input0, input1, input2, context, frame_state, effect, control));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(
+ r.replacement(),
+ IsCall(_, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
+ CodeFactory::FastCloneShallowObject(isolate(), 6).code())),
+ input0, input1, input2, _, context, frame_state, effect, control));
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8