Commit f7934b64 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[turbofan] Thread through object boilerplate length.

This adds the number of properties to be expected within the boilerplate
object for object literals to the TurboFan IR. The reason is that this
length can no longer be easily inferred from just the constants array.
The length is potentially non-zero for empty object literals and might
also diverge in the presence of constant functions or duplicate property
names.

For future safety and for symmetry reasons, the same change was applied
to array literals as well, even though inferring the length from the
constant elements is still possible there.

R=verwaest@chromium.org
BUG=chromium:593008
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#34594}
parent 26abfc50
......@@ -1725,7 +1725,7 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
// Create node to deep-copy the literal boilerplate.
const Operator* op = javascript()->CreateLiteralObject(
expr->constant_properties(), expr->ComputeFlags(true),
expr->literal_index());
expr->literal_index(), expr->properties_count());
Node* literal = NewNode(op, closure);
PrepareFrameState(literal, expr->CreateLiteralId(),
OutputFrameStateCombine::Push());
......@@ -1928,7 +1928,7 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
// Create node to deep-copy the literal boilerplate.
const Operator* op = javascript()->CreateLiteralArray(
expr->constant_elements(), expr->ComputeFlags(true),
expr->literal_index());
expr->literal_index(), expr->values()->length());
Node* literal = NewNode(op, closure);
PrepareFrameState(literal, expr->CreateLiteralId(),
OutputFrameStateCombine::Push());
......
......@@ -944,8 +944,9 @@ void BytecodeGraphBuilder::BuildCreateArrayLiteral() {
bytecode_iterator().GetConstantForIndexOperand(0));
int literal_index = bytecode_iterator().GetIndexOperand(1);
int literal_flags = bytecode_iterator().GetImmediateOperand(2);
int number_of_elements = constant_elements->length();
const Operator* op = javascript()->CreateLiteralArray(
constant_elements, literal_flags, literal_index);
constant_elements, literal_flags, literal_index, number_of_elements);
BuildCreateLiteral(op);
}
......@@ -962,8 +963,10 @@ void BytecodeGraphBuilder::BuildCreateObjectLiteral() {
bytecode_iterator().GetConstantForIndexOperand(0));
int literal_index = bytecode_iterator().GetIndexOperand(1);
int literal_flags = bytecode_iterator().GetImmediateOperand(2);
// TODO(mstarzinger): Thread through number of properties.
int number_of_properties = constant_properties->length() / 2;
const Operator* op = javascript()->CreateLiteralObject(
constant_properties, literal_flags, literal_index);
constant_properties, literal_flags, literal_index, number_of_properties);
BuildCreateLiteral(op);
}
......
......@@ -555,14 +555,13 @@ void JSGenericLowering::LowerJSCreateIterResultObject(Node* node) {
void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
int const length = Handle<FixedArray>::cast(p.constant())->length();
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
// Use the FastCloneShallowArrayStub only for shallow boilerplates up to the
// initial length limit for arrays with "fast" elements kind.
if ((p.flags() & ArrayLiteral::kShallowElements) != 0 &&
length < JSArray::kInitialMaxFastElementArray) {
p.length() < JSArray::kInitialMaxFastElementArray) {
Callable callable = CodeFactory::FastCloneShallowArray(isolate());
ReplaceWithStubCall(node, callable, flags);
} else {
......@@ -575,8 +574,6 @@ void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
// Constants are pairs, see ObjectLiteral::properties_count().
int const length = Handle<FixedArray>::cast(p.constant())->length() / 2;
node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
......@@ -584,8 +581,9 @@ void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
// Use the FastCloneShallowObjectStub only for shallow boilerplates without
// elements up to the number of properties that the stubs can handle.
if ((p.flags() & ObjectLiteral::kShallowProperties) != 0 &&
length <= FastCloneShallowObjectStub::kMaximumClonedProperties) {
Callable callable = CodeFactory::FastCloneShallowObject(isolate(), length);
p.length() <= FastCloneShallowObjectStub::kMaximumClonedProperties) {
Callable callable =
CodeFactory::FastCloneShallowObject(isolate(), p.length());
ReplaceWithStubCall(node, callable, flags);
} else {
ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral);
......
......@@ -346,7 +346,8 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
bool operator==(CreateLiteralParameters const& lhs,
CreateLiteralParameters const& rhs) {
return lhs.constant().location() == rhs.constant().location() &&
lhs.flags() == rhs.flags() && lhs.index() == rhs.index();
lhs.length() == rhs.length() && lhs.flags() == rhs.flags() &&
lhs.index() == rhs.index();
}
......@@ -357,12 +358,14 @@ bool operator!=(CreateLiteralParameters const& lhs,
size_t hash_value(CreateLiteralParameters const& p) {
return base::hash_combine(p.constant().location(), p.flags(), p.index());
return base::hash_combine(p.constant().location(), p.length(), p.flags(),
p.index());
}
std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) {
return os << Brief(*p.constant()) << ", " << p.flags() << ", " << p.index();
return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags()
<< ", " << p.index();
}
......@@ -733,12 +736,11 @@ const Operator* JSOperatorBuilder::CreateClosure(
parameters); // parameter
}
const Operator* JSOperatorBuilder::CreateLiteralArray(
Handle<FixedArray> constant_elements, int literal_flags,
int literal_index) {
CreateLiteralParameters parameters(constant_elements, literal_flags,
literal_index);
Handle<FixedArray> constant_elements, int literal_flags, int literal_index,
int number_of_elements) {
CreateLiteralParameters parameters(constant_elements, number_of_elements,
literal_flags, literal_index);
return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties, // opcode
"JSCreateLiteralArray", // name
......@@ -746,12 +748,11 @@ const Operator* JSOperatorBuilder::CreateLiteralArray(
parameters); // parameter
}
const Operator* JSOperatorBuilder::CreateLiteralObject(
Handle<FixedArray> constant_properties, int literal_flags,
int literal_index) {
CreateLiteralParameters parameters(constant_properties, literal_flags,
literal_index);
int literal_index, int number_of_properties) {
CreateLiteralParameters parameters(constant_properties, number_of_properties,
literal_flags, literal_index);
return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties, // opcode
"JSCreateLiteralObject", // name
......@@ -762,7 +763,7 @@ const Operator* JSOperatorBuilder::CreateLiteralObject(
const Operator* JSOperatorBuilder::CreateLiteralRegExp(
Handle<String> constant_pattern, int literal_flags, int literal_index) {
CreateLiteralParameters parameters(constant_pattern, literal_flags,
CreateLiteralParameters parameters(constant_pattern, -1, literal_flags,
literal_index);
return new (zone()) Operator1<CreateLiteralParameters>( // --
IrOpcode::kJSCreateLiteralRegExp, Operator::kNoProperties, // opcode
......
......@@ -350,15 +350,18 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op);
// JSCreateLiteralRegExp operators.
class CreateLiteralParameters final {
public:
CreateLiteralParameters(Handle<HeapObject> constant, int flags, int index)
: constant_(constant), flags_(flags), index_(index) {}
CreateLiteralParameters(Handle<HeapObject> constant, int length, int flags,
int index)
: constant_(constant), length_(length), flags_(flags), index_(index) {}
Handle<HeapObject> constant() const { return constant_; }
int length() const { return length_; }
int flags() const { return flags_; }
int index() const { return index_; }
private:
Handle<HeapObject> const constant_;
int const length_;
int const flags_;
int const index_;
};
......@@ -414,9 +417,11 @@ class JSOperatorBuilder final : public ZoneObject {
PretenureFlag pretenure);
const Operator* CreateIterResultObject();
const Operator* CreateLiteralArray(Handle<FixedArray> constant_elements,
int literal_flags, int literal_index);
int literal_flags, int literal_index,
int number_of_elements);
const Operator* CreateLiteralObject(Handle<FixedArray> constant_properties,
int literal_flags, int literal_index);
int literal_flags, int literal_index,
int number_of_properties);
const Operator* CreateLiteralRegExp(Handle<String> constant_pattern,
int literal_flags, int literal_index);
......
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