Drop computed handler count and index from AST.
authormstarzinger <mstarzinger@chromium.org>
Mon, 8 Jun 2015 18:19:32 +0000 (11:19 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 8 Jun 2015 18:19:40 +0000 (18:19 +0000)
These values were computed by the parser and hence out of sync with any
visitor over the AST. Our AST visitor aborts visitation of statement
lists as soon as a jump statement has been reached. Now handler tables
are guaranteed to be dense and fully populated.

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

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

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

14 files changed:
src/arm/full-codegen-arm.cc
src/arm64/full-codegen-arm64.cc
src/ast.h
src/full-codegen.cc
src/full-codegen.h
src/ia32/full-codegen-ia32.cc
src/mips/full-codegen-mips.cc
src/mips64/full-codegen-mips64.cc
src/parser.cc
src/ppc/full-codegen-ppc.cc
src/preparser.h
src/x64/full-codegen-x64.cc
src/x87/full-codegen-x87.cc
test/mjsunit/regress/regress-crbug-493290.js [new file with mode: 0644]

index 95f3c8c0615af6a1aad13c21ecb5afcaba770f2f..9a01faddc1f42738518b1dcac7b70d6d8f04562b 100644 (file)
@@ -105,10 +105,6 @@ class JumpPatchSite BASE_EMBEDDED {
 // frames-arm.h for its layout.
 void FullCodeGenerator::Generate() {
   CompilationInfo* info = info_;
-  handler_table_ =
-      Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
-          HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -2207,7 +2203,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       // re-boxing.
       __ bind(&l_try);
       __ pop(r0);                                        // result
-      EnterTryBlock(expr->index(), &l_catch);
+      int handler_index = NewHandlerTableEntry();
+      EnterTryBlock(handler_index, &l_catch);
       const int try_block_size = TryCatch::kElementCount * kPointerSize;
       __ push(r0);                                       // result
       __ jmp(&l_suspend);
@@ -2217,7 +2214,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       const int generator_object_depth = kPointerSize + try_block_size;
       __ ldr(r0, MemOperand(sp, generator_object_depth));
       __ push(r0);                                       // g
-      __ Push(Smi::FromInt(expr->index()));              // handler-index
+      __ Push(Smi::FromInt(handler_index));              // handler-index
       DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
       __ mov(r1, Operand(Smi::FromInt(l_continuation.pos())));
       __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset));
@@ -2230,7 +2227,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       __ pop(r0);                                      // result
       EmitReturnSequence();
       __ bind(&l_resume);                              // received in r0
-      ExitTryBlock(expr->index());
+      ExitTryBlock(handler_index);
 
       // receiver = iter; f = 'next'; arg = received;
       __ bind(&l_next);
index cdc615ea5a2c1e81affebbea57cb01f104d41a3d..90b57784d9eb75708bd45229ee63f3874c0ef067 100644 (file)
@@ -103,10 +103,6 @@ class JumpPatchSite BASE_EMBEDDED {
 // frames-arm.h for its layout.
 void FullCodeGenerator::Generate() {
   CompilationInfo* info = info_;
-  handler_table_ =
-      Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
-          HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -5141,7 +5137,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       // re-boxing.
       __ Bind(&l_try);
       __ Pop(x0);                                        // result
-      EnterTryBlock(expr->index(), &l_catch);
+      int handler_index = NewHandlerTableEntry();
+      EnterTryBlock(handler_index, &l_catch);
       const int try_block_size = TryCatch::kElementCount * kPointerSize;
       __ Push(x0);                                       // result
       __ B(&l_suspend);
@@ -5156,7 +5153,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       const int generator_object_depth = kPointerSize + try_block_size;
       __ Peek(x0, generator_object_depth);
       __ Push(x0);                                       // g
-      __ Push(Smi::FromInt(expr->index()));              // handler-index
+      __ Push(Smi::FromInt(handler_index));              // handler-index
       DCHECK((l_continuation.pos() > 0) && Smi::IsValid(l_continuation.pos()));
       __ Mov(x1, Smi::FromInt(l_continuation.pos()));
       __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset));
@@ -5169,7 +5166,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       __ Pop(x0);                                        // result
       EmitReturnSequence();
       __ Bind(&l_resume);                                // received in x0
-      ExitTryBlock(expr->index());
+      ExitTryBlock(handler_index);
 
       // receiver = iter; f = 'next'; arg = received;
       __ Bind(&l_next);
index 73b06631e49c8312ed4435a59735222a0a3ad017..01154d37628a9f8518497f8428c8523922db54be 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1161,17 +1161,13 @@ class IfStatement final : public Statement {
 
 class TryStatement : public Statement {
  public:
-  int index() const { return index_; }
   Block* try_block() const { return try_block_; }
 
  protected:
-  TryStatement(Zone* zone, int index, Block* try_block, int pos)
-      : Statement(zone, pos), index_(index), try_block_(try_block) {}
+  TryStatement(Zone* zone, Block* try_block, int pos)
+      : Statement(zone, pos), try_block_(try_block) {}
 
  private:
-  // Unique (per-function) index of this handler.  This is not an AST ID.
-  int index_;
-
   Block* try_block_;
 };
 
@@ -1185,18 +1181,12 @@ class TryCatchStatement final : public TryStatement {
   Block* catch_block() const { return catch_block_; }
 
  protected:
-  TryCatchStatement(Zone* zone,
-                    int index,
-                    Block* try_block,
-                    Scope* scope,
-                    Variable* variable,
-                    Block* catch_block,
-                    int pos)
-      : TryStatement(zone, index, try_block, pos),
+  TryCatchStatement(Zone* zone, Block* try_block, Scope* scope,
+                    Variable* variable, Block* catch_block, int pos)
+      : TryStatement(zone, try_block, pos),
         scope_(scope),
         variable_(variable),
-        catch_block_(catch_block) {
-  }
+        catch_block_(catch_block) {}
 
  private:
   Scope* scope_;
@@ -1212,10 +1202,9 @@ class TryFinallyStatement final : public TryStatement {
   Block* finally_block() const { return finally_block_; }
 
  protected:
-  TryFinallyStatement(
-      Zone* zone, int index, Block* try_block, Block* finally_block, int pos)
-      : TryStatement(zone, index, try_block, pos),
-        finally_block_(finally_block) { }
+  TryFinallyStatement(Zone* zone, Block* try_block, Block* finally_block,
+                      int pos)
+      : TryStatement(zone, try_block, pos), finally_block_(finally_block) {}
 
  private:
   Block* finally_block_;
@@ -2405,18 +2394,6 @@ class Yield final : public Expression {
   Expression* expression() const { return expression_; }
   Kind yield_kind() const { return yield_kind_; }
 
-  // Delegating yield surrounds the "yield" in a "try/catch".  This index
-  // locates the catch handler in the handler table, and is equivalent to
-  // TryCatchStatement::index().
-  int index() const {
-    DCHECK_EQ(kDelegating, yield_kind());
-    return index_;
-  }
-  void set_index(int index) {
-    DCHECK_EQ(kDelegating, yield_kind());
-    index_ = index;
-  }
-
   // Type feedback information.
   bool HasFeedbackSlots() const { return yield_kind() == kDelegating; }
   virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
@@ -2449,14 +2426,12 @@ class Yield final : public Expression {
         generator_object_(generator_object),
         expression_(expression),
         yield_kind_(yield_kind),
-        index_(-1),
         yield_first_feedback_slot_(FeedbackVectorICSlot::Invalid()) {}
 
  private:
   Expression* generator_object_;
   Expression* expression_;
   Kind yield_kind_;
-  int index_;
   FeedbackVectorICSlot yield_first_feedback_slot_;
 };
 
@@ -2523,7 +2498,6 @@ class FunctionLiteral final : public Expression {
 
   int materialized_literal_count() { return materialized_literal_count_; }
   int expected_property_count() { return expected_property_count_; }
-  int handler_count() { return handler_count_; }
   int parameter_count() { return parameter_count_; }
 
   bool AllowsLazyCompilation();
@@ -2618,8 +2592,8 @@ class FunctionLiteral final : public Expression {
   FunctionLiteral(Zone* zone, const AstRawString* name,
                   AstValueFactory* ast_value_factory, Scope* scope,
                   ZoneList<Statement*>* body, int materialized_literal_count,
-                  int expected_property_count, int handler_count,
-                  int parameter_count, FunctionType function_type,
+                  int expected_property_count, int parameter_count,
+                  FunctionType function_type,
                   ParameterFlag has_duplicate_parameters,
                   IsFunctionFlag is_function,
                   EagerCompileHint eager_compile_hint, FunctionKind kind,
@@ -2633,7 +2607,6 @@ class FunctionLiteral final : public Expression {
         dont_optimize_reason_(kNoReason),
         materialized_literal_count_(materialized_literal_count),
         expected_property_count_(expected_property_count),
-        handler_count_(handler_count),
         parameter_count_(parameter_count),
         function_token_position_(RelocInfo::kNoPosition) {
     bitfield_ = IsExpression::encode(function_type != DECLARATION) |
@@ -2660,7 +2633,6 @@ class FunctionLiteral final : public Expression {
 
   int materialized_literal_count_;
   int expected_property_count_;
-  int handler_count_;
   int parameter_count_;
   int function_token_position_;
 
@@ -3360,22 +3332,17 @@ class AstNodeFactory final BASE_EMBEDDED {
         IfStatement(zone_, condition, then_statement, else_statement, pos);
   }
 
-  TryCatchStatement* NewTryCatchStatement(int index,
-                                          Block* try_block,
-                                          Scope* scope,
+  TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
                                           Variable* variable,
-                                          Block* catch_block,
-                                          int pos) {
-    return new (zone_) TryCatchStatement(zone_, index, try_block, scope,
-                                         variable, catch_block, pos);
+                                          Block* catch_block, int pos) {
+    return new (zone_)
+        TryCatchStatement(zone_, try_block, scope, variable, catch_block, pos);
   }
 
-  TryFinallyStatement* NewTryFinallyStatement(int index,
-                                              Block* try_block,
-                                              Block* finally_block,
-                                              int pos) {
+  TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
+                                              Block* finally_block, int pos) {
     return new (zone_)
-        TryFinallyStatement(zone_, index, try_block, finally_block, pos);
+        TryFinallyStatement(zone_, try_block, finally_block, pos);
   }
 
   DebuggerStatement* NewDebuggerStatement(int pos) {
@@ -3577,7 +3544,7 @@ class AstNodeFactory final BASE_EMBEDDED {
   FunctionLiteral* NewFunctionLiteral(
       const AstRawString* name, AstValueFactory* ast_value_factory,
       Scope* scope, ZoneList<Statement*>* body, int materialized_literal_count,
-      int expected_property_count, int handler_count, int parameter_count,
+      int expected_property_count, int parameter_count,
       FunctionLiteral::ParameterFlag has_duplicate_parameters,
       FunctionLiteral::FunctionType function_type,
       FunctionLiteral::IsFunctionFlag is_function,
@@ -3585,7 +3552,7 @@ class AstNodeFactory final BASE_EMBEDDED {
       int position) {
     return new (zone_) FunctionLiteral(
         zone_, name, ast_value_factory, scope, body, materialized_literal_count,
-        expected_property_count, handler_count, parameter_count, function_type,
+        expected_property_count, parameter_count, function_type,
         has_duplicate_parameters, is_function, eager_compile_hint, kind,
         position);
   }
index 5103f3ac89de75f49fd18a3823a4848a33da3601..16f0b55780bb88d52a743fd79191dc26d4befedc 100644 (file)
@@ -319,9 +319,9 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
   Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
   cgen.PopulateDeoptimizationData(code);
   cgen.PopulateTypeFeedbackInfo(code);
+  cgen.PopulateHandlerTable(code);
   code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
   code->set_has_reloc_info_for_serialization(info->will_serialize());
-  code->set_handler_table(*cgen.handler_table());
   code->set_compiled_optimizable(info->IsOptimizable());
   code->set_allow_osr_at_loop_nesting_level(0);
   code->set_profiler_ticks(0);
@@ -401,6 +401,32 @@ void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
 }
 
 
+void FullCodeGenerator::PopulateHandlerTable(Handle<Code> code) {
+  int handler_table_size = static_cast<int>(handler_table_.size());
+  Handle<HandlerTable> table =
+      Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
+          HandlerTable::LengthForRange(handler_table_size), TENURED));
+  for (int i = 0; i < handler_table_size; ++i) {
+    HandlerTable::CatchPrediction prediction =
+        handler_table_[i].try_catch_depth > 0 ? HandlerTable::CAUGHT
+                                              : HandlerTable::UNCAUGHT;
+    table->SetRangeStart(i, handler_table_[i].range_start);
+    table->SetRangeEnd(i, handler_table_[i].range_end);
+    table->SetRangeHandler(i, handler_table_[i].handler_offset, prediction);
+    table->SetRangeDepth(i, handler_table_[i].stack_depth);
+  }
+  code->set_handler_table(*table);
+}
+
+
+int FullCodeGenerator::NewHandlerTableEntry() {
+  int index = static_cast<int>(handler_table_.size());
+  HandlerTableEntry entry = {0, 0, 0, 0, 0};
+  handler_table_.push_back(entry);
+  return index;
+}
+
+
 bool FullCodeGenerator::MustCreateObjectLiteralWithRuntime(
     ObjectLiteral* expr) const {
   int literal_flags = expr->ComputeFlags();
@@ -1229,11 +1255,12 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
   __ bind(&try_entry);
 
   try_catch_depth_++;
-  EnterTryBlock(stmt->index(), &handler_entry);
+  int handler_index = NewHandlerTableEntry();
+  EnterTryBlock(handler_index, &handler_entry);
   { TryCatch try_body(this);
     Visit(stmt->try_block());
   }
-  ExitTryBlock(stmt->index());
+  ExitTryBlock(handler_index);
   try_catch_depth_--;
   __ bind(&exit);
 }
@@ -1286,11 +1313,12 @@ void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
 
   // Set up try handler.
   __ bind(&try_entry);
-  EnterTryBlock(stmt->index(), &handler_entry);
+  int handler_index = NewHandlerTableEntry();
+  EnterTryBlock(handler_index, &handler_entry);
   { TryFinally try_body(this, &finally_entry);
     Visit(stmt->try_block());
   }
-  ExitTryBlock(stmt->index());
+  ExitTryBlock(handler_index);
   // Execute the finally block on the way out.  Clobber the unpredictable
   // value in the result register with one that's safe for GC because the
   // finally block will unconditionally preserve the result register on the
@@ -1451,18 +1479,18 @@ void FullCodeGenerator::VisitThrow(Throw* expr) {
 }
 
 
-void FullCodeGenerator::EnterTryBlock(int index, Label* handler) {
-  handler_table()->SetRangeStart(index, masm()->pc_offset());
-  HandlerTable::CatchPrediction prediction =
-      try_catch_depth_ > 0 ? HandlerTable::CAUGHT : HandlerTable::UNCAUGHT;
-  handler_table()->SetRangeHandler(index, handler->pos(), prediction);
+void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) {
+  HandlerTableEntry* entry = &handler_table_[handler_index];
+  entry->range_start = masm()->pc_offset();
+  entry->handler_offset = handler->pos();
+  entry->try_catch_depth = try_catch_depth_;
 
   // Determine expression stack depth of try statement.
   int stack_depth = info_->scope()->num_stack_slots();  // Include stack locals.
   for (NestedStatement* current = nesting_stack_; current != NULL; /*nop*/) {
     current = current->AccumulateDepth(&stack_depth);
   }
-  handler_table()->SetRangeDepth(index, stack_depth);
+  entry->stack_depth = stack_depth;
 
   // Push context onto operand stack.
   STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
@@ -1470,8 +1498,9 @@ void FullCodeGenerator::EnterTryBlock(int index, Label* handler) {
 }
 
 
-void FullCodeGenerator::ExitTryBlock(int index) {
-  handler_table()->SetRangeEnd(index, masm()->pc_offset());
+void FullCodeGenerator::ExitTryBlock(int handler_index) {
+  HandlerTableEntry* entry = &handler_table_[handler_index];
+  entry->range_end = masm()->pc_offset();
 
   // Drop context from operand stack.
   __ Drop(TryBlockConstant::kElementCount);
index ef4bf1f15f6cec7e6aaeff9552d3a2edaba7d673..ecab4f9bc0060c3553064bed70f3f9eb72aa8e04 100644 (file)
@@ -77,6 +77,7 @@ class FullCodeGenerator: public AstVisitor {
                              : 0,
                          info->zone()),
         back_edges_(2, info->zone()),
+        handler_table_(info->zone()),
         ic_total_count_(0) {
     DCHECK(!info->IsStub());
     Initialize();
@@ -750,13 +751,14 @@ class FullCodeGenerator: public AstVisitor {
   void Generate();
   void PopulateDeoptimizationData(Handle<Code> code);
   void PopulateTypeFeedbackInfo(Handle<Code> code);
+  void PopulateHandlerTable(Handle<Code> code);
 
   bool MustCreateObjectLiteralWithRuntime(ObjectLiteral* expr) const;
   bool MustCreateArrayLiteralWithRuntime(ArrayLiteral* expr) const;
 
   void EmitLoadStoreICSlot(FeedbackVectorICSlot slot);
 
-  Handle<HandlerTable> handler_table() { return handler_table_; }
+  int NewHandlerTableEntry();
 
   struct BailoutEntry {
     BailoutId id;
@@ -769,6 +771,14 @@ class FullCodeGenerator: public AstVisitor {
     uint32_t loop_depth;
   };
 
+  struct HandlerTableEntry {
+    unsigned range_start;
+    unsigned range_end;
+    unsigned handler_offset;
+    int stack_depth;
+    int try_catch_depth;
+  };
+
   class ExpressionContext BASE_EMBEDDED {
    public:
     explicit ExpressionContext(FullCodeGenerator* codegen)
@@ -974,8 +984,8 @@ class FullCodeGenerator: public AstVisitor {
   const ExpressionContext* context_;
   ZoneList<BailoutEntry> bailout_entries_;
   ZoneList<BackEdgeEntry> back_edges_;
+  ZoneVector<HandlerTableEntry> handler_table_;
   int ic_total_count_;
-  Handle<HandlerTable> handler_table_;
   Handle<Cell> profiling_counter_;
   bool generate_debug_code_;
 
index 6a1d82078177de137f699fef083d30835e12f6f5..40d54a6d691dadede991e5ac253e9aa32d025072 100644 (file)
@@ -93,10 +93,6 @@ class JumpPatchSite BASE_EMBEDDED {
 // frames-ia32.h for its layout.
 void FullCodeGenerator::Generate() {
   CompilationInfo* info = info_;
-  handler_table_ =
-      Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
-          HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -2130,7 +2126,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       // re-boxing.
       __ bind(&l_try);
       __ pop(eax);                                       // result
-      EnterTryBlock(expr->index(), &l_catch);
+      int handler_index = NewHandlerTableEntry();
+      EnterTryBlock(handler_index, &l_catch);
       const int try_block_size = TryCatch::kElementCount * kPointerSize;
       __ push(eax);                                      // result
       __ jmp(&l_suspend);
@@ -2140,7 +2137,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       const int generator_object_depth = kPointerSize + try_block_size;
       __ mov(eax, Operand(esp, generator_object_depth));
       __ push(eax);                                      // g
-      __ push(Immediate(Smi::FromInt(expr->index())));   // handler-index
+      __ push(Immediate(Smi::FromInt(handler_index)));   // handler-index
       DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
       __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset),
              Immediate(Smi::FromInt(l_continuation.pos())));
@@ -2154,7 +2151,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       __ pop(eax);                                       // result
       EmitReturnSequence();
       __ bind(&l_resume);                                // received in eax
-      ExitTryBlock(expr->index());
+      ExitTryBlock(handler_index);
 
       // receiver = iter; f = iter.next; arg = received;
       __ bind(&l_next);
index a3f04194a36e6cd0f2ab4d73b5868ec361457f4d..b7d161193c6ff1ecc693edcf0f1d700a7c5254d5 100644 (file)
@@ -113,10 +113,6 @@ class JumpPatchSite BASE_EMBEDDED {
 // frames-mips.h for its layout.
 void FullCodeGenerator::Generate() {
   CompilationInfo* info = info_;
-  handler_table_ =
-      Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
-          HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -2192,7 +2188,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       // re-boxing.
       __ bind(&l_try);
       __ pop(a0);                                        // result
-      EnterTryBlock(expr->index(), &l_catch);
+      int handler_index = NewHandlerTableEntry();
+      EnterTryBlock(handler_index, &l_catch);
       const int try_block_size = TryCatch::kElementCount * kPointerSize;
       __ push(a0);                                       // result
       __ jmp(&l_suspend);
@@ -2203,7 +2200,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       const int generator_object_depth = kPointerSize + try_block_size;
       __ lw(a0, MemOperand(sp, generator_object_depth));
       __ push(a0);                                       // g
-      __ Push(Smi::FromInt(expr->index()));              // handler-index
+      __ Push(Smi::FromInt(handler_index));              // handler-index
       DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
       __ li(a1, Operand(Smi::FromInt(l_continuation.pos())));
       __ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset));
@@ -2217,7 +2214,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       EmitReturnSequence();
       __ mov(a0, v0);
       __ bind(&l_resume);                              // received in a0
-      ExitTryBlock(expr->index());
+      ExitTryBlock(handler_index);
 
       // receiver = iter; f = 'next'; arg = received;
       __ bind(&l_next);
index 02f25c509481c14960a5278780366360d8e98dd4..4f5139b129dd9ac39d51a70d7fddb9d7547d35ca 100644 (file)
@@ -113,10 +113,6 @@ class JumpPatchSite BASE_EMBEDDED {
 // frames-mips.h for its layout.
 void FullCodeGenerator::Generate() {
   CompilationInfo* info = info_;
-  handler_table_ =
-      Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
-          HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -2190,7 +2186,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       // re-boxing.
       __ bind(&l_try);
       __ pop(a0);                                        // result
-      EnterTryBlock(expr->index(), &l_catch);
+      int handler_index = NewHandlerTableEntry();
+      EnterTryBlock(handler_index, &l_catch);
       const int try_block_size = TryCatch::kElementCount * kPointerSize;
       __ push(a0);                                       // result
       __ jmp(&l_suspend);
@@ -2201,7 +2198,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       const int generator_object_depth = kPointerSize + try_block_size;
       __ ld(a0, MemOperand(sp, generator_object_depth));
       __ push(a0);                                       // g
-      __ Push(Smi::FromInt(expr->index()));              // handler-index
+      __ Push(Smi::FromInt(handler_index));              // handler-index
       DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
       __ li(a1, Operand(Smi::FromInt(l_continuation.pos())));
       __ sd(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset));
@@ -2215,7 +2212,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       EmitReturnSequence();
       __ mov(a0, v0);
       __ bind(&l_resume);                              // received in a0
-      ExitTryBlock(expr->index());
+      ExitTryBlock(handler_index);
 
       // receiver = iter; f = 'next'; arg = received;
       __ bind(&l_next);
index 75bfbe25ab84611b2a14a95be4f098cd17073728..28dcf1eb32e5240e2ecba7dfa4571e14287a91f0 100644 (file)
@@ -336,7 +336,6 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
                                             int pos, int end_pos) {
   int materialized_literal_count = -1;
   int expected_property_count = -1;
-  int handler_count = 0;
   int parameter_count = 0;
   const AstRawString* name = ast_value_factory()->empty_string();
 
@@ -379,13 +378,12 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
 
     materialized_literal_count = function_state.materialized_literal_count();
     expected_property_count = function_state.expected_property_count();
-    handler_count = function_state.handler_count();
   }
 
   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
       name, ast_value_factory(), function_scope, body,
-      materialized_literal_count, expected_property_count, handler_count,
-      parameter_count, FunctionLiteral::kNoDuplicateParameters,
+      materialized_literal_count, expected_property_count, parameter_count,
+      FunctionLiteral::kNoDuplicateParameters,
       FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
       FunctionLiteral::kShouldLazyCompile, kind, pos);
 
@@ -1070,8 +1068,7 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
       result = factory()->NewFunctionLiteral(
           ast_value_factory()->empty_string(), ast_value_factory(), scope_,
           body, function_state.materialized_literal_count(),
-          function_state.expected_property_count(),
-          function_state.handler_count(), 0,
+          function_state.expected_property_count(), 0,
           FunctionLiteral::kNoDuplicateParameters,
           FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
           FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction,
@@ -3020,10 +3017,9 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
   if (catch_block != NULL && finally_block != NULL) {
     // If we have both, create an inner try/catch.
     DCHECK(catch_scope != NULL && catch_variable != NULL);
-    int index = function_state_->NextHandlerIndex();
-    TryCatchStatement* statement = factory()->NewTryCatchStatement(
-        index, try_block, catch_scope, catch_variable, catch_block,
-        RelocInfo::kNoPosition);
+    TryCatchStatement* statement =
+        factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable,
+                                        catch_block, RelocInfo::kNoPosition);
     try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
     try_block->AddStatement(statement, zone());
     catch_block = NULL;  // Clear to indicate it's been handled.
@@ -3033,14 +3029,11 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
   if (catch_block != NULL) {
     DCHECK(finally_block == NULL);
     DCHECK(catch_scope != NULL && catch_variable != NULL);
-    int index = function_state_->NextHandlerIndex();
-    result = factory()->NewTryCatchStatement(
-        index, try_block, catch_scope, catch_variable, catch_block, pos);
+    result = factory()->NewTryCatchStatement(try_block, catch_scope,
+                                             catch_variable, catch_block, pos);
   } else {
     DCHECK(finally_block != NULL);
-    int index = function_state_->NextHandlerIndex();
-    result = factory()->NewTryFinallyStatement(
-        index, try_block, finally_block, pos);
+    result = factory()->NewTryFinallyStatement(try_block, finally_block, pos);
   }
 
   return result;
@@ -3883,7 +3876,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
   ZoneList<Statement*>* body = NULL;
   int materialized_literal_count = -1;
   int expected_property_count = -1;
-  int handler_count = 0;
   ExpressionClassifier formals_classifier;
   FunctionLiteral::EagerCompileHint eager_compile_hint =
       parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile
@@ -4020,7 +4012,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
                                     kind, CHECK_OK);
       materialized_literal_count = function_state.materialized_literal_count();
       expected_property_count = function_state.expected_property_count();
-      handler_count = function_state.handler_count();
 
       if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
         if (!function_state.super_location().IsValid()) {
@@ -4059,9 +4050,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
 
   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
       function_name, ast_value_factory(), scope, body,
-      materialized_literal_count, expected_property_count, handler_count,
-      num_parameters, duplicate_parameters, function_type,
-      FunctionLiteral::kIsFunction, eager_compile_hint, kind, pos);
+      materialized_literal_count, expected_property_count, num_parameters,
+      duplicate_parameters, function_type, FunctionLiteral::kIsFunction,
+      eager_compile_hint, kind, pos);
   function_literal->set_function_token_position(function_token_pos);
   if (should_be_used_once_hint)
     function_literal->set_should_be_used_once_hint();
index f6931f9e4dd687a414a27e7e01a3e8c293a770f5..db7c40150e964261852d4c7e19e6e21152b343a9 100644 (file)
@@ -102,10 +102,6 @@ class JumpPatchSite BASE_EMBEDDED {
 // frames-ppc.h for its layout.
 void FullCodeGenerator::Generate() {
   CompilationInfo* info = info_;
-  handler_table_ =
-      Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
-          HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -2164,7 +2160,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       // re-boxing.
       __ bind(&l_try);
       __ pop(r3);  // result
-      EnterTryBlock(expr->index(), &l_catch);
+      int handler_index = NewHandlerTableEntry();
+      EnterTryBlock(handler_index, &l_catch);
       const int try_block_size = TryCatch::kElementCount * kPointerSize;
       __ push(r3);  // result
       __ b(&l_suspend);
@@ -2174,7 +2171,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       const int generator_object_depth = kPointerSize + try_block_size;
       __ LoadP(r3, MemOperand(sp, generator_object_depth));
       __ push(r3);  // g
-      __ Push(Smi::FromInt(expr->index()));  // handler-index
+      __ Push(Smi::FromInt(handler_index));  // handler-index
       DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
       __ LoadSmiLiteral(r4, Smi::FromInt(l_continuation.pos()));
       __ StoreP(r4, FieldMemOperand(r3, JSGeneratorObject::kContinuationOffset),
@@ -2188,7 +2185,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       __ pop(r3);  // result
       EmitReturnSequence();
       __ bind(&l_resume);  // received in r3
-      ExitTryBlock(expr->index());
+      ExitTryBlock(handler_index);
 
       // receiver = iter; f = 'next'; arg = received;
       __ bind(&l_next);
index 7a68e835ff2870e5397c2be37f7f17acb4fed00f..b89263229fe372368d3dcd9f20e7313f3fab9aa5 100644 (file)
@@ -221,9 +221,6 @@ class ParserBase : public Traits {
       return next_materialized_literal_index_;
     }
 
-    int NextHandlerIndex() { return next_handler_index_++; }
-    int handler_count() { return next_handler_index_; }
-
     void AddProperty() { expected_property_count_++; }
     int expected_property_count() { return expected_property_count_; }
 
@@ -264,9 +261,6 @@ class ParserBase : public Traits {
     // array literals.
     int next_materialized_literal_index_;
 
-    // Used to assign a per-function index to try and catch handlers.
-    int next_handler_index_;
-
     // Properties count estimation.
     int expected_property_count_;
 
@@ -305,21 +299,18 @@ class ParserBase : public Traits {
       function_state_ = parser->function_state_;
       next_materialized_literal_index_ =
           function_state_->next_materialized_literal_index_;
-      next_handler_index_ = function_state_->next_handler_index_;
       expected_property_count_ = function_state_->expected_property_count_;
     }
 
     void Restore() {
       function_state_->next_materialized_literal_index_ =
           next_materialized_literal_index_;
-      function_state_->next_handler_index_ = next_handler_index_;
       function_state_->expected_property_count_ = expected_property_count_;
     }
 
    private:
     FunctionState* function_state_;
     int next_materialized_literal_index_;
-    int next_handler_index_;
     int expected_property_count_;
   };
 
@@ -1487,7 +1478,7 @@ class PreParserFactory {
   PreParserExpression NewFunctionLiteral(
       PreParserIdentifier name, AstValueFactory* ast_value_factory,
       Scope* scope, PreParserStatementList body, int materialized_literal_count,
-      int expected_property_count, int handler_count, int parameter_count,
+      int expected_property_count, int parameter_count,
       FunctionLiteral::ParameterFlag has_duplicate_parameters,
       FunctionLiteral::FunctionType function_type,
       FunctionLiteral::IsFunctionFlag is_function,
@@ -2046,7 +2037,6 @@ ParserBase<Traits>::FunctionState::FunctionState(
     FunctionState** function_state_stack, Scope** scope_stack, Scope* scope,
     FunctionKind kind, typename Traits::Type::Factory* factory)
     : next_materialized_literal_index_(0),
-      next_handler_index_(0),
       expected_property_count_(0),
       this_location_(Scanner::Location::invalid()),
       return_location_(Scanner::Location::invalid()),
@@ -3055,9 +3045,6 @@ ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
   }
   typename Traits::Type::YieldExpression yield =
       factory()->NewYield(generator_object, expression, kind, pos);
-  if (kind == Yield::kDelegating) {
-    yield->set_index(function_state_->NextHandlerIndex());
-  }
   return yield;
 }
 
@@ -3785,7 +3772,6 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
   int num_parameters = scope->num_parameters();
   int materialized_literal_count = -1;
   int expected_property_count = -1;
-  int handler_count = 0;
   Scanner::Location super_loc;
 
   {
@@ -3811,7 +3797,6 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
         materialized_literal_count =
             function_state.materialized_literal_count();
         expected_property_count = function_state.expected_property_count();
-        handler_count = function_state.handler_count();
       }
     } else {
       // Single-expression body
@@ -3825,7 +3810,6 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
       body->Add(factory()->NewReturnStatement(expression, pos), zone());
       materialized_literal_count = function_state.materialized_literal_count();
       expected_property_count = function_state.expected_property_count();
-      handler_count = function_state.handler_count();
     }
     super_loc = function_state.super_location();
 
@@ -3849,8 +3833,8 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
 
   FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
       this->EmptyIdentifierString(), ast_value_factory(), scope, body,
-      materialized_literal_count, expected_property_count, handler_count,
-      num_parameters, FunctionLiteral::kNoDuplicateParameters,
+      materialized_literal_count, expected_property_count, num_parameters,
+      FunctionLiteral::kNoDuplicateParameters,
       FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
       FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
       scope->start_position());
index 5ed18854dcb91ed695e67a43a81f683f1d8edcdd..f06eaa9384e0215b94118436004bbab583774304 100644 (file)
@@ -93,10 +93,6 @@ class JumpPatchSite BASE_EMBEDDED {
 // frames-x64.h for its layout.
 void FullCodeGenerator::Generate() {
   CompilationInfo* info = info_;
-  handler_table_ =
-      Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
-          HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -2160,7 +2156,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       // re-boxing.
       __ bind(&l_try);
       __ Pop(rax);                                       // result
-      EnterTryBlock(expr->index(), &l_catch);
+      int handler_index = NewHandlerTableEntry();
+      EnterTryBlock(handler_index, &l_catch);
       const int try_block_size = TryCatch::kElementCount * kPointerSize;
       __ Push(rax);                                      // result
       __ jmp(&l_suspend);
@@ -2170,7 +2167,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       const int generator_object_depth = kPointerSize + try_block_size;
       __ movp(rax, Operand(rsp, generator_object_depth));
       __ Push(rax);                                      // g
-      __ Push(Smi::FromInt(expr->index()));              // handler-index
+      __ Push(Smi::FromInt(handler_index));              // handler-index
       DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
       __ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset),
               Smi::FromInt(l_continuation.pos()));
@@ -2184,7 +2181,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       __ Pop(rax);                                       // result
       EmitReturnSequence();
       __ bind(&l_resume);                                // received in rax
-      ExitTryBlock(expr->index());
+      ExitTryBlock(handler_index);
 
       // receiver = iter; f = 'next'; arg = received;
       __ bind(&l_next);
index 4d66a874fa9b694b279690ca93f5ad472d216917..3af7ce6a7d0c7753e55bd68f0d83704ae3e5d060 100644 (file)
@@ -93,10 +93,6 @@ class JumpPatchSite BASE_EMBEDDED {
 // frames-x87.h for its layout.
 void FullCodeGenerator::Generate() {
   CompilationInfo* info = info_;
-  handler_table_ =
-      Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
-          HandlerTable::LengthForRange(function()->handler_count()), TENURED));
-
   profiling_counter_ = isolate()->factory()->NewCell(
       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
   SetFunctionPosition(function());
@@ -2101,7 +2097,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       // re-boxing.
       __ bind(&l_try);
       __ pop(eax);                                       // result
-      EnterTryBlock(expr->index(), &l_catch);
+      int handler_index = NewHandlerTableEntry();
+      EnterTryBlock(handler_index, &l_catch);
       const int try_block_size = TryCatch::kElementCount * kPointerSize;
       __ push(eax);                                      // result
       __ jmp(&l_suspend);
@@ -2111,7 +2108,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       const int generator_object_depth = kPointerSize + try_block_size;
       __ mov(eax, Operand(esp, generator_object_depth));
       __ push(eax);                                      // g
-      __ push(Immediate(Smi::FromInt(expr->index())));   // handler-index
+      __ push(Immediate(Smi::FromInt(handler_index)));   // handler-index
       DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
       __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset),
              Immediate(Smi::FromInt(l_continuation.pos())));
@@ -2125,7 +2122,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
       __ pop(eax);                                       // result
       EmitReturnSequence();
       __ bind(&l_resume);                                // received in eax
-      ExitTryBlock(expr->index());
+      ExitTryBlock(handler_index);
 
       // receiver = iter; f = iter.next; arg = received;
       __ bind(&l_next);
diff --git a/test/mjsunit/regress/regress-crbug-493290.js b/test/mjsunit/regress/regress-crbug-493290.js
new file mode 100644 (file)
index 0000000..6ff9fe1
--- /dev/null
@@ -0,0 +1,9 @@
+// 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.
+
+function f() {
+  throw "boom";
+  try {} catch (e) {}
+}
+assertThrows(f);