Commit 8673108d authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[turbofan] Enable optimizing the empty object literal again

Since we don't create an AllocationSite for the empty object literal, the
TF lowering bailed out early and used the slow runtime call as a fallback.

Bug: chromium:757596, v8:6211
Change-Id: I68307ff2d0870c35f07c3aad4cd10cf08e378686
Reviewed-on: https://chromium-review.googlesource.com/625619Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47514}
parent 4c54a218
......@@ -894,43 +894,6 @@ Reduction JSCreateLowering::ReduceJSCreateKeyValueArray(Node* node) {
return Changed(node);
}
Reduction JSCreateLowering::ReduceNewObject(Node* node,
Handle<AllocationSite> site) {
DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralObject, node->opcode());
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
// Extract tenuring feedback from the {site} and add appropriate code
// dependencies on the {site} if deoptimization is enabled.
PretenureFlag pretenure = site->GetPretenureMode();
dependencies()->AssumeTenuringDecision(site);
// Retrieve the initial map for the object.
Handle<Map> map = factory()->ObjectLiteralMapFromCache(native_context(), 0);
DCHECK(!map->is_dictionary_map());
DCHECK(!map->IsInobjectSlackTrackingInProgress());
Node* js_object_map = jsgraph()->HeapConstant(map);
// Setup elements and properties.
Node* elements = jsgraph()->EmptyFixedArrayConstant();
Node* properties = jsgraph()->EmptyFixedArrayConstant();
// Perform the allocation of the actual JSArray object.
AllocationBuilder a(jsgraph(), effect, control);
a.Allocate(map->instance_size(), pretenure);
a.Store(AccessBuilder::ForMap(), js_object_map);
a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
a.Store(AccessBuilder::ForJSObjectElements(), elements);
for (int i = 0; i < map->GetInObjectProperties(); i++) {
a.Store(AccessBuilder::ForJSObjectInObjectProperty(map, i),
jsgraph()->UndefinedConstant());
}
RelaxControls(node);
a.FinishAndChange(node);
return Changed(node);
}
Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
DCHECK(node->opcode() == IrOpcode::kJSCreateLiteralArray ||
node->opcode() == IrOpcode::kJSCreateLiteralObject);
......@@ -977,6 +940,52 @@ Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
return NoChange();
}
Reduction JSCreateLowering::ReduceNewObject(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralObject, node->opcode());
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
// Retrieve the initial map for the object.
Handle<Map> map = factory()->ObjectLiteralMapFromCache(native_context(), 0);
DCHECK(!map->is_dictionary_map());
DCHECK(!map->IsInobjectSlackTrackingInProgress());
Node* js_object_map = jsgraph()->HeapConstant(map);
// Setup elements and properties.
Node* elements = jsgraph()->EmptyFixedArrayConstant();
Node* properties = jsgraph()->EmptyFixedArrayConstant();
// Perform the allocation of the actual JSArray object.
AllocationBuilder a(jsgraph(), effect, control);
a.Allocate(map->instance_size());
a.Store(AccessBuilder::ForMap(), js_object_map);
a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
a.Store(AccessBuilder::ForJSObjectElements(), elements);
for (int i = 0; i < map->GetInObjectProperties(); i++) {
a.Store(AccessBuilder::ForJSObjectInObjectProperty(map, i),
jsgraph()->UndefinedConstant());
}
RelaxControls(node);
a.FinishAndChange(node);
return Changed(node);
}
Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kJSCreateEmptyLiteralObject);
int literal_index = OpParameter<int>(node);
Handle<FeedbackVector> feedback_vector;
if (GetSpecializationFeedbackVector(node).ToHandle(&feedback_vector)) {
FeedbackSlot slot(FeedbackVector::ToSlot(literal_index));
Handle<Object> raw_site(feedback_vector->Get(slot), isolate());
// TODO(cbruni): remove once the empty object literal doesn't rely on the
// AllocationSite anymore.
DCHECK(!raw_site->IsAllocationSite());
return ReduceNewObject(node);
}
return NoChange();
}
Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
DCHECK(node->opcode() == IrOpcode::kJSCreateLiteralRegExp);
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
......@@ -997,23 +1006,6 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
return NoChange();
}
Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kJSCreateEmptyLiteralObject);
int literal_index = OpParameter<int>(node);
Handle<FeedbackVector> feedback_vector;
if (GetSpecializationFeedbackVector(node).ToHandle(&feedback_vector)) {
FeedbackSlot slot(FeedbackVector::ToSlot(literal_index));
Handle<Object> raw_site(feedback_vector->Get(slot), isolate());
if (raw_site->IsAllocationSite()) {
Handle<AllocationSite> site = Handle<AllocationSite>::cast(raw_site);
// The empty object literal doesn't need a boilerplate.
DCHECK(!site->PointsToLiteral());
return ReduceNewObject(node, site);
}
}
return NoChange();
}
Reduction JSCreateLowering::ReduceJSCreateFunctionContext(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode());
const CreateFunctionContextParameters& parameters =
......
......@@ -67,7 +67,7 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
Handle<AllocationSite> site);
Reduction ReduceNewArray(Node* node, std::vector<Node*> values,
Handle<AllocationSite> site);
Reduction ReduceNewObject(Node* node, Handle<AllocationSite> site);
Reduction ReduceNewObject(Node* node);
Node* AllocateArguments(Node* effect, Node* control, Node* frame_state);
Node* AllocateRestArguments(Node* effect, Node* control, Node* frame_state,
......
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