[turbofan] Add deopt point for InternalSetPrototype in VisitObjectLiteral.

BUG=572409
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#33078}
This commit is contained in:
jarin 2016-01-04 01:54:07 -08:00 committed by Commit bot
parent 2d997d8659
commit 140f69d784
11 changed files with 63 additions and 13 deletions

View File

@ -1533,11 +1533,18 @@ class ObjectLiteral final : public MaterializedLiteral {
BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
// Return an AST id for a property that is used in simulate instructions.
BailoutId GetIdForProperty(int i) { return BailoutId(local_id(i + 1)); }
BailoutId GetIdForPropertyName(int i) {
return BailoutId(local_id(2 * i + 1));
}
BailoutId GetIdForPropertySet(int i) {
return BailoutId(local_id(2 * i + 2));
}
// Unlike other AST nodes, this number of bailout IDs allocated for an
// ObjectLiteral can vary, so num_ids() is not a static method.
int num_ids() const { return parent_num_ids() + 1 + properties()->length(); }
int num_ids() const {
return parent_num_ids() + 1 + 2 * properties()->length();
}
// Object literals need one feedback slot for each non-trivial value, as well
// as some slots for home objects.

View File

@ -1793,7 +1793,8 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
Node* set_prototype = NewNode(op, receiver, value);
// SetPrototype should not lazy deopt on an object literal.
PrepareFrameState(set_prototype, BailoutId::None());
PrepareFrameState(set_prototype,
expr->GetIdForPropertySet(property_index));
break;
}
case ObjectLiteral::Property::GETTER:
@ -1848,14 +1849,14 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
const Operator* op =
javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
Node* call = NewNode(op, receiver, value);
PrepareFrameState(call, BailoutId::None());
PrepareFrameState(call, expr->GetIdForPropertySet(property_index));
continue;
}
environment()->Push(environment()->Top()); // Duplicate receiver.
VisitForValue(property->key());
Node* name = BuildToName(environment()->Pop(),
expr->GetIdForProperty(property_index));
expr->GetIdForPropertyName(property_index));
environment()->Push(name);
VisitForValue(property->value());
Node* value = environment()->Pop();

View File

@ -1571,6 +1571,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
break;
case ObjectLiteral::Property::GETTER:
@ -1627,8 +1629,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
} else {
EmitPropertyKey(property, expr->GetIdForProperty(property_index));
EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());

View File

@ -1559,6 +1559,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
__ Push(x0);
VisitForStackValue(value);
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
@ -1614,8 +1616,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
} else {
EmitPropertyKey(property, expr->GetIdForProperty(property_index));
EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());

View File

@ -1489,6 +1489,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
@ -1543,8 +1545,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
} else {
EmitPropertyKey(property, expr->GetIdForProperty(property_index));
EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());

View File

@ -1565,6 +1565,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
@ -1620,8 +1622,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
} else {
EmitPropertyKey(property, expr->GetIdForProperty(property_index));
EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());

View File

@ -1565,6 +1565,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
@ -1620,8 +1622,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
} else {
EmitPropertyKey(property, expr->GetIdForProperty(property_index));
EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());

View File

@ -1529,6 +1529,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
@ -1583,8 +1585,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
} else {
EmitPropertyKey(property, expr->GetIdForProperty(property_index));
EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());

View File

@ -1517,6 +1517,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
@ -1569,8 +1571,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
} else {
EmitPropertyKey(property, expr->GetIdForProperty(property_index));
EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());

View File

@ -1481,6 +1481,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
break;
case ObjectLiteral::Property::GETTER:
if (property->emit_store()) {
@ -1535,8 +1537,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(value);
DCHECK(property->emit_store());
__ CallRuntime(Runtime::kInternalSetPrototype);
PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
NO_REGISTERS);
} else {
EmitPropertyKey(property, expr->GetIdForProperty(property_index));
EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());

View File

@ -0,0 +1,10 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var o = function() {};
function f() {
var lit = { __proto__: o };
o instanceof RegExp;
}
f();