Drop computed handler count and index from AST.

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}
This commit is contained in:
mstarzinger 2015-06-08 11:19:32 -07:00 committed by Commit bot
parent d2f5702c56
commit c14ba5ec48
14 changed files with 130 additions and 164 deletions

View 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);

View 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);

View File

@ -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);
}

View 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);

View 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_;

View 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);

View 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);

View 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);

View 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();

View 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);

View 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());

View 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);

View 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);

View File

@ -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);