[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}
This commit is contained in:
parent
26abfc5099
commit
f7934b6427
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user