Revert "Assign bailout and type feedback IDs in a post-pass"
authorsvenpanne@chromium.org <svenpanne@chromium.org>
Tue, 21 Oct 2014 10:55:12 +0000 (10:55 +0000)
committersvenpanne@chromium.org <svenpanne@chromium.org>
Tue, 21 Oct 2014 10:55:12 +0000 (10:55 +0000)
This reverts r24757, which breaks the ARM64 simulator build.
Simple repro:

   out/arm64.debug/d8 -e 'eval("(function(){ const x; var x; })")'

TBR=bmeurer@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24762 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

22 files changed:
BUILD.gn
src/ast-numbering.cc [deleted file]
src/ast-numbering.h [deleted file]
src/ast-value-factory.h
src/ast.cc
src/ast.h
src/compiler.cc
src/compiler.h
src/compiler/js-inlining.cc
src/full-codegen.cc
src/hydrogen.cc
src/parser.cc
src/preparser.cc
src/preparser.h
src/rewriter.cc
src/scopes.cc
test/cctest/compiler/function-tester.h
test/cctest/compiler/test-codegen-deopt.cc
test/cctest/compiler/test-pipeline.cc
test/cctest/test-ast.cc
test/cctest/test-parsing.cc
tools/gyp/v8.gyp

index 01972a0..c8b0292 100644 (file)
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -433,8 +433,6 @@ source_set("v8_base") {
     "src/assembler.h",
     "src/assert-scope.h",
     "src/assert-scope.cc",
-    "src/ast-numbering.cc",
-    "src/ast-numbering.h",
     "src/ast-value-factory.cc",
     "src/ast-value-factory.h",
     "src/ast.cc",
diff --git a/src/ast-numbering.cc b/src/ast-numbering.cc
deleted file mode 100644 (file)
index e878424..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright 2012 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.
-
-#include "src/v8.h"
-
-#include "src/ast.h"
-#include "src/ast-numbering.h"
-#include "src/compiler.h"
-#include "src/scopes.h"
-
-namespace v8 {
-namespace internal {
-
-
-class AstNumberingVisitor FINAL : public AstVisitor {
- public:
-  explicit AstNumberingVisitor(Zone* zone)
-      : AstVisitor(), next_id_(BailoutId::FirstUsable().ToInt()) {
-    InitializeAstVisitor(zone);
-  }
-
-  void Renumber(FunctionLiteral* node);
-
- private:
-// AST node visitor interface.
-#define DEFINE_VISIT(type) virtual void Visit##type(type* node);
-  AST_NODE_LIST(DEFINE_VISIT)
-#undef DEFINE_VISIT
-
-  void VisitStatements(ZoneList<Statement*>* statements);
-  void VisitDeclarations(ZoneList<Declaration*>* declarations);
-  void VisitArguments(ZoneList<Expression*>* arguments);
-  void VisitObjectLiteralProperty(ObjectLiteralProperty* property);
-
-  int ReserveIdRange(int n) {
-    int tmp = next_id_;
-    next_id_ += n;
-    return tmp;
-  }
-
-  int next_id_;
-
-  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
-  DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor);
-};
-
-
-void AstNumberingVisitor::VisitVariableDeclaration(VariableDeclaration* node) {
-  VisitVariableProxy(node->proxy());
-}
-
-
-void AstNumberingVisitor::VisitExportDeclaration(ExportDeclaration* node) {
-  VisitVariableProxy(node->proxy());
-}
-
-
-void AstNumberingVisitor::VisitModuleUrl(ModuleUrl* node) {}
-
-
-void AstNumberingVisitor::VisitEmptyStatement(EmptyStatement* node) {}
-
-
-void AstNumberingVisitor::VisitContinueStatement(ContinueStatement* node) {}
-
-
-void AstNumberingVisitor::VisitBreakStatement(BreakStatement* node) {}
-
-
-void AstNumberingVisitor::VisitDebuggerStatement(DebuggerStatement* node) {
-  node->set_base_id(ReserveIdRange(DebuggerStatement::num_ids()));
-}
-
-
-void AstNumberingVisitor::VisitNativeFunctionLiteral(
-    NativeFunctionLiteral* node) {
-  node->set_base_id(ReserveIdRange(NativeFunctionLiteral::num_ids()));
-}
-
-
-void AstNumberingVisitor::VisitLiteral(Literal* node) {
-  node->set_base_id(ReserveIdRange(Literal::num_ids()));
-}
-
-
-void AstNumberingVisitor::VisitRegExpLiteral(RegExpLiteral* node) {
-  node->set_base_id(ReserveIdRange(RegExpLiteral::num_ids()));
-}
-
-
-void AstNumberingVisitor::VisitVariableProxy(VariableProxy* node) {
-  node->set_base_id(ReserveIdRange(VariableProxy::num_ids()));
-}
-
-
-void AstNumberingVisitor::VisitThisFunction(ThisFunction* node) {
-  node->set_base_id(ReserveIdRange(ThisFunction::num_ids()));
-}
-
-
-void AstNumberingVisitor::VisitSuperReference(SuperReference* node) {
-  node->set_base_id(ReserveIdRange(SuperReference::num_ids()));
-  Visit(node->this_var());
-}
-
-
-void AstNumberingVisitor::VisitModuleDeclaration(ModuleDeclaration* node) {
-  VisitVariableProxy(node->proxy());
-  Visit(node->module());
-}
-
-
-void AstNumberingVisitor::VisitImportDeclaration(ImportDeclaration* node) {
-  VisitVariableProxy(node->proxy());
-  Visit(node->module());
-}
-
-
-void AstNumberingVisitor::VisitModuleVariable(ModuleVariable* node) {
-  Visit(node->proxy());
-}
-
-
-void AstNumberingVisitor::VisitModulePath(ModulePath* node) {
-  Visit(node->module());
-}
-
-
-void AstNumberingVisitor::VisitModuleStatement(ModuleStatement* node) {
-  Visit(node->body());
-}
-
-
-void AstNumberingVisitor::VisitExpressionStatement(ExpressionStatement* node) {
-  Visit(node->expression());
-}
-
-
-void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) {
-  Visit(node->expression());
-}
-
-
-void AstNumberingVisitor::VisitYield(Yield* node) {
-  node->set_base_id(ReserveIdRange(Yield::num_ids()));
-  Visit(node->generator_object());
-  Visit(node->expression());
-}
-
-
-void AstNumberingVisitor::VisitThrow(Throw* node) {
-  node->set_base_id(ReserveIdRange(Throw::num_ids()));
-  Visit(node->exception());
-}
-
-
-void AstNumberingVisitor::VisitUnaryOperation(UnaryOperation* node) {
-  node->set_base_id(ReserveIdRange(UnaryOperation::num_ids()));
-  Visit(node->expression());
-}
-
-
-void AstNumberingVisitor::VisitCountOperation(CountOperation* node) {
-  node->set_base_id(ReserveIdRange(CountOperation::num_ids()));
-  Visit(node->expression());
-}
-
-
-void AstNumberingVisitor::VisitBlock(Block* node) {
-  node->set_base_id(ReserveIdRange(Block::num_ids()));
-  if (node->scope() != NULL) VisitDeclarations(node->scope()->declarations());
-  VisitStatements(node->statements());
-}
-
-
-void AstNumberingVisitor::VisitFunctionDeclaration(FunctionDeclaration* node) {
-  VisitVariableProxy(node->proxy());
-  VisitFunctionLiteral(node->fun());
-}
-
-
-void AstNumberingVisitor::VisitModuleLiteral(ModuleLiteral* node) {
-  VisitBlock(node->body());
-}
-
-
-void AstNumberingVisitor::VisitCallRuntime(CallRuntime* node) {
-  node->set_base_id(ReserveIdRange(CallRuntime::num_ids()));
-  VisitArguments(node->arguments());
-}
-
-
-void AstNumberingVisitor::VisitWithStatement(WithStatement* node) {
-  Visit(node->expression());
-  Visit(node->statement());
-}
-
-
-void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) {
-  node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids()));
-  Visit(node->body());
-  Visit(node->cond());
-}
-
-
-void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) {
-  node->set_base_id(ReserveIdRange(WhileStatement::num_ids()));
-  Visit(node->cond());
-  Visit(node->body());
-}
-
-
-void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) {
-  Visit(node->try_block());
-  Visit(node->catch_block());
-}
-
-
-void AstNumberingVisitor::VisitTryFinallyStatement(TryFinallyStatement* node) {
-  Visit(node->try_block());
-  Visit(node->finally_block());
-}
-
-
-void AstNumberingVisitor::VisitProperty(Property* node) {
-  node->set_base_id(ReserveIdRange(Property::num_ids()));
-  Visit(node->key());
-  Visit(node->obj());
-}
-
-
-void AstNumberingVisitor::VisitAssignment(Assignment* node) {
-  node->set_base_id(ReserveIdRange(Assignment::num_ids()));
-  if (node->is_compound()) VisitBinaryOperation(node->binary_operation());
-  Visit(node->target());
-  Visit(node->value());
-}
-
-
-void AstNumberingVisitor::VisitBinaryOperation(BinaryOperation* node) {
-  node->set_base_id(ReserveIdRange(BinaryOperation::num_ids()));
-  Visit(node->left());
-  Visit(node->right());
-}
-
-
-void AstNumberingVisitor::VisitCompareOperation(CompareOperation* node) {
-  node->set_base_id(ReserveIdRange(CompareOperation::num_ids()));
-  Visit(node->left());
-  Visit(node->right());
-}
-
-
-void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
-  node->set_base_id(ReserveIdRange(ForInStatement::num_ids()));
-  Visit(node->each());
-  Visit(node->enumerable());
-  Visit(node->body());
-}
-
-
-void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) {
-  node->set_base_id(ReserveIdRange(ForOfStatement::num_ids()));
-  Visit(node->assign_iterator());
-  Visit(node->next_result());
-  Visit(node->result_done());
-  Visit(node->assign_each());
-  Visit(node->body());
-}
-
-
-void AstNumberingVisitor::VisitConditional(Conditional* node) {
-  node->set_base_id(ReserveIdRange(Conditional::num_ids()));
-  Visit(node->condition());
-  Visit(node->then_expression());
-  Visit(node->else_expression());
-}
-
-
-void AstNumberingVisitor::VisitIfStatement(IfStatement* node) {
-  node->set_base_id(ReserveIdRange(IfStatement::num_ids()));
-  Visit(node->condition());
-  Visit(node->then_statement());
-  if (node->HasElseStatement()) {
-    Visit(node->else_statement());
-  }
-}
-
-
-void AstNumberingVisitor::VisitSwitchStatement(SwitchStatement* node) {
-  node->set_base_id(ReserveIdRange(SwitchStatement::num_ids()));
-  Visit(node->tag());
-  ZoneList<CaseClause*>* cases = node->cases();
-  for (int i = 0; i < cases->length(); i++) {
-    VisitCaseClause(cases->at(i));
-  }
-}
-
-
-void AstNumberingVisitor::VisitCaseClause(CaseClause* node) {
-  node->set_base_id(ReserveIdRange(CaseClause::num_ids()));
-  if (!node->is_default()) Visit(node->label());
-  VisitStatements(node->statements());
-}
-
-
-void AstNumberingVisitor::VisitForStatement(ForStatement* node) {
-  node->set_base_id(ReserveIdRange(ForStatement::num_ids()));
-  if (node->init() != NULL) Visit(node->init());
-  if (node->cond() != NULL) Visit(node->cond());
-  if (node->next() != NULL) Visit(node->next());
-  Visit(node->body());
-}
-
-
-void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) {
-  node->set_base_id(ReserveIdRange(ClassLiteral::num_ids()));
-  if (node->extends()) Visit(node->extends());
-  if (node->constructor()) Visit(node->constructor());
-  for (int i = 0; i < node->properties()->length(); i++) {
-    VisitObjectLiteralProperty(node->properties()->at(i));
-  }
-}
-
-
-void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) {
-  node->set_base_id(ReserveIdRange(ObjectLiteral::num_ids()));
-  for (int i = 0; i < node->properties()->length(); i++) {
-    VisitObjectLiteralProperty(node->properties()->at(i));
-  }
-}
-
-
-void AstNumberingVisitor::VisitObjectLiteralProperty(
-    ObjectLiteralProperty* node) {
-  Visit(node->key());
-  Visit(node->value());
-}
-
-
-void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) {
-  node->set_base_id(ReserveIdRange(node->num_ids()));
-  for (int i = 0; i < node->values()->length(); i++) {
-    Visit(node->values()->at(i));
-  }
-}
-
-
-void AstNumberingVisitor::VisitCall(Call* node) {
-  node->set_base_id(ReserveIdRange(Call::num_ids()));
-  Visit(node->expression());
-  VisitArguments(node->arguments());
-}
-
-
-void AstNumberingVisitor::VisitCallNew(CallNew* node) {
-  node->set_base_id(ReserveIdRange(CallNew::num_ids()));
-  Visit(node->expression());
-  VisitArguments(node->arguments());
-}
-
-
-void AstNumberingVisitor::VisitStatements(ZoneList<Statement*>* statements) {
-  if (statements == NULL) return;
-  for (int i = 0; i < statements->length(); i++) {
-    Visit(statements->at(i));
-  }
-}
-
-
-void AstNumberingVisitor::VisitDeclarations(
-    ZoneList<Declaration*>* declarations) {
-  for (int i = 0; i < declarations->length(); i++) {
-    Visit(declarations->at(i));
-  }
-}
-
-
-void AstNumberingVisitor::VisitArguments(ZoneList<Expression*>* arguments) {
-  for (int i = 0; i < arguments->length(); i++) {
-    Visit(arguments->at(i));
-  }
-}
-
-
-void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
-  node->set_base_id(ReserveIdRange(FunctionLiteral::num_ids()));
-  // We don't recurse into the declarations or body of the function literal:
-  // you have to separately Renumber() each FunctionLiteral that you compile.
-}
-
-
-void AstNumberingVisitor::Renumber(FunctionLiteral* node) {
-  if (node->scope()->HasIllegalRedeclaration()) {
-    node->scope()->VisitIllegalRedeclaration(this);
-    return;
-  }
-
-  Scope* scope = node->scope();
-  VisitDeclarations(scope->declarations());
-  if (scope->is_function_scope() && scope->function() != NULL) {
-    // Visit the name of the named function expression.
-    Visit(scope->function());
-  }
-  VisitStatements(node->body());
-}
-
-
-bool AstNumbering::Renumber(FunctionLiteral* function, Zone* zone) {
-  AstNumberingVisitor visitor(zone);
-  visitor.Renumber(function);
-  return !visitor.HasStackOverflow();
-}
-}
-}  // namespace v8::internal
diff --git a/src/ast-numbering.h b/src/ast-numbering.h
deleted file mode 100644 (file)
index ab97c22..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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.
-
-#ifndef V8_AST_NUMBERING_H_
-#define V8_AST_NUMBERING_H_
-
-namespace v8 {
-namespace internal {
-
-namespace AstNumbering {
-// Assign type feedback IDs and bailout IDs to an AST node tree.
-//
-bool Renumber(FunctionLiteral* function, Zone* zone);
-}
-}
-}  // namespace v8::internal
-
-#endif  // V8_AST_NUMBERING_H_
index de8a442..09702eb 100644 (file)
@@ -282,8 +282,6 @@ class AstValueFactory {
 #undef F
   }
 
-  Zone* zone() const { return zone_; }
-
   const AstRawString* GetOneByteString(Vector<const uint8_t> literal);
   const AstRawString* GetOneByteString(const char* string) {
     return GetOneByteString(Vector<const uint8_t>(
index 11bb4ef..722742e 100644 (file)
@@ -59,8 +59,9 @@ bool Expression::IsUndefinedLiteral(Isolate* isolate) const {
 }
 
 
-VariableProxy::VariableProxy(Zone* zone, Variable* var, int position)
-    : Expression(zone, position),
+VariableProxy::VariableProxy(Zone* zone, Variable* var, int position,
+                             IdGen* id_gen)
+    : Expression(zone, position, 0, id_gen),
       is_this_(var->is_this()),
       is_assigned_(false),
       is_resolved_(false),
@@ -72,8 +73,8 @@ VariableProxy::VariableProxy(Zone* zone, Variable* var, int position)
 
 
 VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
-                             Interface* interface, int position)
-    : Expression(zone, position),
+                             Interface* interface, int position, IdGen* id_gen)
+    : Expression(zone, position, 0, id_gen),
       is_this_(is_this),
       is_assigned_(false),
       is_resolved_(false),
@@ -97,8 +98,8 @@ void VariableProxy::BindTo(Variable* var) {
 
 
 Assignment::Assignment(Zone* zone, Token::Value op, Expression* target,
-                       Expression* value, int pos)
-    : Expression(zone, pos),
+                       Expression* value, int pos, IdGen* id_gen)
+    : Expression(zone, pos, num_ids(), id_gen),
       is_uninitialized_(false),
       key_type_(ELEMENT),
       store_mode_(STANDARD_STORE),
@@ -989,8 +990,8 @@ RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes)
 
 
 CaseClause::CaseClause(Zone* zone, Expression* label,
-                       ZoneList<Statement*>* statements, int pos)
-    : Expression(zone, pos),
+                       ZoneList<Statement*>* statements, int pos, IdGen* id_gen)
+    : Expression(zone, pos, num_ids(), id_gen),
       label_(label),
       statements_(statements),
       compare_type_(Type::None(zone)) {}
index f997c44..fe9a7fd 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -199,6 +199,23 @@ class AstProperties FINAL BASE_EMBEDDED {
 
 class AstNode: public ZoneObject {
  public:
+  // For generating IDs for AstNodes.
+  class IdGen {
+   public:
+    IdGen() : id_(BailoutId::FirstUsable().ToInt()) {}
+
+    int ReserveIdRange(int n) {
+      int tmp = id_;
+      id_ += n;
+      return tmp;
+    }
+
+   private:
+    int id_;
+
+    DISALLOW_COPY_AND_ASSIGN(IdGen);
+  };
+
 #define DECLARE_TYPE_ENUM(type) k##type,
   enum NodeType {
     AST_NODE_LIST(DECLARE_TYPE_ENUM)
@@ -388,30 +405,24 @@ class Expression : public AstNode {
   virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
   byte to_boolean_types() const { return to_boolean_types_; }
 
-  void set_base_id(int id) { base_id_ = id; }
-  static int num_ids() { return parent_num_ids() + 2; }
-  BailoutId id() const { return BailoutId(local_id(0)); }
-  TypeFeedbackId test_id() const { return TypeFeedbackId(local_id(1)); }
+  BailoutId id() const { return BailoutId(base_id() + 0); }
+  TypeFeedbackId test_id() const { return TypeFeedbackId(base_id() + 1); }
 
  protected:
-  Expression(Zone* zone, int pos)
+  Expression(Zone* zone, int pos, int num_ids_needed_by_subclass, IdGen* id_gen)
       : AstNode(pos),
-        base_id_(BailoutId::None().ToInt()),
+        base_id_(
+            id_gen->ReserveIdRange(num_ids_needed_by_subclass + num_ids())),
         bounds_(Bounds::Unbounded(zone)),
         is_parenthesized_(false),
         is_multi_parenthesized_(false) {}
-  static int parent_num_ids() { return 0; }
   void set_to_boolean_types(byte types) { to_boolean_types_ = types; }
 
-  int base_id() const {
-    DCHECK(!BailoutId(base_id_).IsNone());
-    return base_id_;
-  }
+  static int num_ids() { return 2; }
+  int base_id() const { return base_id_; }
 
  private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
-
-  int base_id_;
+  const int base_id_;
   Bounds bounds_;
   byte to_boolean_types_;
   bool is_parenthesized_ : 1;
@@ -443,34 +454,29 @@ class BreakableStatement : public Statement {
     return breakable_type_ == TARGET_FOR_ANONYMOUS;
   }
 
-  void set_base_id(int id) { base_id_ = id; }
-  static int num_ids() { return parent_num_ids() + 2; }
-  BailoutId EntryId() const { return BailoutId(local_id(0)); }
-  BailoutId ExitId() const { return BailoutId(local_id(1)); }
+  BailoutId EntryId() const { return BailoutId(base_id() + 0); }
+  BailoutId ExitId() const { return BailoutId(base_id() + 1); }
 
  protected:
   BreakableStatement(Zone* zone, ZoneList<const AstRawString*>* labels,
-                     BreakableType breakable_type, int position)
+                     BreakableType breakable_type, int position,
+                     int num_ids_needed_by_subclass, IdGen* id_gen)
       : Statement(zone, position),
         labels_(labels),
         breakable_type_(breakable_type),
-        base_id_(BailoutId::None().ToInt()) {
+        base_id_(
+            id_gen->ReserveIdRange(num_ids_needed_by_subclass + num_ids())) {
     DCHECK(labels == NULL || labels->length() > 0);
   }
-  static int parent_num_ids() { return 0; }
 
-  int base_id() const {
-    DCHECK(!BailoutId(base_id_).IsNone());
-    return base_id_;
-  }
+  static int num_ids() { return 2; }
+  int base_id() const { return base_id_; }
 
  private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
-
   ZoneList<const AstRawString*>* labels_;
   BreakableType breakable_type_;
   Label break_target_;
-  int base_id_;
+  const int base_id_;
 };
 
 
@@ -485,8 +491,7 @@ class Block FINAL : public BreakableStatement {
   ZoneList<Statement*>* statements() { return &statements_; }
   bool is_initializer_block() const { return is_initializer_block_; }
 
-  static int num_ids() { return parent_num_ids() + 1; }
-  BailoutId DeclsId() const { return BailoutId(local_id(0)); }
+  BailoutId DeclsId() const { return BailoutId(base_id() + 0); }
 
   virtual bool IsJump() const OVERRIDE {
     return !statements_.is_empty() && statements_.last()->IsJump()
@@ -498,16 +503,19 @@ class Block FINAL : public BreakableStatement {
 
  protected:
   Block(Zone* zone, ZoneList<const AstRawString*>* labels, int capacity,
-        bool is_initializer_block, int pos)
-      : BreakableStatement(zone, labels, TARGET_FOR_NAMED_ONLY, pos),
+        bool is_initializer_block, int pos, IdGen* id_gen)
+      : BreakableStatement(zone, labels, TARGET_FOR_NAMED_ONLY, pos, num_ids(),
+                           id_gen),
         statements_(capacity, zone),
         is_initializer_block_(is_initializer_block),
         scope_(NULL) {}
-  static int parent_num_ids() { return BreakableStatement::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 1; }
+  int base_id() const {
+    return BreakableStatement::base_id() + BreakableStatement::num_ids();
+  }
 
+ private:
   ZoneList<Statement*> statements_;
   bool is_initializer_block_;
   Scope* scope_;
@@ -755,8 +763,7 @@ class IterationStatement : public BreakableStatement {
 
   Statement* body() const { return body_; }
 
-  static int num_ids() { return parent_num_ids() + 1; }
-  BailoutId OsrEntryId() const { return BailoutId(local_id(0)); }
+  BailoutId OsrEntryId() const { return BailoutId(base_id() + 0); }
   virtual BailoutId ContinueId() const = 0;
   virtual BailoutId StackCheckId() const = 0;
 
@@ -764,15 +771,22 @@ class IterationStatement : public BreakableStatement {
   Label* continue_target()  { return &continue_target_; }
 
  protected:
-  IterationStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
-      : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos),
+  IterationStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
+                     int num_ids_needed_by_subclass, IdGen* id_gen)
+      : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos,
+                           num_ids_needed_by_subclass + num_ids(), id_gen),
         body_(NULL) {}
-  static int parent_num_ids() { return BreakableStatement::num_ids(); }
-  void Initialize(Statement* body) { body_ = body; }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  void Initialize(Statement* body) {
+    body_ = body;
+  }
+
+  static int num_ids() { return 1; }
+  int base_id() const {
+    return BreakableStatement::base_id() + BreakableStatement::num_ids();
+  }
 
+ private:
   Statement* body_;
   Label continue_target_;
 };
@@ -789,21 +803,23 @@ class DoWhileStatement FINAL : public IterationStatement {
 
   Expression* cond() const { return cond_; }
 
-  static int num_ids() { return parent_num_ids() + 2; }
   virtual BailoutId ContinueId() const OVERRIDE {
-    return BailoutId(local_id(0));
+    return BailoutId(base_id() + 0);
   }
   virtual BailoutId StackCheckId() const OVERRIDE { return BackEdgeId(); }
-  BailoutId BackEdgeId() const { return BailoutId(local_id(1)); }
+  BailoutId BackEdgeId() const { return BailoutId(base_id() + 1); }
 
  protected:
-  DoWhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
-      : IterationStatement(zone, labels, pos), cond_(NULL) {}
-  static int parent_num_ids() { return IterationStatement::num_ids(); }
+  DoWhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
+                   IdGen* id_gen)
+      : IterationStatement(zone, labels, pos, num_ids(), id_gen), cond_(NULL) {}
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 2; }
+  int base_id() const {
+    return IterationStatement::base_id() + IterationStatement::num_ids();
+  }
 
+ private:
   Expression* cond_;
 };
 
@@ -825,21 +841,23 @@ class WhileStatement FINAL : public IterationStatement {
     may_have_function_literal_ = value;
   }
 
-  static int num_ids() { return parent_num_ids() + 1; }
   virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
   virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
-  BailoutId BodyId() const { return BailoutId(local_id(0)); }
+  BailoutId BodyId() const { return BailoutId(base_id() + 0); }
 
  protected:
-  WhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
-      : IterationStatement(zone, labels, pos),
+  WhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
+                 IdGen* id_gen)
+      : IterationStatement(zone, labels, pos, num_ids(), id_gen),
         cond_(NULL),
         may_have_function_literal_(true) {}
-  static int parent_num_ids() { return IterationStatement::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 1; }
+  int base_id() const {
+    return IterationStatement::base_id() + IterationStatement::num_ids();
+  }
 
+ private:
   Expression* cond_;
 
   // True if there is a function literal subexpression in the condition.
@@ -872,30 +890,32 @@ class ForStatement FINAL : public IterationStatement {
     may_have_function_literal_ = value;
   }
 
-  static int num_ids() { return parent_num_ids() + 2; }
   virtual BailoutId ContinueId() const OVERRIDE {
-    return BailoutId(local_id(0));
+    return BailoutId(base_id() + 0);
   }
   virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
-  BailoutId BodyId() const { return BailoutId(local_id(1)); }
+  BailoutId BodyId() const { return BailoutId(base_id() + 1); }
 
   bool is_fast_smi_loop() { return loop_variable_ != NULL; }
   Variable* loop_variable() { return loop_variable_; }
   void set_loop_variable(Variable* var) { loop_variable_ = var; }
 
  protected:
-  ForStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
-      : IterationStatement(zone, labels, pos),
+  ForStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
+               IdGen* id_gen)
+      : IterationStatement(zone, labels, pos, num_ids(), id_gen),
         init_(NULL),
         cond_(NULL),
         next_(NULL),
         may_have_function_literal_(true),
         loop_variable_(NULL) {}
-  static int parent_num_ids() { return IterationStatement::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 2; }
+  int base_id() const {
+    return IterationStatement::base_id() + IterationStatement::num_ids();
+  }
 
+ private:
   Statement* init_;
   Expression* cond_;
   Statement* next_;
@@ -923,8 +943,12 @@ class ForEachStatement : public IterationStatement {
   Expression* subject() const { return subject_; }
 
  protected:
-  ForEachStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
-      : IterationStatement(zone, labels, pos), each_(NULL), subject_(NULL) {}
+  ForEachStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
+                   int num_ids_needed_by_subclass, IdGen* id_gen)
+      : IterationStatement(zone, labels, pos, num_ids_needed_by_subclass,
+                           id_gen),
+        each_(NULL),
+        subject_(NULL) {}
 
  private:
   Expression* each_;
@@ -957,22 +981,24 @@ class ForInStatement FINAL : public ForEachStatement {
   ForInType for_in_type() const { return for_in_type_; }
   void set_for_in_type(ForInType type) { for_in_type_ = type; }
 
-  static int num_ids() { return parent_num_ids() + 2; }
-  BailoutId BodyId() const { return BailoutId(local_id(0)); }
-  BailoutId PrepareId() const { return BailoutId(local_id(1)); }
+  BailoutId BodyId() const { return BailoutId(base_id() + 0); }
+  BailoutId PrepareId() const { return BailoutId(base_id() + 1); }
   virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
   virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
 
  protected:
-  ForInStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
-      : ForEachStatement(zone, labels, pos),
+  ForInStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
+                 IdGen* id_gen)
+      : ForEachStatement(zone, labels, pos, num_ids(), id_gen),
         for_in_type_(SLOW_FOR_IN),
         for_in_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
-  static int parent_num_ids() { return ForEachStatement::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 2; }
+  int base_id() const {
+    return ForEachStatement::base_id() + ForEachStatement::num_ids();
+  }
 
+ private:
   ForInType for_in_type_;
   FeedbackVectorSlot for_in_feedback_slot_;
 };
@@ -1023,21 +1049,23 @@ class ForOfStatement FINAL : public ForEachStatement {
   virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
   virtual BailoutId StackCheckId() const OVERRIDE { return BackEdgeId(); }
 
-  static int num_ids() { return parent_num_ids() + 1; }
-  BailoutId BackEdgeId() const { return BailoutId(local_id(0)); }
+  BailoutId BackEdgeId() const { return BailoutId(base_id() + 0); }
 
  protected:
-  ForOfStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
-      : ForEachStatement(zone, labels, pos),
+  ForOfStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
+                 IdGen* id_gen)
+      : ForEachStatement(zone, labels, pos, num_ids(), id_gen),
         assign_iterator_(NULL),
         next_result_(NULL),
         result_done_(NULL),
         assign_each_(NULL) {}
-  static int parent_num_ids() { return ForEachStatement::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 1; }
+  int base_id() const {
+    return ForEachStatement::base_id() + ForEachStatement::num_ids();
+  }
 
+ private:
   Expression* assign_iterator_;
   Expression* next_result_;
   Expression* result_done_;
@@ -1152,20 +1180,18 @@ class CaseClause FINAL : public Expression {
   Label* body_target() { return &body_target_; }
   ZoneList<Statement*>* statements() const { return statements_; }
 
-  static int num_ids() { return parent_num_ids() + 2; }
-  BailoutId EntryId() const { return BailoutId(local_id(0)); }
-  TypeFeedbackId CompareId() { return TypeFeedbackId(local_id(1)); }
+  BailoutId EntryId() const { return BailoutId(base_id() + 0); }
+  TypeFeedbackId CompareId() { return TypeFeedbackId(base_id() + 1); }
 
   Type* compare_type() { return compare_type_; }
   void set_compare_type(Type* type) { compare_type_ = type; }
 
- protected:
-  static int parent_num_ids() { return Expression::num_ids(); }
-
  private:
   CaseClause(Zone* zone, Expression* label, ZoneList<Statement*>* statements,
-             int pos);
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+             int pos, IdGen* id_gen);
+
+  static int num_ids() { return 2; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
   Expression* label_;
   Label body_target_;
@@ -1187,8 +1213,9 @@ class SwitchStatement FINAL : public BreakableStatement {
   ZoneList<CaseClause*>* cases() const { return cases_; }
 
  protected:
-  SwitchStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
-      : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos),
+  SwitchStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
+                  IdGen* id_gen)
+      : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos, 0, id_gen),
         tag_(NULL),
         cases_(NULL) {}
 
@@ -1219,34 +1246,27 @@ class IfStatement FINAL : public Statement {
         && HasElseStatement() && else_statement()->IsJump();
   }
 
-  void set_base_id(int id) { base_id_ = id; }
-  static int num_ids() { return parent_num_ids() + 3; }
-  BailoutId IfId() const { return BailoutId(local_id(0)); }
-  BailoutId ThenId() const { return BailoutId(local_id(1)); }
-  BailoutId ElseId() const { return BailoutId(local_id(2)); }
+  BailoutId IfId() const { return BailoutId(base_id() + 0); }
+  BailoutId ThenId() const { return BailoutId(base_id() + 1); }
+  BailoutId ElseId() const { return BailoutId(base_id() + 2); }
 
  protected:
   IfStatement(Zone* zone, Expression* condition, Statement* then_statement,
-              Statement* else_statement, int pos)
+              Statement* else_statement, int pos, IdGen* id_gen)
       : Statement(zone, pos),
         condition_(condition),
         then_statement_(then_statement),
         else_statement_(else_statement),
-        base_id_(BailoutId::None().ToInt()) {}
-  static int parent_num_ids() { return 0; }
+        base_id_(id_gen->ReserveIdRange(num_ids())) {}
 
-  int base_id() const {
-    DCHECK(!BailoutId(base_id_).IsNone());
-    return base_id_;
-  }
+  static int num_ids() { return 3; }
+  int base_id() const { return base_id_; }
 
  private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
-
   Expression* condition_;
   Statement* then_statement_;
   Statement* else_statement_;
-  int base_id_;
+  const int base_id_;
 };
 
 
@@ -1350,24 +1370,17 @@ class DebuggerStatement FINAL : public Statement {
  public:
   DECLARE_NODE_TYPE(DebuggerStatement)
 
-  void set_base_id(int id) { base_id_ = id; }
-  static int num_ids() { return parent_num_ids() + 1; }
-  BailoutId DebugBreakId() const { return BailoutId(local_id(0)); }
+  BailoutId DebugBreakId() const { return BailoutId(base_id() + 0); }
 
  protected:
-  explicit DebuggerStatement(Zone* zone, int pos)
-      : Statement(zone, pos), base_id_(BailoutId::None().ToInt()) {}
-  static int parent_num_ids() { return 0; }
+  explicit DebuggerStatement(Zone* zone, int pos, IdGen* id_gen)
+      : Statement(zone, pos), base_id_(id_gen->ReserveIdRange(num_ids())) {}
 
-  int base_id() const {
-    DCHECK(!BailoutId(base_id_).IsNone());
-    return base_id_;
-  }
+  static int num_ids() { return 1; }
+  int base_id() const { return base_id_; }
 
  private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
-
-  int base_id_;
+  const int base_id_;
 };
 
 
@@ -1413,19 +1426,18 @@ class Literal FINAL : public Expression {
   uint32_t Hash();
   static bool Match(void* literal1, void* literal2);
 
-  static int num_ids() { return parent_num_ids() + 1; }
   TypeFeedbackId LiteralFeedbackId() const {
-    return TypeFeedbackId(local_id(0));
+    return TypeFeedbackId(base_id() + 0);
   }
 
  protected:
-  Literal(Zone* zone, const AstValue* value, int position)
-      : Expression(zone, position), value_(value) {}
-  static int parent_num_ids() { return Expression::num_ids(); }
+  Literal(Zone* zone, const AstValue* value, int position, IdGen* id_gen)
+      : Expression(zone, position, num_ids(), id_gen), value_(value) {}
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 1; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
+ private:
   const AstValue* value_;
 };
 
@@ -1444,8 +1456,9 @@ class MaterializedLiteral : public Expression {
   }
 
  protected:
-  MaterializedLiteral(Zone* zone, int literal_index, int pos)
-      : Expression(zone, pos),
+  MaterializedLiteral(Zone* zone, int literal_index, int pos,
+                      int num_ids_needed_by_subclass, IdGen* id_gen)
+      : Expression(zone, pos, num_ids_needed_by_subclass, id_gen),
         literal_index_(literal_index),
         is_simple_(false),
         depth_(0) {}
@@ -1575,8 +1588,9 @@ class ObjectLiteral FINAL : public MaterializedLiteral {
 
  protected:
   ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
-                int boilerplate_properties, bool has_function, int pos)
-      : MaterializedLiteral(zone, literal_index, pos),
+                int boilerplate_properties, bool has_function, int pos,
+                IdGen* id_gen)
+      : MaterializedLiteral(zone, literal_index, pos, 0, id_gen),
         properties_(properties),
         boilerplate_properties_(boilerplate_properties),
         fast_elements_(false),
@@ -1603,8 +1617,9 @@ class RegExpLiteral FINAL : public MaterializedLiteral {
 
  protected:
   RegExpLiteral(Zone* zone, const AstRawString* pattern,
-                const AstRawString* flags, int literal_index, int pos)
-      : MaterializedLiteral(zone, literal_index, pos),
+                const AstRawString* flags, int literal_index, int pos,
+                IdGen* id_gen)
+      : MaterializedLiteral(zone, literal_index, pos, 0, id_gen),
         pattern_(pattern),
         flags_(flags) {
     set_depth(1);
@@ -1625,12 +1640,8 @@ class ArrayLiteral FINAL : public MaterializedLiteral {
   Handle<FixedArray> constant_elements() const { return constant_elements_; }
   ZoneList<Expression*>* values() const { return values_; }
 
-  // Unlike other AST nodes, this number of bailout IDs allocated for an
-  // ArrayLiteral can vary, so num_ids() is not a static method.
-  int num_ids() const { return parent_num_ids() + values()->length(); }
-
   // Return an AST id for an element that is used in simulate instructions.
-  BailoutId GetIdForElement(int i) { return BailoutId(local_id(i)); }
+  BailoutId GetIdForElement(int i) { return BailoutId(base_id() + i); }
 
   // Populate the constant elements fixed array.
   void BuildConstantElements(Isolate* isolate);
@@ -1650,13 +1661,16 @@ class ArrayLiteral FINAL : public MaterializedLiteral {
 
  protected:
   ArrayLiteral(Zone* zone, ZoneList<Expression*>* values, int literal_index,
-               int pos)
-      : MaterializedLiteral(zone, literal_index, pos), values_(values) {}
-  static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
+               int pos, IdGen* id_gen)
+      : MaterializedLiteral(zone, literal_index, pos, num_ids(values), id_gen),
+        values_(values) {}
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids(ZoneList<Expression*>* values) { return values->length(); }
+  int base_id() const {
+    return MaterializedLiteral::base_id() + MaterializedLiteral::num_ids();
+  }
 
+ private:
   Handle<FixedArray> constant_elements_;
   ZoneList<Expression*>* values_;
 };
@@ -1712,10 +1726,10 @@ class VariableProxy FINAL : public Expression {
   }
 
  protected:
-  VariableProxy(Zone* zone, Variable* var, int position);
+  VariableProxy(Zone* zone, Variable* var, int position, IdGen* id_gen);
 
   VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
-                Interface* interface, int position);
+                Interface* interface, int position, IdGen* id_gen);
 
   bool is_this_ : 1;
   bool is_assigned_ : 1;
@@ -1738,9 +1752,9 @@ class Property FINAL : public Expression {
   Expression* obj() const { return obj_; }
   Expression* key() const { return key_; }
 
-  static int num_ids() { return parent_num_ids() + 2; }
-  BailoutId LoadId() const { return BailoutId(local_id(0)); }
-  TypeFeedbackId PropertyFeedbackId() { return TypeFeedbackId(local_id(1)); }
+  BailoutId LoadId() const { return BailoutId(base_id() + 0); }
+  TypeFeedbackId PropertyFeedbackId() { return TypeFeedbackId(base_id() + 1); }
+
 
   bool IsStringAccess() const { return is_string_access_; }
 
@@ -1783,19 +1797,19 @@ class Property FINAL : public Expression {
   }
 
  protected:
-  Property(Zone* zone, Expression* obj, Expression* key, int pos)
-      : Expression(zone, pos),
+  Property(Zone* zone, Expression* obj, Expression* key, int pos, IdGen* id_gen)
+      : Expression(zone, pos, num_ids(), id_gen),
         is_for_call_(false),
         is_uninitialized_(false),
         is_string_access_(false),
         property_feedback_slot_(FeedbackVectorICSlot::Invalid()),
         obj_(obj),
         key_(key) {}
-  static int parent_num_ids() { return Expression::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 2; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
+ private:
   bool is_for_call_ : 1;
   bool is_uninitialized_ : 1;
   bool is_string_access_ : 1;
@@ -1859,9 +1873,8 @@ class Call FINAL : public Expression {
   }
   bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupIterator* it);
 
-  static int num_ids() { return parent_num_ids() + 2; }
-  BailoutId ReturnId() const { return BailoutId(local_id(0)); }
-  BailoutId EvalOrLookupId() const { return BailoutId(local_id(1)); }
+  BailoutId ReturnId() const { return BailoutId(base_id() + 0); }
+  BailoutId EvalOrLookupId() const { return BailoutId(base_id() + 1); }
 
   enum CallType {
     POSSIBLY_EVAL_CALL,
@@ -1883,8 +1896,8 @@ class Call FINAL : public Expression {
 
  protected:
   Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
-       int pos)
-      : Expression(zone, pos),
+       int pos, IdGen* id_gen)
+      : Expression(zone, pos, num_ids(), id_gen),
         call_feedback_slot_(FeedbackVectorICSlot::Invalid()),
         expression_(expression),
         arguments_(arguments) {
@@ -1892,11 +1905,11 @@ class Call FINAL : public Expression {
       expression->AsProperty()->mark_for_call();
     }
   }
-  static int parent_num_ids() { return Expression::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 2; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
+ private:
   FeedbackVectorICSlot call_feedback_slot_;
   Expression* expression_;
   ZoneList<Expression*>* arguments_;
@@ -1934,24 +1947,23 @@ class CallNew FINAL : public Expression {
     return allocation_site_;
   }
 
-  static int num_ids() { return parent_num_ids() + 1; }
   static int feedback_slots() { return 1; }
-  BailoutId ReturnId() const { return BailoutId(local_id(0)); }
+
+  BailoutId ReturnId() const { return BailoutId(base_id() + 0); }
 
  protected:
   CallNew(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
-          int pos)
-      : Expression(zone, pos),
+          int pos, IdGen* id_gen)
+      : Expression(zone, pos, num_ids(), id_gen),
         expression_(expression),
         arguments_(arguments),
         is_monomorphic_(false),
         callnew_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
 
-  static int parent_num_ids() { return Expression::num_ids(); }
+  static int num_ids() { return 1; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
  private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
-
   Expression* expression_;
   ZoneList<Expression*>* arguments_;
   bool is_monomorphic_;
@@ -1988,25 +2000,24 @@ class CallRuntime FINAL : public Expression {
     return callruntime_feedback_slot_;
   }
 
-  static int num_ids() { return parent_num_ids() + 1; }
   TypeFeedbackId CallRuntimeFeedbackId() const {
-    return TypeFeedbackId(local_id(0));
+    return TypeFeedbackId(base_id() + 0);
   }
 
  protected:
   CallRuntime(Zone* zone, const AstRawString* name,
               const Runtime::Function* function,
-              ZoneList<Expression*>* arguments, int pos)
-      : Expression(zone, pos),
+              ZoneList<Expression*>* arguments, int pos, IdGen* id_gen)
+      : Expression(zone, pos, num_ids(), id_gen),
         raw_name_(name),
         function_(function),
         arguments_(arguments),
         callruntime_feedback_slot_(FeedbackVectorICSlot::Invalid()) {}
-  static int parent_num_ids() { return Expression::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 1; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
+ private:
   const AstRawString* raw_name_;
   const Runtime::Function* function_;
   ZoneList<Expression*>* arguments_;
@@ -2023,23 +2034,25 @@ class UnaryOperation FINAL : public Expression {
 
   // For unary not (Token::NOT), the AST ids where true and false will
   // actually be materialized, respectively.
-  static int num_ids() { return parent_num_ids() + 2; }
-  BailoutId MaterializeTrueId() const { return BailoutId(local_id(0)); }
-  BailoutId MaterializeFalseId() const { return BailoutId(local_id(1)); }
+  BailoutId MaterializeTrueId() const { return BailoutId(base_id() + 0); }
+  BailoutId MaterializeFalseId() const { return BailoutId(base_id() + 1); }
 
   virtual void RecordToBooleanTypeFeedback(
       TypeFeedbackOracle* oracle) OVERRIDE;
 
  protected:
-  UnaryOperation(Zone* zone, Token::Value op, Expression* expression, int pos)
-      : Expression(zone, pos), op_(op), expression_(expression) {
+  UnaryOperation(Zone* zone, Token::Value op, Expression* expression, int pos,
+                 IdGen* id_gen)
+      : Expression(zone, pos, num_ids(), id_gen),
+        op_(op),
+        expression_(expression) {
     DCHECK(Token::IsUnaryOp(op));
   }
-  static int parent_num_ids() { return Expression::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 2; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
+ private:
   Token::Value op_;
   Expression* expression_;
 };
@@ -2061,11 +2074,10 @@ class BinaryOperation FINAL : public Expression {
 
   // The short-circuit logical operations need an AST ID for their
   // right-hand subexpression.
-  static int num_ids() { return parent_num_ids() + 2; }
-  BailoutId RightId() const { return BailoutId(local_id(0)); }
+  BailoutId RightId() const { return BailoutId(base_id() + 0); }
 
   TypeFeedbackId BinaryOperationFeedbackId() const {
-    return TypeFeedbackId(local_id(1));
+    return TypeFeedbackId(base_id() + 1);
   }
   Maybe<int> fixed_right_arg() const {
     return has_fixed_right_arg_ ? Maybe<int>(fixed_right_arg_value_)
@@ -2081,18 +2093,18 @@ class BinaryOperation FINAL : public Expression {
 
  protected:
   BinaryOperation(Zone* zone, Token::Value op, Expression* left,
-                  Expression* right, int pos)
-      : Expression(zone, pos),
+                  Expression* right, int pos, IdGen* id_gen)
+      : Expression(zone, pos, num_ids(), id_gen),
         op_(static_cast<byte>(op)),
         left_(left),
         right_(right) {
     DCHECK(Token::IsBinaryOp(op));
   }
-  static int parent_num_ids() { return Expression::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 2; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
+ private:
   const byte op_;  // actually Token::Value
   // TODO(rossberg): the fixed arg should probably be represented as a Constant
   // type for the RHS. Currenty it's actually a Maybe<int>
@@ -2133,29 +2145,28 @@ class CountOperation FINAL : public Expression {
   void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
   void set_type(Type* type) { type_ = type; }
 
-  static int num_ids() { return parent_num_ids() + 3; }
-  BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
+  BailoutId AssignmentId() const { return BailoutId(base_id() + 0); }
   TypeFeedbackId CountBinOpFeedbackId() const {
-    return TypeFeedbackId(local_id(1));
+    return TypeFeedbackId(base_id() + 1);
   }
   TypeFeedbackId CountStoreFeedbackId() const {
-    return TypeFeedbackId(local_id(2));
+    return TypeFeedbackId(base_id() + 2);
   }
 
  protected:
   CountOperation(Zone* zone, Token::Value op, bool is_prefix, Expression* expr,
-                 int pos)
-      : Expression(zone, pos),
+                 int pos, IdGen* id_gen)
+      : Expression(zone, pos, num_ids(), id_gen),
         op_(op),
         is_prefix_(is_prefix),
         key_type_(ELEMENT),
         store_mode_(STANDARD_STORE),
         expression_(expr) {}
-  static int parent_num_ids() { return Expression::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 3; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
+ private:
   Token::Value op_;
   bool is_prefix_ : 1;
   IcCheckType key_type_ : 1;
@@ -2176,9 +2187,8 @@ class CompareOperation FINAL : public Expression {
   Expression* right() const { return right_; }
 
   // Type feedback information.
-  static int num_ids() { return parent_num_ids() + 1; }
   TypeFeedbackId CompareOperationFeedbackId() const {
-    return TypeFeedbackId(local_id(0));
+    return TypeFeedbackId(base_id() + 0);
   }
   Type* combined_type() const { return combined_type_; }
   void set_combined_type(Type* type) { combined_type_ = type; }
@@ -2190,19 +2200,19 @@ class CompareOperation FINAL : public Expression {
 
  protected:
   CompareOperation(Zone* zone, Token::Value op, Expression* left,
-                   Expression* right, int pos)
-      : Expression(zone, pos),
+                   Expression* right, int pos, IdGen* id_gen)
+      : Expression(zone, pos, num_ids(), id_gen),
         op_(op),
         left_(left),
         right_(right),
         combined_type_(Type::None(zone)) {
     DCHECK(Token::IsCompareOp(op));
   }
-  static int parent_num_ids() { return Expression::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 1; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
+ private:
   Token::Value op_;
   Expression* left_;
   Expression* right_;
@@ -2219,22 +2229,21 @@ class Conditional FINAL : public Expression {
   Expression* then_expression() const { return then_expression_; }
   Expression* else_expression() const { return else_expression_; }
 
-  static int num_ids() { return parent_num_ids() + 2; }
-  BailoutId ThenId() const { return BailoutId(local_id(0)); }
-  BailoutId ElseId() const { return BailoutId(local_id(1)); }
+  BailoutId ThenId() const { return BailoutId(base_id() + 0); }
+  BailoutId ElseId() const { return BailoutId(base_id() + 1); }
 
  protected:
   Conditional(Zone* zone, Expression* condition, Expression* then_expression,
-              Expression* else_expression, int position)
-      : Expression(zone, position),
+              Expression* else_expression, int position, IdGen* id_gen)
+      : Expression(zone, position, num_ids(), id_gen),
         condition_(condition),
         then_expression_(then_expression),
         else_expression_(else_expression) {}
-  static int parent_num_ids() { return Expression::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 2; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
+ private:
   Expression* condition_;
   Expression* then_expression_;
   Expression* else_expression_;
@@ -2257,11 +2266,12 @@ class Assignment FINAL : public Expression {
   // This check relies on the definition order of token in token.h.
   bool is_compound() const { return op() > Token::ASSIGN; }
 
-  static int num_ids() { return parent_num_ids() + 2; }
-  BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
+  BailoutId AssignmentId() const { return BailoutId(base_id() + 0); }
 
   // Type feedback information.
-  TypeFeedbackId AssignmentFeedbackId() { return TypeFeedbackId(local_id(1)); }
+  TypeFeedbackId AssignmentFeedbackId() {
+    return TypeFeedbackId(base_id() + 1);
+  }
   virtual bool IsMonomorphic() OVERRIDE {
     return receiver_types_.length() == 1;
   }
@@ -2282,11 +2292,13 @@ class Assignment FINAL : public Expression {
 
  protected:
   Assignment(Zone* zone, Token::Value op, Expression* target, Expression* value,
-             int pos);
-  static int parent_num_ids() { return Expression::num_ids(); }
+             int pos, IdGen* id_gen);
+
+  static int num_ids() { return 2; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
-  template <class Visitor>
-  void Init(AstNodeFactory<Visitor>* factory) {
+  template<class Visitor>
+  void Init(Zone* zone, AstNodeFactory<Visitor>* factory) {
     DCHECK(Token::IsAssignmentOp(op_));
     if (is_compound()) {
       binary_operation_ = factory->NewBinaryOperation(
@@ -2295,8 +2307,6 @@ class Assignment FINAL : public Expression {
   }
 
  private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
-
   bool is_uninitialized_ : 1;
   IcCheckType key_type_ : 1;
   KeyedAccessStoreMode store_mode_ : 5;  // Windows treats as signed,
@@ -2357,8 +2367,8 @@ class Yield FINAL : public Expression {
 
  protected:
   Yield(Zone* zone, Expression* generator_object, Expression* expression,
-        Kind yield_kind, int pos)
-      : Expression(zone, pos),
+        Kind yield_kind, int pos, IdGen* id_gen)
+      : Expression(zone, pos, 0, id_gen),
         generator_object_(generator_object),
         expression_(expression),
         yield_kind_(yield_kind),
@@ -2381,8 +2391,8 @@ class Throw FINAL : public Expression {
   Expression* exception() const { return exception_; }
 
  protected:
-  Throw(Zone* zone, Expression* exception, int pos)
-      : Expression(zone, pos), exception_(exception) {}
+  Throw(Zone* zone, Expression* exception, int pos, IdGen* id_gen)
+      : Expression(zone, pos, 0, id_gen), exception_(exception) {}
 
  private:
   Expression* exception_;
@@ -2536,8 +2546,8 @@ class FunctionLiteral FINAL : public Expression {
                   ParameterFlag has_duplicate_parameters,
                   IsFunctionFlag is_function,
                   IsParenthesizedFlag is_parenthesized, FunctionKind kind,
-                  int position)
-      : Expression(zone, position),
+                  int position, IdGen* id_gen)
+      : Expression(zone, position, 0, id_gen),
         raw_name_(name),
         scope_(scope),
         body_(body),
@@ -2603,8 +2613,8 @@ class ClassLiteral FINAL : public Expression {
  protected:
   ClassLiteral(Zone* zone, const AstRawString* name, Expression* extends,
                Expression* constructor, ZoneList<Property*>* properties,
-               int start_position, int end_position)
-      : Expression(zone, start_position),
+               int start_position, int end_position, IdGen* id_gen)
+      : Expression(zone, start_position, 0, id_gen),
         raw_name_(name),
         extends_(extends),
         constructor_(constructor),
@@ -2629,8 +2639,8 @@ class NativeFunctionLiteral FINAL : public Expression {
 
  protected:
   NativeFunctionLiteral(Zone* zone, const AstRawString* name,
-                        v8::Extension* extension, int pos)
-      : Expression(zone, pos), name_(name), extension_(extension) {}
+                        v8::Extension* extension, int pos, IdGen* id_gen)
+      : Expression(zone, pos, 0, id_gen), name_(name), extension_(extension) {}
 
  private:
   const AstRawString* name_;
@@ -2643,7 +2653,8 @@ class ThisFunction FINAL : public Expression {
   DECLARE_NODE_TYPE(ThisFunction)
 
  protected:
-  ThisFunction(Zone* zone, int pos) : Expression(zone, pos) {}
+  ThisFunction(Zone* zone, int pos, IdGen* id_gen)
+      : Expression(zone, pos, 0, id_gen) {}
 };
 
 
@@ -2653,8 +2664,9 @@ class SuperReference FINAL : public Expression {
 
   VariableProxy* this_var() const { return this_var_; }
 
-  static int num_ids() { return parent_num_ids() + 1; }
-  TypeFeedbackId HomeObjectFeedbackId() { return TypeFeedbackId(local_id(0)); }
+  TypeFeedbackId HomeObjectFeedbackId() {
+    return TypeFeedbackId(base_id() + 0);
+  }
 
   // Type feedback information.
   virtual FeedbackVectorRequirements ComputeFeedbackRequirements() {
@@ -2670,17 +2682,17 @@ class SuperReference FINAL : public Expression {
   }
 
  protected:
-  SuperReference(Zone* zone, VariableProxy* this_var, int pos)
-      : Expression(zone, pos),
+  SuperReference(Zone* zone, VariableProxy* this_var, int pos, IdGen* id_gen)
+      : Expression(zone, pos, num_ids(), id_gen),
         this_var_(this_var),
         homeobject_feedback_slot_(FeedbackVectorICSlot::Invalid()) {
     DCHECK(this_var->is_this());
   }
-  static int parent_num_ids() { return Expression::num_ids(); }
 
- private:
-  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+  static int num_ids() { return 1; }
+  int base_id() const { return Expression::base_id() + Expression::num_ids(); }
 
+ private:
   VariableProxy* this_var_;
   FeedbackVectorICSlot homeobject_feedback_slot_;
 };
@@ -3182,9 +3194,9 @@ class AstNullVisitor BASE_EMBEDDED {
 template<class Visitor>
 class AstNodeFactory FINAL BASE_EMBEDDED {
  public:
-  explicit AstNodeFactory(AstValueFactory* ast_value_factory)
-      : zone_(ast_value_factory->zone()),
-        ast_value_factory_(ast_value_factory) {}
+  AstNodeFactory(Zone* zone, AstValueFactory* ast_value_factory,
+                 AstNode::IdGen* id_gen)
+      : zone_(zone), ast_value_factory_(ast_value_factory), id_gen_(id_gen) {}
 
   Visitor* visitor() { return &visitor_; }
 
@@ -3262,14 +3274,14 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                   int capacity,
                   bool is_initializer_block,
                   int pos) {
-    Block* block =
-        new (zone_) Block(zone_, labels, capacity, is_initializer_block, pos);
+    Block* block = new (zone_)
+        Block(zone_, labels, capacity, is_initializer_block, pos, id_gen_);
     VISIT_AND_RETURN(Block, block)
   }
 
 #define STATEMENT_WITH_LABELS(NodeType)                                     \
   NodeType* New##NodeType(ZoneList<const AstRawString*>* labels, int pos) { \
-    NodeType* stmt = new (zone_) NodeType(zone_, labels, pos);              \
+    NodeType* stmt = new (zone_) NodeType(zone_, labels, pos, id_gen_);     \
     VISIT_AND_RETURN(NodeType, stmt);                                       \
   }
   STATEMENT_WITH_LABELS(DoWhileStatement)
@@ -3283,11 +3295,13 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                                         int pos) {
     switch (visit_mode) {
       case ForEachStatement::ENUMERATE: {
-        ForInStatement* stmt = new (zone_) ForInStatement(zone_, labels, pos);
+        ForInStatement* stmt =
+            new (zone_) ForInStatement(zone_, labels, pos, id_gen_);
         VISIT_AND_RETURN(ForInStatement, stmt);
       }
       case ForEachStatement::ITERATE: {
-        ForOfStatement* stmt = new (zone_) ForOfStatement(zone_, labels, pos);
+        ForOfStatement* stmt =
+            new (zone_) ForOfStatement(zone_, labels, pos, id_gen_);
         VISIT_AND_RETURN(ForOfStatement, stmt);
       }
     }
@@ -3335,8 +3349,8 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                               Statement* then_statement,
                               Statement* else_statement,
                               int pos) {
-    IfStatement* stmt = new (zone_)
-        IfStatement(zone_, condition, then_statement, else_statement, pos);
+    IfStatement* stmt = new (zone_) IfStatement(
+        zone_, condition, then_statement, else_statement, pos, id_gen_);
     VISIT_AND_RETURN(IfStatement, stmt)
   }
 
@@ -3361,7 +3375,8 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
   }
 
   DebuggerStatement* NewDebuggerStatement(int pos) {
-    DebuggerStatement* stmt = new (zone_) DebuggerStatement(zone_, pos);
+    DebuggerStatement* stmt =
+        new (zone_) DebuggerStatement(zone_, pos, id_gen_);
     VISIT_AND_RETURN(DebuggerStatement, stmt)
   }
 
@@ -3371,63 +3386,64 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
 
   CaseClause* NewCaseClause(
       Expression* label, ZoneList<Statement*>* statements, int pos) {
-    CaseClause* clause = new (zone_) CaseClause(zone_, label, statements, pos);
+    CaseClause* clause =
+        new (zone_) CaseClause(zone_, label, statements, pos, id_gen_);
     VISIT_AND_RETURN(CaseClause, clause)
   }
 
   Literal* NewStringLiteral(const AstRawString* string, int pos) {
-    Literal* lit =
-        new (zone_) Literal(zone_, ast_value_factory_->NewString(string), pos);
+    Literal* lit = new (zone_)
+        Literal(zone_, ast_value_factory_->NewString(string), pos, id_gen_);
     VISIT_AND_RETURN(Literal, lit)
   }
 
   // A JavaScript symbol (ECMA-262 edition 6).
   Literal* NewSymbolLiteral(const char* name, int pos) {
-    Literal* lit =
-        new (zone_) Literal(zone_, ast_value_factory_->NewSymbol(name), pos);
+    Literal* lit = new (zone_)
+        Literal(zone_, ast_value_factory_->NewSymbol(name), pos, id_gen_);
     VISIT_AND_RETURN(Literal, lit)
   }
 
   Literal* NewNumberLiteral(double number, int pos) {
-    Literal* lit =
-        new (zone_) Literal(zone_, ast_value_factory_->NewNumber(number), pos);
+    Literal* lit = new (zone_)
+        Literal(zone_, ast_value_factory_->NewNumber(number), pos, id_gen_);
     VISIT_AND_RETURN(Literal, lit)
   }
 
   Literal* NewSmiLiteral(int number, int pos) {
-    Literal* lit =
-        new (zone_) Literal(zone_, ast_value_factory_->NewSmi(number), pos);
+    Literal* lit = new (zone_)
+        Literal(zone_, ast_value_factory_->NewSmi(number), pos, id_gen_);
     VISIT_AND_RETURN(Literal, lit)
   }
 
   Literal* NewBooleanLiteral(bool b, int pos) {
-    Literal* lit =
-        new (zone_) Literal(zone_, ast_value_factory_->NewBoolean(b), pos);
+    Literal* lit = new (zone_)
+        Literal(zone_, ast_value_factory_->NewBoolean(b), pos, id_gen_);
     VISIT_AND_RETURN(Literal, lit)
   }
 
   Literal* NewStringListLiteral(ZoneList<const AstRawString*>* strings,
                                 int pos) {
-    Literal* lit = new (zone_)
-        Literal(zone_, ast_value_factory_->NewStringList(strings), pos);
+    Literal* lit = new (zone_) Literal(
+        zone_, ast_value_factory_->NewStringList(strings), pos, id_gen_);
     VISIT_AND_RETURN(Literal, lit)
   }
 
   Literal* NewNullLiteral(int pos) {
     Literal* lit =
-        new (zone_) Literal(zone_, ast_value_factory_->NewNull(), pos);
+        new (zone_) Literal(zone_, ast_value_factory_->NewNull(), pos, id_gen_);
     VISIT_AND_RETURN(Literal, lit)
   }
 
   Literal* NewUndefinedLiteral(int pos) {
-    Literal* lit =
-        new (zone_) Literal(zone_, ast_value_factory_->NewUndefined(), pos);
+    Literal* lit = new (zone_)
+        Literal(zone_, ast_value_factory_->NewUndefined(), pos, id_gen_);
     VISIT_AND_RETURN(Literal, lit)
   }
 
   Literal* NewTheHoleLiteral(int pos) {
-    Literal* lit =
-        new (zone_) Literal(zone_, ast_value_factory_->NewTheHole(), pos);
+    Literal* lit = new (zone_)
+        Literal(zone_, ast_value_factory_->NewTheHole(), pos, id_gen_);
     VISIT_AND_RETURN(Literal, lit)
   }
 
@@ -3437,9 +3453,9 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
       int boilerplate_properties,
       bool has_function,
       int pos) {
-    ObjectLiteral* lit =
-        new (zone_) ObjectLiteral(zone_, properties, literal_index,
-                                  boilerplate_properties, has_function, pos);
+    ObjectLiteral* lit = new (zone_)
+        ObjectLiteral(zone_, properties, literal_index, boilerplate_properties,
+                      has_function, pos, id_gen_);
     VISIT_AND_RETURN(ObjectLiteral, lit)
   }
 
@@ -3463,8 +3479,8 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                                   const AstRawString* flags,
                                   int literal_index,
                                   int pos) {
-    RegExpLiteral* lit =
-        new (zone_) RegExpLiteral(zone_, pattern, flags, literal_index, pos);
+    RegExpLiteral* lit = new (zone_)
+        RegExpLiteral(zone_, pattern, flags, literal_index, pos, id_gen_);
     VISIT_AND_RETURN(RegExpLiteral, lit);
   }
 
@@ -3472,13 +3488,13 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                                 int literal_index,
                                 int pos) {
     ArrayLiteral* lit =
-        new (zone_) ArrayLiteral(zone_, values, literal_index, pos);
+        new (zone_) ArrayLiteral(zone_, values, literal_index, pos, id_gen_);
     VISIT_AND_RETURN(ArrayLiteral, lit)
   }
 
   VariableProxy* NewVariableProxy(Variable* var,
                                   int pos = RelocInfo::kNoPosition) {
-    VariableProxy* proxy = new (zone_) VariableProxy(zone_, var, pos);
+    VariableProxy* proxy = new (zone_) VariableProxy(zone_, var, pos, id_gen_);
     VISIT_AND_RETURN(VariableProxy, proxy)
   }
 
@@ -3486,27 +3502,28 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                                   bool is_this,
                                   Interface* interface = Interface::NewValue(),
                                   int position = RelocInfo::kNoPosition) {
-    VariableProxy* proxy =
-        new (zone_) VariableProxy(zone_, name, is_this, interface, position);
+    VariableProxy* proxy = new (zone_)
+        VariableProxy(zone_, name, is_this, interface, position, id_gen_);
     VISIT_AND_RETURN(VariableProxy, proxy)
   }
 
   Property* NewProperty(Expression* obj, Expression* key, int pos) {
-    Property* prop = new (zone_) Property(zone_, obj, key, pos);
+    Property* prop = new (zone_) Property(zone_, obj, key, pos, id_gen_);
     VISIT_AND_RETURN(Property, prop)
   }
 
   Call* NewCall(Expression* expression,
                 ZoneList<Expression*>* arguments,
                 int pos) {
-    Call* call = new (zone_) Call(zone_, expression, arguments, pos);
+    Call* call = new (zone_) Call(zone_, expression, arguments, pos, id_gen_);
     VISIT_AND_RETURN(Call, call)
   }
 
   CallNew* NewCallNew(Expression* expression,
                       ZoneList<Expression*>* arguments,
                       int pos) {
-    CallNew* call = new (zone_) CallNew(zone_, expression, arguments, pos);
+    CallNew* call =
+        new (zone_) CallNew(zone_, expression, arguments, pos, id_gen_);
     VISIT_AND_RETURN(CallNew, call)
   }
 
@@ -3515,7 +3532,7 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                               ZoneList<Expression*>* arguments,
                               int pos) {
     CallRuntime* call =
-        new (zone_) CallRuntime(zone_, name, function, arguments, pos);
+        new (zone_) CallRuntime(zone_, name, function, arguments, pos, id_gen_);
     VISIT_AND_RETURN(CallRuntime, call)
   }
 
@@ -3523,7 +3540,7 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                                     Expression* expression,
                                     int pos) {
     UnaryOperation* node =
-        new (zone_) UnaryOperation(zone_, op, expression, pos);
+        new (zone_) UnaryOperation(zone_, op, expression, pos, id_gen_);
     VISIT_AND_RETURN(UnaryOperation, node)
   }
 
@@ -3532,7 +3549,7 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                                       Expression* right,
                                       int pos) {
     BinaryOperation* node =
-        new (zone_) BinaryOperation(zone_, op, left, right, pos);
+        new (zone_) BinaryOperation(zone_, op, left, right, pos, id_gen_);
     VISIT_AND_RETURN(BinaryOperation, node)
   }
 
@@ -3541,7 +3558,7 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                                     Expression* expr,
                                     int pos) {
     CountOperation* node =
-        new (zone_) CountOperation(zone_, op, is_prefix, expr, pos);
+        new (zone_) CountOperation(zone_, op, is_prefix, expr, pos, id_gen_);
     VISIT_AND_RETURN(CountOperation, node)
   }
 
@@ -3550,7 +3567,7 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                                         Expression* right,
                                         int pos) {
     CompareOperation* node =
-        new (zone_) CompareOperation(zone_, op, left, right, pos);
+        new (zone_) CompareOperation(zone_, op, left, right, pos, id_gen_);
     VISIT_AND_RETURN(CompareOperation, node)
   }
 
@@ -3559,7 +3576,7 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                               Expression* else_expression,
                               int position) {
     Conditional* cond = new (zone_) Conditional(
-        zone_, condition, then_expression, else_expression, position);
+        zone_, condition, then_expression, else_expression, position, id_gen_);
     VISIT_AND_RETURN(Conditional, cond)
   }
 
@@ -3567,8 +3584,9 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                             Expression* target,
                             Expression* value,
                             int pos) {
-    Assignment* assign = new (zone_) Assignment(zone_, op, target, value, pos);
-    assign->Init(this);
+    Assignment* assign =
+        new (zone_) Assignment(zone_, op, target, value, pos, id_gen_);
+    assign->Init(zone_, this);
     VISIT_AND_RETURN(Assignment, assign)
   }
 
@@ -3577,13 +3595,13 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                   Yield::Kind yield_kind,
                   int pos) {
     if (!expression) expression = NewUndefinedLiteral(pos);
-    Yield* yield =
-        new (zone_) Yield(zone_, generator_object, expression, yield_kind, pos);
+    Yield* yield = new (zone_)
+        Yield(zone_, generator_object, expression, yield_kind, pos, id_gen_);
     VISIT_AND_RETURN(Yield, yield)
   }
 
   Throw* NewThrow(Expression* exception, int pos) {
-    Throw* t = new (zone_) Throw(zone_, exception, pos);
+    Throw* t = new (zone_) Throw(zone_, exception, pos, id_gen_);
     VISIT_AND_RETURN(Throw, t)
   }
 
@@ -3599,8 +3617,8 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
     FunctionLiteral* lit = new (zone_) FunctionLiteral(
         zone_, name, ast_value_factory, scope, body, materialized_literal_count,
         expected_property_count, handler_count, parameter_count, function_type,
-        has_duplicate_parameters, is_function, is_parenthesized, kind,
-        position);
+        has_duplicate_parameters, is_function, is_parenthesized, kind, position,
+        id_gen_);
     // Top-level literal doesn't count for the AST's properties.
     if (is_function == FunctionLiteral::kIsFunction) {
       visitor_.VisitFunctionLiteral(lit);
@@ -3614,7 +3632,7 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                                 int start_position, int end_position) {
     ClassLiteral* lit =
         new (zone_) ClassLiteral(zone_, name, extends, constructor, properties,
-                                 start_position, end_position);
+                                 start_position, end_position, id_gen_);
     VISIT_AND_RETURN(ClassLiteral, lit)
   }
 
@@ -3622,17 +3640,18 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
                                                   v8::Extension* extension,
                                                   int pos) {
     NativeFunctionLiteral* lit =
-        new (zone_) NativeFunctionLiteral(zone_, name, extension, pos);
+        new (zone_) NativeFunctionLiteral(zone_, name, extension, pos, id_gen_);
     VISIT_AND_RETURN(NativeFunctionLiteral, lit)
   }
 
   ThisFunction* NewThisFunction(int pos) {
-    ThisFunction* fun = new (zone_) ThisFunction(zone_, pos);
+    ThisFunction* fun = new (zone_) ThisFunction(zone_, pos, id_gen_);
     VISIT_AND_RETURN(ThisFunction, fun)
   }
 
   SuperReference* NewSuperReference(VariableProxy* this_var, int pos) {
-    SuperReference* super = new (zone_) SuperReference(zone_, this_var, pos);
+    SuperReference* super =
+        new (zone_) SuperReference(zone_, this_var, pos, id_gen_);
     VISIT_AND_RETURN(SuperReference, super);
   }
 
@@ -3642,6 +3661,7 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
   Zone* zone_;
   Visitor visitor_;
   AstValueFactory* ast_value_factory_;
+  AstNode::IdGen* id_gen_;
 };
 
 
index 8e94f76..0e6c3a3 100644 (file)
@@ -6,7 +6,6 @@
 
 #include "src/compiler.h"
 
-#include "src/ast-numbering.h"
 #include "src/bootstrapper.h"
 #include "src/codegen.h"
 #include "src/compilation-cache.h"
@@ -747,7 +746,6 @@ static bool CompileOptimizedPrologue(CompilationInfo* info) {
   if (!Parser::Parse(info)) return false;
   if (!Rewriter::Rewrite(info)) return false;
   if (!Scope::Analyze(info)) return false;
-  if (!AstNumbering::Renumber(info->function(), info->zone())) return false;
   DCHECK(info->scope() != NULL);
   return true;
 }
index 47579bd..4564b90 100644 (file)
@@ -391,6 +391,8 @@ class CompilationInfo {
     ast_value_factory_owned_ = owned;
   }
 
+  AstNode::IdGen* ast_node_id_gen() { return &ast_node_id_gen_; }
+
  protected:
   CompilationInfo(Handle<Script> script,
                   Zone* zone);
@@ -510,6 +512,7 @@ class CompilationInfo {
 
   AstValueFactory* ast_value_factory_;
   bool ast_value_factory_owned_;
+  AstNode::IdGen ast_node_id_gen_;
 
   // This flag is used by the main thread to track whether this compilation
   // should be abandoned due to dependency change.
index f4e6d40..f834602 100644 (file)
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/ast.h"
-#include "src/ast-numbering.h"
 #include "src/compiler/access-builder.h"
 #include "src/compiler/ast-graph-builder.h"
 #include "src/compiler/common-operator.h"
@@ -65,7 +63,6 @@ static void Parse(Handle<JSFunction> function, CompilationInfoWithZone* info) {
   CHECK(Parser::Parse(info));
   CHECK(Rewriter::Rewrite(info));
   CHECK(Scope::Analyze(info));
-  CHECK(AstNumbering::Renumber(info->function(), info->zone()));
   CHECK(Compiler::EnsureDeoptimizationSupport(info));
 }
 
index 9d31cd5..89ae329 100644 (file)
@@ -4,8 +4,6 @@
 
 #include "src/v8.h"
 
-#include "src/ast.h"
-#include "src/ast-numbering.h"
 #include "src/code-factory.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
@@ -308,11 +306,6 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
 
   TimerEventScope<TimerEventCompileFullCode> timer(info->isolate());
 
-  if (!AstNumbering::Renumber(info->function(), info->zone())) {
-    DCHECK(!isolate->has_pending_exception());
-    return false;
-  }
-
   Handle<Script> script = info->script();
   if (!script->IsUndefined() && !script->source()->IsUndefined()) {
     int len = String::cast(script->source())->length();
index 663bafb..3f9d32d 100644 (file)
@@ -9,7 +9,6 @@
 #include "src/v8.h"
 
 #include "src/allocation-site-scopes.h"
-#include "src/ast-numbering.h"
 #include "src/full-codegen.h"
 #include "src/hydrogen-bce.h"
 #include "src/hydrogen-bch.h"
@@ -7831,8 +7830,7 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
   // step, but don't transfer ownership to target_info.
   target_info.SetAstValueFactory(top_info()->ast_value_factory(), false);
   Handle<SharedFunctionInfo> target_shared(target->shared());
-  if (!Parser::Parse(&target_info) || !Scope::Analyze(&target_info) ||
-      !AstNumbering::Renumber(target_info.function(), target_info.zone())) {
+  if (!Parser::Parse(&target_info) || !Scope::Analyze(&target_info)) {
     if (target_info.isolate()->has_pending_exception()) {
       // Parse or scope error, never optimize this function.
       SetStackOverflow();
index bec0a4b..a972a62 100644 (file)
@@ -736,7 +736,8 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral(
 
 Parser::Parser(CompilationInfo* info, ParseInfo* parse_info)
     : ParserBase<ParserTraits>(&scanner_, parse_info->stack_limit,
-                               info->extension(), NULL, info->zone(), this),
+                               info->extension(), NULL, info->zone(),
+                               info->ast_node_id_gen(), this),
       scanner_(parse_info->unicode_cache),
       reusable_preparser_(NULL),
       original_scope_(NULL),
@@ -878,7 +879,7 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope,
 
     // Enters 'scope'.
     AstNodeFactory<AstConstructionVisitor> function_factory(
-        ast_value_factory());
+        zone(), ast_value_factory(), info->ast_node_id_gen());
     FunctionState function_state(&function_state_, &scope_, *scope,
                                  &function_factory);
 
@@ -993,7 +994,7 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
     }
     original_scope_ = scope;
     AstNodeFactory<AstConstructionVisitor> function_factory(
-        ast_value_factory());
+        zone(), ast_value_factory(), info()->ast_node_id_gen());
     FunctionState function_state(&function_state_, &scope_, scope,
                                  &function_factory);
     DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
@@ -3495,7 +3496,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
   // Parse function body.
   {
     AstNodeFactory<AstConstructionVisitor> function_factory(
-        ast_value_factory());
+        zone(), ast_value_factory(), info()->ast_node_id_gen());
     FunctionState function_state(&function_state_, &scope_, scope,
                                  &function_factory);
     scope_->SetScopeName(function_name);
index 987900a..a75ff30 100644 (file)
@@ -104,11 +104,11 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
   log_ = log;
   // Lazy functions always have trivial outer scopes (no with/catch scopes).
   PreParserScope top_scope(scope_, GLOBAL_SCOPE);
-  PreParserFactory top_factory(NULL);
+  PreParserFactory top_factory(NULL, NULL, NULL);
   FunctionState top_state(&function_state_, &scope_, &top_scope, &top_factory);
   scope_->SetStrictMode(strict_mode);
   PreParserScope function_scope(scope_, FUNCTION_SCOPE);
-  PreParserFactory function_factory(NULL);
+  PreParserFactory function_factory(NULL, NULL, NULL);
   FunctionState function_state(&function_state_, &scope_, &function_scope,
                                &function_factory);
   function_state.set_is_generator(is_generator);
@@ -813,7 +813,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
   // Parse function body.
   ScopeType outer_scope_type = scope_->type();
   PreParserScope function_scope(scope_, FUNCTION_SCOPE);
-  PreParserFactory factory(NULL);
+  PreParserFactory factory(NULL, NULL, NULL);
   FunctionState function_state(&function_state_, &scope_, &function_scope,
                                &factory);
   function_state.set_is_generator(IsGeneratorFunction(kind));
index fd82651..20bf9e9 100644 (file)
@@ -70,6 +70,7 @@ class ParserBase : public Traits {
 
   ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension,
              ParserRecorder* log, typename Traits::Type::Zone* zone,
+             AstNode::IdGen* ast_node_id_gen,
              typename Traits::Type::Parser this_object)
       : Traits(this_object),
         parenthesized_function_(false),
@@ -86,7 +87,8 @@ class ParserBase : public Traits {
         allow_natives_syntax_(false),
         allow_arrow_functions_(false),
         allow_harmony_object_literals_(false),
-        zone_(zone) {}
+        zone_(zone),
+        ast_node_id_gen_(ast_node_id_gen) {}
 
   // Getters that indicate whether certain syntactical constructs are
   // allowed to be parsed by this instance of the parser.
@@ -275,6 +277,7 @@ class ParserBase : public Traits {
   void set_stack_overflow() { stack_overflow_ = true; }
   Mode mode() const { return mode_; }
   typename Traits::Type::Zone* zone() const { return zone_; }
+  AstNode::IdGen* ast_node_id_gen() const { return ast_node_id_gen_; }
 
   INLINE(Token::Value peek()) {
     if (stack_overflow_) return Token::ILLEGAL;
@@ -577,6 +580,7 @@ class ParserBase : public Traits {
   bool allow_harmony_object_literals_;
 
   typename Traits::Type::Zone* zone_;  // Only used by Parser.
+  AstNode::IdGen* ast_node_id_gen_;
 };
 
 
@@ -968,7 +972,7 @@ class PreParserScope {
 
 class PreParserFactory {
  public:
-  explicit PreParserFactory(void* unused_value_factory) {}
+  PreParserFactory(void*, void*, void*) {}
   PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
                                        int pos) {
     return PreParserExpression::Default();
@@ -1413,7 +1417,7 @@ class PreParser : public ParserBase<PreParserTraits> {
   };
 
   PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
-      : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
+      : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, NULL,
                                     this) {}
 
   // Pre-parse the program from the character stream; returns true on
@@ -1422,7 +1426,7 @@ class PreParser : public ParserBase<PreParserTraits> {
   // during parsing.
   PreParseResult PreParseProgram() {
     PreParserScope scope(scope_, GLOBAL_SCOPE);
-    PreParserFactory factory(NULL);
+    PreParserFactory factory(NULL, NULL, NULL);
     FunctionState top_scope(&function_state_, &scope_, &scope, &factory);
     bool ok = true;
     int start_position = scanner()->peek_location().beg_pos;
@@ -2612,7 +2616,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<
   int handler_count = 0;
 
   {
-    typename Traits::Type::Factory function_factory(this->ast_value_factory());
+    typename Traits::Type::Factory function_factory(
+        zone(), this->ast_value_factory(), ast_node_id_gen_);
     FunctionState function_state(&function_state_, &scope_,
                                  Traits::Type::ptr_to_scope(scope),
                                  &function_factory);
index e870e90..8616960 100644 (file)
@@ -15,13 +15,15 @@ namespace internal {
 
 class Processor: public AstVisitor {
  public:
-  Processor(Variable* result, AstValueFactory* ast_value_factory)
+  Processor(Variable* result, Zone* zone, AstNode::IdGen* ast_node_id_gen)
       : result_(result),
         result_assigned_(false),
         is_set_(false),
         in_try_(false),
-        factory_(ast_value_factory) {
-    InitializeAstVisitor(ast_value_factory->zone());
+        // Passing a null AstValueFactory is fine, because Processor doesn't
+        // need to create strings or literals.
+        factory_(zone, NULL, ast_node_id_gen) {
+    InitializeAstVisitor(zone);
   }
 
   virtual ~Processor() { }
@@ -238,7 +240,7 @@ bool Rewriter::Rewrite(CompilationInfo* info) {
         scope->NewTemporary(info->ast_value_factory()->dot_result_string());
     // The name string must be internalized at this point.
     DCHECK(!result->name().is_null());
-    Processor processor(result, info->ast_value_factory());
+    Processor processor(result, info->zone(), info->ast_node_id_gen());
     processor.Process(body);
     if (processor.HasStackOverflow()) return false;
 
index 51c0065..fd803b3 100644 (file)
@@ -275,7 +275,8 @@ bool Scope::Analyze(CompilationInfo* info) {
 
   // Allocate the variables.
   {
-    AstNodeFactory<AstNullVisitor> ast_node_factory(info->ast_value_factory());
+    AstNodeFactory<AstNullVisitor> ast_node_factory(
+        info->zone(), info->ast_value_factory(), info->ast_node_id_gen());
     if (!top->AllocateVariables(info, &ast_node_factory)) return false;
   }
 
index 34c663f..a5a71a7 100644 (file)
@@ -8,7 +8,6 @@
 #include "src/v8.h"
 #include "test/cctest/cctest.h"
 
-#include "src/ast-numbering.h"
 #include "src/compiler.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/pipeline.h"
@@ -167,7 +166,6 @@ class FunctionTester : public InitializedHandleScope {
     }
     CHECK(Rewriter::Rewrite(&info));
     CHECK(Scope::Analyze(&info));
-    CHECK(AstNumbering::Renumber(info.function(), info.zone()));
     CHECK(Compiler::EnsureDeoptimizationSupport(&info));
 
     Pipeline pipeline(&info);
@@ -217,7 +215,6 @@ class FunctionTester : public InitializedHandleScope {
                        Handle<Code>(function->shared()->code()));
     CHECK(Rewriter::Rewrite(&info));
     CHECK(Scope::Analyze(&info));
-    CHECK(AstNumbering::Renumber(info.function(), info.zone()));
     CHECK(Compiler::EnsureDeoptimizationSupport(&info));
 
     Pipeline pipeline(&info);
index 0d2d5d1..3b5a737 100644 (file)
@@ -16,7 +16,6 @@
 #include "src/compiler/register-allocator.h"
 #include "src/compiler/schedule.h"
 
-#include "src/ast-numbering.h"
 #include "src/full-codegen.h"
 #include "src/parser.h"
 #include "src/rewriter.h"
@@ -49,7 +48,6 @@ class DeoptCodegenTester {
     info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
     CHECK(Rewriter::Rewrite(&info));
     CHECK(Scope::Analyze(&info));
-    CHECK(AstNumbering::Renumber(info.function(), info.zone()));
     CHECK(Compiler::EnsureDeoptimizationSupport(&info));
 
     DCHECK(info.shared_info()->has_deoptimization_support());
index 9d8a2d1..f0b750a 100644 (file)
@@ -5,7 +5,6 @@
 #include "src/v8.h"
 #include "test/cctest/cctest.h"
 
-#include "src/ast-numbering.h"
 #include "src/compiler.h"
 #include "src/compiler/pipeline.h"
 #include "src/handles.h"
@@ -26,7 +25,6 @@ TEST(PipelineAdd) {
   CHECK(Parser::Parse(&info));
   CHECK(Rewriter::Rewrite(&info));
   CHECK(Scope::Analyze(&info));
-  CHECK(AstNumbering::Renumber(info.function(), info.zone()));
   CHECK_NE(NULL, info.scope());
 
   Pipeline pipeline(&info);
index 31d5eba..24819df 100644 (file)
@@ -40,8 +40,8 @@ TEST(List) {
 
   Isolate* isolate = CcTest::i_isolate();
   Zone zone(isolate);
-  AstValueFactory value_factory(&zone, 0);
-  AstNodeFactory<AstNullVisitor> factory(&value_factory);
+  AstNode::IdGen id_gen;
+  AstNodeFactory<AstNullVisitor> factory(&zone, NULL, &id_gen);
   AstNode* node = factory.NewEmptyStatement(RelocInfo::kNoPosition);
   list->Add(node);
   CHECK_EQ(1, list->length());
index 700d104..d33d037 100644 (file)
@@ -31,8 +31,6 @@
 
 #include "src/v8.h"
 
-#include "src/ast.h"
-#include "src/ast-numbering.h"
 #include "src/ast-value-factory.h"
 #include "src/compiler.h"
 #include "src/execution.h"
@@ -3275,7 +3273,6 @@ TEST(InnerAssignment) {
           CHECK(parser.Parse());
           CHECK(i::Rewriter::Rewrite(&info));
           CHECK(i::Scope::Analyze(&info));
-          CHECK(i::AstNumbering::Renumber(info.function(), info.zone()));
           CHECK(info.function() != NULL);
 
           i::Scope* scope = info.function()->scope();
index 57296e7..b8317cb 100644 (file)
         '../../src/assert-scope.cc',
         '../../src/ast-value-factory.cc',
         '../../src/ast-value-factory.h',
-        '../../src/ast-numbering.cc',
-        '../../src/ast-numbering.h',
         '../../src/ast.cc',
         '../../src/ast.h',
         '../../src/background-parsing-task.cc',