[turbofan] Introduce proper CreateLiteralParameters.
Put the constant parts of the CreateLiteralArray and CreateLiteralObject operators into CreateLiteralParameters and properly use them everywhere. R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/1475613002 Cr-Commit-Position: refs/heads/master@{#32207}
This commit is contained in:
parent
085fed0fb5
commit
68ce906134
@ -1715,11 +1715,10 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
// Create node to deep-copy the literal boilerplate.
|
||||
Node* literals_array =
|
||||
BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
|
||||
Node* literal_index = jsgraph()->Constant(expr->literal_index());
|
||||
Node* constants = jsgraph()->Constant(expr->constant_properties());
|
||||
const Operator* op =
|
||||
javascript()->CreateLiteralObject(expr->ComputeFlags(true));
|
||||
Node* literal = NewNode(op, literals_array, literal_index, constants);
|
||||
const Operator* op = javascript()->CreateLiteralObject(
|
||||
expr->constant_properties(), expr->ComputeFlags(true),
|
||||
expr->literal_index());
|
||||
Node* literal = NewNode(op, literals_array);
|
||||
PrepareFrameState(literal, expr->CreateLiteralId(),
|
||||
OutputFrameStateCombine::Push());
|
||||
|
||||
@ -1921,11 +1920,10 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
// Create node to deep-copy the literal boilerplate.
|
||||
Node* literals_array =
|
||||
BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
|
||||
Node* literal_index = jsgraph()->Constant(expr->literal_index());
|
||||
Node* constants = jsgraph()->Constant(expr->constant_elements());
|
||||
const Operator* op =
|
||||
javascript()->CreateLiteralArray(expr->ComputeFlags(true));
|
||||
Node* literal = NewNode(op, literals_array, literal_index, constants);
|
||||
const Operator* op = javascript()->CreateLiteralArray(
|
||||
expr->constant_elements(), expr->ComputeFlags(true),
|
||||
expr->literal_index());
|
||||
Node* literal = NewNode(op, literals_array);
|
||||
PrepareFrameState(literal, expr->CreateLiteralId(),
|
||||
OutputFrameStateCombine::Push());
|
||||
|
||||
|
@ -504,15 +504,19 @@ void JSGenericLowering::LowerJSCreateClosure(Node* node) {
|
||||
|
||||
|
||||
void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
|
||||
int literal_flags = OpParameter<int>(node->op());
|
||||
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(literal_flags));
|
||||
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
|
||||
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
|
||||
node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constants()));
|
||||
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.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));
|
||||
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
|
||||
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
|
||||
node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constants()));
|
||||
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
|
||||
ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral);
|
||||
}
|
||||
|
||||
|
@ -410,6 +410,36 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
|
||||
}
|
||||
|
||||
|
||||
bool operator==(CreateLiteralParameters const& lhs,
|
||||
CreateLiteralParameters const& rhs) {
|
||||
return lhs.constants().location() == rhs.constants().location() &&
|
||||
lhs.flags() == rhs.flags() && lhs.index() == rhs.index();
|
||||
}
|
||||
|
||||
|
||||
bool operator!=(CreateLiteralParameters const& lhs,
|
||||
CreateLiteralParameters const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
|
||||
size_t hash_value(CreateLiteralParameters const& p) {
|
||||
return base::hash_combine(p.constants().location(), p.flags(), p.index());
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) {
|
||||
return os << Brief(*p.constants()) << ", " << p.flags() << ", " << p.index();
|
||||
}
|
||||
|
||||
|
||||
const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
|
||||
DCHECK(op->opcode() == IrOpcode::kJSCreateLiteralArray ||
|
||||
op->opcode() == IrOpcode::kJSCreateLiteralObject);
|
||||
return OpParameter<CreateLiteralParameters>(op);
|
||||
}
|
||||
|
||||
|
||||
#define CACHED_OP_LIST(V) \
|
||||
V(Equal, Operator::kNoProperties, 2, 1) \
|
||||
V(NotEqual, Operator::kNoProperties, 2, 1) \
|
||||
@ -723,21 +753,29 @@ const Operator* JSOperatorBuilder::CreateClosure(
|
||||
}
|
||||
|
||||
|
||||
const Operator* JSOperatorBuilder::CreateLiteralArray(int literal_flags) {
|
||||
return new (zone()) Operator1<int>( // --
|
||||
const Operator* JSOperatorBuilder::CreateLiteralArray(
|
||||
Handle<FixedArray> constant_elements, int literal_flags,
|
||||
int literal_index) {
|
||||
CreateLiteralParameters parameters(constant_elements, literal_flags,
|
||||
literal_index);
|
||||
return new (zone()) Operator1<CreateLiteralParameters>( // --
|
||||
IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties, // opcode
|
||||
"JSCreateLiteralArray", // name
|
||||
3, 1, 1, 1, 1, 2, // counts
|
||||
literal_flags); // parameter
|
||||
1, 1, 1, 1, 1, 2, // counts
|
||||
parameters); // parameter
|
||||
}
|
||||
|
||||
|
||||
const Operator* JSOperatorBuilder::CreateLiteralObject(int literal_flags) {
|
||||
return new (zone()) Operator1<int>( // --
|
||||
const Operator* JSOperatorBuilder::CreateLiteralObject(
|
||||
Handle<FixedArray> constant_properties, int literal_flags,
|
||||
int literal_index) {
|
||||
CreateLiteralParameters parameters(constant_properties, literal_flags,
|
||||
literal_index);
|
||||
return new (zone()) Operator1<CreateLiteralParameters>( // --
|
||||
IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties, // opcode
|
||||
"JSCreateLiteralObject", // name
|
||||
3, 1, 1, 1, 1, 2, // counts
|
||||
literal_flags); // parameter
|
||||
1, 1, 1, 1, 1, 2, // counts
|
||||
parameters); // parameter
|
||||
}
|
||||
|
||||
|
||||
|
@ -403,6 +403,34 @@ std::ostream& operator<<(std::ostream&, CreateClosureParameters const&);
|
||||
const CreateClosureParameters& CreateClosureParametersOf(const Operator* op);
|
||||
|
||||
|
||||
// Defines shared information for the literal that should be created. This is
|
||||
// used as parameter by JSCreateLiteralArray and JSCreateLiteralObject
|
||||
// operators.
|
||||
class CreateLiteralParameters final {
|
||||
public:
|
||||
CreateLiteralParameters(Handle<FixedArray> constants, int flags, int index)
|
||||
: constants_(constants), flags_(flags), index_(index) {}
|
||||
|
||||
Handle<FixedArray> constants() const { return constants_; }
|
||||
int flags() const { return flags_; }
|
||||
int index() const { return index_; }
|
||||
|
||||
private:
|
||||
Handle<FixedArray> const constants_;
|
||||
int const flags_;
|
||||
int const index_;
|
||||
};
|
||||
|
||||
bool operator==(CreateLiteralParameters const&, CreateLiteralParameters const&);
|
||||
bool operator!=(CreateLiteralParameters const&, CreateLiteralParameters const&);
|
||||
|
||||
size_t hash_value(CreateLiteralParameters const&);
|
||||
|
||||
std::ostream& operator<<(std::ostream&, CreateLiteralParameters const&);
|
||||
|
||||
const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op);
|
||||
|
||||
|
||||
// Interface for building JavaScript-level operators, e.g. directly from the
|
||||
// AST. Most operators have no parameters, thus can be globally shared for all
|
||||
// graphs.
|
||||
@ -444,8 +472,10 @@ 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* CreateLiteralArray(int literal_flags);
|
||||
const Operator* CreateLiteralObject(int literal_flags);
|
||||
const Operator* CreateLiteralArray(Handle<FixedArray> constant_elements,
|
||||
int literal_flags, int literal_index);
|
||||
const Operator* CreateLiteralObject(Handle<FixedArray> constant_properties,
|
||||
int literal_flags, int literal_index);
|
||||
|
||||
const Operator* CallFunction(
|
||||
size_t arity, LanguageMode language_mode,
|
||||
|
@ -1765,9 +1765,9 @@ Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) {
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) {
|
||||
DCHECK_EQ(IrOpcode::kJSCreateLiteralArray, node->opcode());
|
||||
HeapObjectMatcher mconst(NodeProperties::GetValueInput(node, 2));
|
||||
int length = Handle<FixedArray>::cast(mconst.Value())->length();
|
||||
int flags = OpParameter<int>(node->op());
|
||||
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
|
||||
int const length = p.constants()->length();
|
||||
int const flags = p.flags();
|
||||
|
||||
// Use the FastCloneShallowArrayStub only for shallow boilerplates up to the
|
||||
// initial length limit for arrays with "fast" elements kind.
|
||||
@ -1784,7 +1784,11 @@ Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) {
|
||||
: CallDescriptor::kNoFlags);
|
||||
const Operator* new_op = common()->Call(desc);
|
||||
Node* stub_code = jsgraph()->HeapConstant(callable.code());
|
||||
Node* literal_index = jsgraph()->SmiConstant(p.index());
|
||||
Node* constant_elements = jsgraph()->HeapConstant(p.constants());
|
||||
node->InsertInput(graph()->zone(), 0, stub_code);
|
||||
node->InsertInput(graph()->zone(), 2, literal_index);
|
||||
node->InsertInput(graph()->zone(), 3, constant_elements);
|
||||
NodeProperties::ChangeOp(node, new_op);
|
||||
return Changed(node);
|
||||
}
|
||||
@ -1795,10 +1799,10 @@ Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) {
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSCreateLiteralObject(Node* node) {
|
||||
DCHECK_EQ(IrOpcode::kJSCreateLiteralObject, node->opcode());
|
||||
HeapObjectMatcher mconst(NodeProperties::GetValueInput(node, 2));
|
||||
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
|
||||
// Constants are pairs, see ObjectLiteral::properties_count().
|
||||
int length = Handle<FixedArray>::cast(mconst.Value())->length() / 2;
|
||||
int flags = OpParameter<int>(node->op());
|
||||
int const length = p.constants()->length() / 2;
|
||||
int const flags = p.flags();
|
||||
|
||||
// Use the FastCloneShallowObjectStub only for shallow boilerplates without
|
||||
// elements up to the number of properties that the stubs can handle.
|
||||
@ -1813,8 +1817,13 @@ Reduction JSTypedLowering::ReduceJSCreateLiteralObject(Node* node) {
|
||||
: 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* literal_index = jsgraph()->SmiConstant(p.index());
|
||||
Node* literal_flags = jsgraph()->SmiConstant(flags);
|
||||
Node* constant_elements = jsgraph()->HeapConstant(p.constants());
|
||||
node->InsertInput(graph()->zone(), 0, stub_code);
|
||||
node->InsertInput(graph()->zone(), 2, literal_index);
|
||||
node->InsertInput(graph()->zone(), 3, constant_elements);
|
||||
node->InsertInput(graph()->zone(), 4, literal_flags);
|
||||
NodeProperties::ChangeOp(node, new_op);
|
||||
return Changed(node);
|
||||
}
|
||||
|
@ -1091,22 +1091,26 @@ TEST_F(JSTypedLoweringTest, JSCreateClosure) {
|
||||
|
||||
|
||||
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();
|
||||
Handle<FixedArray> const constant_elements = factory()->NewFixedArray(12);
|
||||
int const literal_flags = ArrayLiteral::kShallowElements;
|
||||
int const literal_index = 1;
|
||||
Node* const input = Parameter(0);
|
||||
Node* const context = Parameter(1);
|
||||
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));
|
||||
Reduction const r = Reduce(
|
||||
graph()->NewNode(javascript()->CreateLiteralArray(
|
||||
constant_elements, literal_flags, literal_index),
|
||||
input, context, frame_state, effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(
|
||||
r.replacement(),
|
||||
IsCall(_, IsHeapConstant(
|
||||
CodeFactory::FastCloneShallowArray(isolate()).code()),
|
||||
input0, input1, input2, context, frame_state, effect, control));
|
||||
input, IsNumberConstant(literal_index),
|
||||
IsHeapConstant(constant_elements), context, frame_state, effect,
|
||||
control));
|
||||
}
|
||||
|
||||
|
||||
@ -1115,22 +1119,27 @@ TEST_F(JSTypedLoweringTest, JSCreateLiteralArray) {
|
||||
|
||||
|
||||
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();
|
||||
Handle<FixedArray> const constant_properties =
|
||||
factory()->NewFixedArray(6 * 2);
|
||||
int const literal_flags = ObjectLiteral::kShallowProperties;
|
||||
int const literal_index = 1;
|
||||
Node* const input = Parameter(0);
|
||||
Node* const context = Parameter(1);
|
||||
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));
|
||||
Reduction const r = Reduce(
|
||||
graph()->NewNode(javascript()->CreateLiteralObject(
|
||||
constant_properties, literal_flags, literal_index),
|
||||
input, context, frame_state, effect, control));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(
|
||||
r.replacement(),
|
||||
IsCall(_, IsHeapConstant(
|
||||
CodeFactory::FastCloneShallowObject(isolate(), 6).code()),
|
||||
input0, input1, input2, _, context, frame_state, effect, control));
|
||||
input, IsNumberConstant(literal_index),
|
||||
IsHeapConstant(constant_properties), _, context, frame_state,
|
||||
effect, control));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user