Reviewers: arv,
Description:
[turbofan] Fix known issue about computed property names.
This fixes a corner-case where deoptimization while evaluating the
value to a __proto__ property after computed property names appeared
in an object literal, lead to environments not being in sync with
unoptimized code.
[email protected]
TEST=mjsunit/harmony/computed-property-names-deopt
Please review this at https://codereview.chromium.org/1158443004/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+44, -9 lines):
M src/compiler/ast-graph-builder.cc
A test/mjsunit/harmony/computed-property-names-deopt.js
Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc
b/src/compiler/ast-graph-builder.cc
index
0d01a5a08b9b37fa495684003baec4d061e96bfc..561cd50395740d974d5e19b1af69c1847ecd0dd6
100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -1888,14 +1888,23 @@ void
AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
for (; property_index < expr->properties()->length(); property_index++) {
ObjectLiteral::Property* property =
expr->properties()->at(property_index);
+ if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
+ environment()->Push(literal); // Duplicate receiver.
+ VisitForValue(property->value());
+ Node* value = environment()->Pop();
+ Node* receiver = environment()->Pop();
+ const Operator* op =
+ javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
+ Node* call = NewNode(op, receiver, value);
+ PrepareFrameState(call, BailoutId::None());
+ continue;
+ }
+
environment()->Push(literal); // Duplicate receiver.
VisitForValue(property->key());
Node* name = BuildToName(environment()->Pop(),
expr->GetIdForProperty(property_index));
environment()->Push(name);
- // TODO(mstarzinger): For ObjectLiteral::Property::PROTOTYPE the key
should
- // not be on the operand stack while the value is being evaluated.
Come up
- // with a repro for this and fix it. Also find a nice way to do so. :)
VisitForValue(property->value());
Node* value = environment()->Pop();
Node* key = environment()->Pop();
@@ -1913,13 +1922,9 @@ void
AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
PrepareFrameState(call, BailoutId::None());
break;
}
- case ObjectLiteral::Property::PROTOTYPE: {
- const Operator* op =
- javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
- Node* call = NewNode(op, receiver, value);
- PrepareFrameState(call, BailoutId::None());
+ case ObjectLiteral::Property::PROTOTYPE:
+ UNREACHABLE(); // Handled specially above.
break;
- }
case ObjectLiteral::Property::GETTER: {
Node* attr = jsgraph()->Constant(NONE);
const Operator* op = javascript()->CallRuntime(
Index: test/mjsunit/harmony/computed-property-names-deopt.js
diff --git a/test/mjsunit/harmony/computed-property-names-deopt.js
b/test/mjsunit/harmony/computed-property-names-deopt.js
new file mode 100644
index
0000000000000000000000000000000000000000..1f0b0585fc36250912ee9df28da3aa28452daca6
--- /dev/null
+++ b/test/mjsunit/harmony/computed-property-names-deopt.js
@@ -0,0 +1,30 @@
+// Copyright 2014 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.
+
+// Flags: --harmony-computed-property-names --allow-natives-syntax
+
+
+(function TestProtoDeopt() {
+ var proto = {};
+
+ function deoptMe() {
+ %DeoptimizeFunction(f);
+ return proto;
+ }
+
+ function checkObject(name, value, o) {
+ assertSame(proto, Object.getPrototypeOf(o));
+ assertTrue(o.hasOwnProperty(name));
+ assertEquals(value, o[name]);
+ }
+
+ function f(name, value) {
+ return { [name]: value, __proto__: deoptMe() };
+ }
+
+ checkObject("a", 1, f("a", 1));
+ checkObject("b", 2, f("b", 2));
+ %OptimizeFunctionOnNextCall(f);
+ checkObject("c", 3, f("c", 3));
+})();
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.