[turbofan] Fix frame state for class literal definition.
authormstarzinger <mstarzinger@chromium.org>
Fri, 24 Apr 2015 11:13:13 +0000 (04:13 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 24 Apr 2015 11:12:57 +0000 (11:12 +0000)
This introduces a bailout point for class literals right after the
%DefineClass function has been called. Otherwise the FrameState after
class literal evaluation might contain the literal itself.

R=jarin@chromium.org
TEST=mjsunit/regress/regress-crbug-480819
BUG=chromium:480819
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#28043}

src/ast.h
src/compiler/ast-graph-builder.cc
src/full-codegen.cc
test/mjsunit/regress/regress-crbug-480819.js [new file with mode: 0644]

index 5a89cda..330aa9e 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -2696,13 +2696,14 @@ class ClassLiteral final : public Expression {
   BailoutId EntryId() const { return BailoutId(local_id(0)); }
   BailoutId DeclsId() const { return BailoutId(local_id(1)); }
   BailoutId ExitId() { return BailoutId(local_id(2)); }
+  BailoutId CreateLiteralId() const { return BailoutId(local_id(3)); }
 
   // Return an AST id for a property that is used in simulate instructions.
-  BailoutId GetIdForProperty(int i) { return BailoutId(local_id(i + 3)); }
+  BailoutId GetIdForProperty(int i) { return BailoutId(local_id(i + 4)); }
 
   // Unlike other AST nodes, this number of bailout IDs allocated for an
   // ClassLiteral can vary, so num_ids() is not a static method.
-  int num_ids() const { return parent_num_ids() + 3 + properties()->length(); }
+  int num_ids() const { return parent_num_ids() + 4 + properties()->length(); }
 
  protected:
   ClassLiteral(Zone* zone, const AstRawString* name, Scope* scope,
index d299aec..9dd11b8 100644 (file)
@@ -1518,6 +1518,8 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
   Node* end = jsgraph()->Constant(expr->end_position());
   const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass, 6);
   Node* literal = NewNode(opc, name, extends, constructor, script, start, end);
+  PrepareFrameState(literal, expr->CreateLiteralId(),
+                    OutputFrameStateCombine::Push());
 
   // The prototype is ensured to exist by Runtime_DefineClass. No access check
   // is needed here since the constructor is created by the class literal.
@@ -1594,7 +1596,6 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
     BuildVariableAssignment(var, literal, Token::INIT_CONST, BailoutId::None());
   }
 
-  PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(literal);
 }
 
index 08fe7a7..3386ce1 100644 (file)
@@ -1591,6 +1591,7 @@ void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
     __ Push(Smi::FromInt(lit->end_position()));
 
     __ CallRuntime(Runtime::kDefineClass, 6);
+    PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG);
     EmitClassDefineProperties(lit);
 
     if (lit->scope() != NULL) {
diff --git a/test/mjsunit/regress/regress-crbug-480819.js b/test/mjsunit/regress/regress-crbug-480819.js
new file mode 100644 (file)
index 0000000..8d3b7ee
--- /dev/null
@@ -0,0 +1,10 @@
+// Copyright 2015 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: --turbo-filter=* --always-opt --turbo-deoptimization --noanalyze-environment-liveness
+
+(function() {
+  "use strict";
+  class C1 {}
+})();