AST nodes have at most one bailout/typefeedback ID now, saving lots of memory.

This is basically https://codereview.chromium.org/569573002/ done right:

During construction, each node type tells its parent how many IDs it
needs in addition to the parent's ones. This is done all the way up in
the class hierarchy until a node's parent doesn't need any ID. At that
point we know how many IDs in summary are needed, and we reserve the
whole range at once, saving only the base ID of that range. All IDs
are now calculated via simple offsets to that base ID. To all
performaniacs: The C++ compiler simplifies the constant calculation to
a simple load and the addition of a single constant.

Note that the actual code is much simpler than all that prose above. :-)
It's basically how compilers for OO languages figure out vtable entries.

We still have lots of holes due to padding in the AST nodes, but this
will be addressed in a separate CL.

BUG=chromium:417697
LOG=y
R=mvstanton@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24524 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6ca8f782
...@@ -61,7 +61,7 @@ bool Expression::IsUndefinedLiteral(Isolate* isolate) const { ...@@ -61,7 +61,7 @@ bool Expression::IsUndefinedLiteral(Isolate* isolate) const {
VariableProxy::VariableProxy(Zone* zone, Variable* var, int position, VariableProxy::VariableProxy(Zone* zone, Variable* var, int position,
IdGen* id_gen) IdGen* id_gen)
: Expression(zone, position, id_gen), : Expression(zone, position, 0, id_gen),
raw_name_(var->raw_name()), raw_name_(var->raw_name()),
interface_(var->interface()), interface_(var->interface()),
variable_feedback_slot_(kInvalidFeedbackSlot), variable_feedback_slot_(kInvalidFeedbackSlot),
...@@ -74,7 +74,7 @@ VariableProxy::VariableProxy(Zone* zone, Variable* var, int position, ...@@ -74,7 +74,7 @@ VariableProxy::VariableProxy(Zone* zone, Variable* var, int position,
VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, bool is_this, VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
Interface* interface, int position, IdGen* id_gen) Interface* interface, int position, IdGen* id_gen)
: Expression(zone, position, id_gen), : Expression(zone, position, 0, id_gen),
raw_name_(name), raw_name_(name),
interface_(interface), interface_(interface),
variable_feedback_slot_(kInvalidFeedbackSlot), variable_feedback_slot_(kInvalidFeedbackSlot),
...@@ -99,12 +99,11 @@ void VariableProxy::BindTo(Variable* var) { ...@@ -99,12 +99,11 @@ void VariableProxy::BindTo(Variable* var) {
Assignment::Assignment(Zone* zone, Token::Value op, Expression* target, Assignment::Assignment(Zone* zone, Token::Value op, Expression* target,
Expression* value, int pos, IdGen* id_gen) Expression* value, int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, num_ids(), id_gen),
op_(op), op_(op),
target_(target), target_(target),
value_(value), value_(value),
binary_operation_(NULL), binary_operation_(NULL),
assignment_id_(id_gen->GetNextId()),
is_uninitialized_(false), is_uninitialized_(false),
store_mode_(STANDARD_STORE) {} store_mode_(STANDARD_STORE) {}
...@@ -989,12 +988,10 @@ RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes) ...@@ -989,12 +988,10 @@ RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes)
CaseClause::CaseClause(Zone* zone, Expression* label, CaseClause::CaseClause(Zone* zone, Expression* label,
ZoneList<Statement*>* statements, int pos, IdGen* id_gen) ZoneList<Statement*>* statements, int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, num_ids(), id_gen),
label_(label), label_(label),
statements_(statements), statements_(statements),
compare_type_(Type::None(zone)), compare_type_(Type::None(zone)) {}
compare_id_(id_gen->GetNextId()),
entry_id_(id_gen->GetNextId()) {}
#define REGULAR_NODE(NodeType) \ #define REGULAR_NODE(NodeType) \
......
...@@ -186,7 +186,6 @@ class AstNode: public ZoneObject { ...@@ -186,7 +186,6 @@ class AstNode: public ZoneObject {
public: public:
IdGen() : id_(BailoutId::FirstUsable().ToInt()) {} IdGen() : id_(BailoutId::FirstUsable().ToInt()) {}
int GetNextId() { return ReserveIdRange(1); }
int ReserveIdRange(int n) { int ReserveIdRange(int n) {
int tmp = id_; int tmp = id_;
id_ += n; id_ += n;
...@@ -245,13 +244,6 @@ class AstNode: public ZoneObject { ...@@ -245,13 +244,6 @@ class AstNode: public ZoneObject {
} }
virtual void SetFirstFeedbackSlot(int slot) { UNREACHABLE(); } virtual void SetFirstFeedbackSlot(int slot) { UNREACHABLE(); }
protected:
// Some nodes re-use bailout IDs for type feedback.
static TypeFeedbackId reuse(BailoutId id) {
return TypeFeedbackId(id.ToInt());
}
private: private:
// Hidden to prevent accidental usage. It would have to load the // Hidden to prevent accidental usage. It would have to load the
// current zone from the TLS. // current zone from the TLS.
...@@ -390,27 +382,28 @@ class Expression : public AstNode { ...@@ -390,27 +382,28 @@ class Expression : public AstNode {
virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle); virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
byte to_boolean_types() const { return to_boolean_types_; } byte to_boolean_types() const { return to_boolean_types_; }
BailoutId id() const { return id_; } BailoutId id() const { return BailoutId(base_id() + 0); }
TypeFeedbackId test_id() const { return test_id_; } TypeFeedbackId test_id() const { return TypeFeedbackId(base_id() + 1); }
protected: protected:
Expression(Zone* zone, int pos, IdGen* id_gen) Expression(Zone* zone, int pos, int num_ids_needed_by_subclass, IdGen* id_gen)
: AstNode(pos), : AstNode(pos),
is_parenthesized_(false), is_parenthesized_(false),
is_multi_parenthesized_(false), is_multi_parenthesized_(false),
bounds_(Bounds::Unbounded(zone)), bounds_(Bounds::Unbounded(zone)),
id_(id_gen->GetNextId()), base_id_(
test_id_(id_gen->GetNextId()) {} id_gen->ReserveIdRange(num_ids_needed_by_subclass + num_ids())) {}
void set_to_boolean_types(byte types) { to_boolean_types_ = types; } void set_to_boolean_types(byte types) { to_boolean_types_ = types; }
static int num_ids() { return 2; }
int base_id() const { return base_id_; }
private: private:
byte to_boolean_types_; byte to_boolean_types_;
bool is_parenthesized_ : 1; bool is_parenthesized_ : 1;
bool is_multi_parenthesized_ : 1; bool is_multi_parenthesized_ : 1;
Bounds bounds_; Bounds bounds_;
const int base_id_;
const BailoutId id_;
const TypeFeedbackId test_id_;
}; };
...@@ -438,27 +431,29 @@ class BreakableStatement : public Statement { ...@@ -438,27 +431,29 @@ class BreakableStatement : public Statement {
return breakable_type_ == TARGET_FOR_ANONYMOUS; return breakable_type_ == TARGET_FOR_ANONYMOUS;
} }
BailoutId EntryId() const { return entry_id_; } BailoutId EntryId() const { return BailoutId(base_id() + 0); }
BailoutId ExitId() const { return exit_id_; } BailoutId ExitId() const { return BailoutId(base_id() + 1); }
protected: protected:
BreakableStatement(Zone* zone, ZoneList<const AstRawString*>* labels, BreakableStatement(Zone* zone, ZoneList<const AstRawString*>* labels,
BreakableType breakable_type, int position, IdGen* id_gen) BreakableType breakable_type, int position,
int num_ids_needed_by_subclass, IdGen* id_gen)
: Statement(zone, position), : Statement(zone, position),
labels_(labels), labels_(labels),
breakable_type_(breakable_type), breakable_type_(breakable_type),
entry_id_(id_gen->GetNextId()), base_id_(
exit_id_(id_gen->GetNextId()) { id_gen->ReserveIdRange(num_ids_needed_by_subclass + num_ids())) {
DCHECK(labels == NULL || labels->length() > 0); DCHECK(labels == NULL || labels->length() > 0);
} }
static int num_ids() { return 2; }
int base_id() const { return base_id_; }
private: private:
ZoneList<const AstRawString*>* labels_; ZoneList<const AstRawString*>* labels_;
BreakableType breakable_type_; BreakableType breakable_type_;
Label break_target_; Label break_target_;
const BailoutId entry_id_; const int base_id_;
const BailoutId exit_id_;
}; };
...@@ -473,7 +468,7 @@ class Block FINAL : public BreakableStatement { ...@@ -473,7 +468,7 @@ class Block FINAL : public BreakableStatement {
ZoneList<Statement*>* statements() { return &statements_; } ZoneList<Statement*>* statements() { return &statements_; }
bool is_initializer_block() const { return is_initializer_block_; } bool is_initializer_block() const { return is_initializer_block_; }
BailoutId DeclsId() const { return decls_id_; } BailoutId DeclsId() const { return BailoutId(base_id() + 0); }
virtual bool IsJump() const OVERRIDE { virtual bool IsJump() const OVERRIDE {
return !statements_.is_empty() && statements_.last()->IsJump() return !statements_.is_empty() && statements_.last()->IsJump()
...@@ -486,16 +481,20 @@ class Block FINAL : public BreakableStatement { ...@@ -486,16 +481,20 @@ class Block FINAL : public BreakableStatement {
protected: protected:
Block(Zone* zone, ZoneList<const AstRawString*>* labels, int capacity, Block(Zone* zone, ZoneList<const AstRawString*>* labels, int capacity,
bool is_initializer_block, int pos, IdGen* id_gen) bool is_initializer_block, int pos, IdGen* id_gen)
: BreakableStatement(zone, labels, TARGET_FOR_NAMED_ONLY, pos, id_gen), : BreakableStatement(zone, labels, TARGET_FOR_NAMED_ONLY, pos, num_ids(),
id_gen),
statements_(capacity, zone), statements_(capacity, zone),
is_initializer_block_(is_initializer_block), is_initializer_block_(is_initializer_block),
decls_id_(id_gen->GetNextId()),
scope_(NULL) {} scope_(NULL) {}
static int num_ids() { return 1; }
int base_id() const {
return BreakableStatement::base_id() + BreakableStatement::num_ids();
}
private: private:
ZoneList<Statement*> statements_; ZoneList<Statement*> statements_;
bool is_initializer_block_; bool is_initializer_block_;
const BailoutId decls_id_;
Scope* scope_; Scope* scope_;
}; };
...@@ -747,7 +746,7 @@ class IterationStatement : public BreakableStatement { ...@@ -747,7 +746,7 @@ class IterationStatement : public BreakableStatement {
Statement* body() const { return body_; } Statement* body() const { return body_; }
BailoutId OsrEntryId() const { return osr_entry_id_; } BailoutId OsrEntryId() const { return BailoutId(base_id() + 0); }
virtual BailoutId ContinueId() const = 0; virtual BailoutId ContinueId() const = 0;
virtual BailoutId StackCheckId() const = 0; virtual BailoutId StackCheckId() const = 0;
...@@ -756,20 +755,23 @@ class IterationStatement : public BreakableStatement { ...@@ -756,20 +755,23 @@ class IterationStatement : public BreakableStatement {
protected: protected:
IterationStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos, IterationStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
IdGen* id_gen) int num_ids_needed_by_subclass, IdGen* id_gen)
: BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos, id_gen), : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos,
body_(NULL), num_ids_needed_by_subclass + num_ids(), id_gen),
osr_entry_id_(id_gen->GetNextId()) {} body_(NULL) {}
void Initialize(Statement* body) { void Initialize(Statement* body) {
body_ = body; body_ = body;
} }
static int num_ids() { return 1; }
int base_id() const {
return BreakableStatement::base_id() + BreakableStatement::num_ids();
}
private: private:
Statement* body_; Statement* body_;
Label continue_target_; Label continue_target_;
const BailoutId osr_entry_id_;
}; };
...@@ -784,23 +786,24 @@ class DoWhileStatement FINAL : public IterationStatement { ...@@ -784,23 +786,24 @@ class DoWhileStatement FINAL : public IterationStatement {
Expression* cond() const { return cond_; } Expression* cond() const { return cond_; }
virtual BailoutId ContinueId() const OVERRIDE { return continue_id_; } virtual BailoutId ContinueId() const OVERRIDE {
virtual BailoutId StackCheckId() const OVERRIDE { return back_edge_id_; } return BailoutId(base_id() + 0);
BailoutId BackEdgeId() const { return back_edge_id_; } }
virtual BailoutId StackCheckId() const OVERRIDE { return BackEdgeId(); }
BailoutId BackEdgeId() const { return BailoutId(base_id() + 1); }
protected: protected:
DoWhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos, DoWhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
IdGen* id_gen) IdGen* id_gen)
: IterationStatement(zone, labels, pos, id_gen), : IterationStatement(zone, labels, pos, num_ids(), id_gen), cond_(NULL) {}
cond_(NULL),
continue_id_(id_gen->GetNextId()), static int num_ids() { return 2; }
back_edge_id_(id_gen->GetNextId()) {} int base_id() const {
return IterationStatement::base_id() + IterationStatement::num_ids();
}
private: private:
Expression* cond_; Expression* cond_;
const BailoutId continue_id_;
const BailoutId back_edge_id_;
}; };
...@@ -822,24 +825,26 @@ class WhileStatement FINAL : public IterationStatement { ...@@ -822,24 +825,26 @@ class WhileStatement FINAL : public IterationStatement {
} }
virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); } virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
virtual BailoutId StackCheckId() const OVERRIDE { return body_id_; } virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
BailoutId BodyId() const { return body_id_; } BailoutId BodyId() const { return BailoutId(base_id() + 0); }
protected: protected:
WhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos, WhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
IdGen* id_gen) IdGen* id_gen)
: IterationStatement(zone, labels, pos, id_gen), : IterationStatement(zone, labels, pos, num_ids(), id_gen),
cond_(NULL), cond_(NULL),
may_have_function_literal_(true), may_have_function_literal_(true) {}
body_id_(id_gen->GetNextId()) {}
static int num_ids() { return 1; }
int base_id() const {
return IterationStatement::base_id() + IterationStatement::num_ids();
}
private: private:
Expression* cond_; Expression* cond_;
// True if there is a function literal subexpression in the condition. // True if there is a function literal subexpression in the condition.
bool may_have_function_literal_; bool may_have_function_literal_;
const BailoutId body_id_;
}; };
...@@ -868,9 +873,11 @@ class ForStatement FINAL : public IterationStatement { ...@@ -868,9 +873,11 @@ class ForStatement FINAL : public IterationStatement {
may_have_function_literal_ = value; may_have_function_literal_ = value;
} }
virtual BailoutId ContinueId() const OVERRIDE { return continue_id_; } virtual BailoutId ContinueId() const OVERRIDE {
virtual BailoutId StackCheckId() const OVERRIDE { return body_id_; } return BailoutId(base_id() + 0);
BailoutId BodyId() const { return body_id_; } }
virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
BailoutId BodyId() const { return BailoutId(base_id() + 1); }
bool is_fast_smi_loop() { return loop_variable_ != NULL; } bool is_fast_smi_loop() { return loop_variable_ != NULL; }
Variable* loop_variable() { return loop_variable_; } Variable* loop_variable() { return loop_variable_; }
...@@ -879,14 +886,17 @@ class ForStatement FINAL : public IterationStatement { ...@@ -879,14 +886,17 @@ class ForStatement FINAL : public IterationStatement {
protected: protected:
ForStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos, ForStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
IdGen* id_gen) IdGen* id_gen)
: IterationStatement(zone, labels, pos, id_gen), : IterationStatement(zone, labels, pos, num_ids(), id_gen),
init_(NULL), init_(NULL),
cond_(NULL), cond_(NULL),
next_(NULL), next_(NULL),
may_have_function_literal_(true), may_have_function_literal_(true),
loop_variable_(NULL), loop_variable_(NULL) {}
continue_id_(id_gen->GetNextId()),
body_id_(id_gen->GetNextId()) {} static int num_ids() { return 2; }
int base_id() const {
return IterationStatement::base_id() + IterationStatement::num_ids();
}
private: private:
Statement* init_; Statement* init_;
...@@ -896,9 +906,6 @@ class ForStatement FINAL : public IterationStatement { ...@@ -896,9 +906,6 @@ class ForStatement FINAL : public IterationStatement {
// True if there is a function literal subexpression in the condition. // True if there is a function literal subexpression in the condition.
bool may_have_function_literal_; bool may_have_function_literal_;
Variable* loop_variable_; Variable* loop_variable_;
const BailoutId continue_id_;
const BailoutId body_id_;
}; };
...@@ -920,8 +927,9 @@ class ForEachStatement : public IterationStatement { ...@@ -920,8 +927,9 @@ class ForEachStatement : public IterationStatement {
protected: protected:
ForEachStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos, ForEachStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
IdGen* id_gen) int num_ids_needed_by_subclass, IdGen* id_gen)
: IterationStatement(zone, labels, pos, id_gen), : IterationStatement(zone, labels, pos, num_ids_needed_by_subclass,
id_gen),
each_(NULL), each_(NULL),
subject_(NULL) {} subject_(NULL) {}
...@@ -952,24 +960,26 @@ class ForInStatement FINAL : public ForEachStatement { ...@@ -952,24 +960,26 @@ class ForInStatement FINAL : public ForEachStatement {
ForInType for_in_type() const { return for_in_type_; } ForInType for_in_type() const { return for_in_type_; }
void set_for_in_type(ForInType type) { for_in_type_ = type; } void set_for_in_type(ForInType type) { for_in_type_ = type; }
BailoutId BodyId() const { return body_id_; } BailoutId BodyId() const { return BailoutId(base_id() + 0); }
BailoutId PrepareId() const { return prepare_id_; } BailoutId PrepareId() const { return BailoutId(base_id() + 1); }
virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); } virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
virtual BailoutId StackCheckId() const OVERRIDE { return body_id_; } virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
protected: protected:
ForInStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos, ForInStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
IdGen* id_gen) IdGen* id_gen)
: ForEachStatement(zone, labels, pos, id_gen), : ForEachStatement(zone, labels, pos, num_ids(), id_gen),
for_in_type_(SLOW_FOR_IN), for_in_type_(SLOW_FOR_IN),
for_in_feedback_slot_(kInvalidFeedbackSlot), for_in_feedback_slot_(kInvalidFeedbackSlot) {}
body_id_(id_gen->GetNextId()),
prepare_id_(id_gen->GetNextId()) {}
static int num_ids() { return 2; }
int base_id() const {
return ForEachStatement::base_id() + ForEachStatement::num_ids();
}
private:
ForInType for_in_type_; ForInType for_in_type_;
int for_in_feedback_slot_; int for_in_feedback_slot_;
const BailoutId body_id_;
const BailoutId prepare_id_;
}; };
...@@ -1018,23 +1028,27 @@ class ForOfStatement FINAL : public ForEachStatement { ...@@ -1018,23 +1028,27 @@ class ForOfStatement FINAL : public ForEachStatement {
virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); } virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
virtual BailoutId StackCheckId() const OVERRIDE { return BackEdgeId(); } virtual BailoutId StackCheckId() const OVERRIDE { return BackEdgeId(); }
BailoutId BackEdgeId() const { return back_edge_id_; } BailoutId BackEdgeId() const { return BailoutId(base_id() + 0); }
protected: protected:
ForOfStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos, ForOfStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
IdGen* id_gen) IdGen* id_gen)
: ForEachStatement(zone, labels, pos, id_gen), : ForEachStatement(zone, labels, pos, num_ids(), id_gen),
assign_iterator_(NULL), assign_iterator_(NULL),
next_result_(NULL), next_result_(NULL),
result_done_(NULL), result_done_(NULL),
assign_each_(NULL), assign_each_(NULL) {}
back_edge_id_(id_gen->GetNextId()) {}
static int num_ids() { return 1; }
int base_id() const {
return ForEachStatement::base_id() + ForEachStatement::num_ids();
}
private:
Expression* assign_iterator_; Expression* assign_iterator_;
Expression* next_result_; Expression* next_result_;
Expression* result_done_; Expression* result_done_;
Expression* assign_each_; Expression* assign_each_;
const BailoutId back_edge_id_;
}; };
...@@ -1145,10 +1159,9 @@ class CaseClause FINAL : public Expression { ...@@ -1145,10 +1159,9 @@ class CaseClause FINAL : public Expression {
Label* body_target() { return &body_target_; } Label* body_target() { return &body_target_; }
ZoneList<Statement*>* statements() const { return statements_; } ZoneList<Statement*>* statements() const { return statements_; }
BailoutId EntryId() const { return entry_id_; } BailoutId EntryId() const { return BailoutId(base_id() + 0); }
TypeFeedbackId CompareId() { return TypeFeedbackId(base_id() + 1); }
// Type feedback information.
TypeFeedbackId CompareId() { return compare_id_; }
Type* compare_type() { return compare_type_; } Type* compare_type() { return compare_type_; }
void set_compare_type(Type* type) { compare_type_ = type; } void set_compare_type(Type* type) { compare_type_ = type; }
...@@ -1156,13 +1169,13 @@ class CaseClause FINAL : public Expression { ...@@ -1156,13 +1169,13 @@ class CaseClause FINAL : public Expression {
CaseClause(Zone* zone, Expression* label, ZoneList<Statement*>* statements, CaseClause(Zone* zone, Expression* label, ZoneList<Statement*>* statements,
int pos, IdGen* id_gen); int pos, IdGen* id_gen);
static int num_ids() { return 2; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
Expression* label_; Expression* label_;
Label body_target_; Label body_target_;
ZoneList<Statement*>* statements_; ZoneList<Statement*>* statements_;
Type* compare_type_; Type* compare_type_;
const TypeFeedbackId compare_id_;
const BailoutId entry_id_;
}; };
...@@ -1181,7 +1194,7 @@ class SwitchStatement FINAL : public BreakableStatement { ...@@ -1181,7 +1194,7 @@ class SwitchStatement FINAL : public BreakableStatement {
protected: protected:
SwitchStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos, SwitchStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
IdGen* id_gen) IdGen* id_gen)
: BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos, id_gen), : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos, 0, id_gen),
tag_(NULL), tag_(NULL),
cases_(NULL) {} cases_(NULL) {}
...@@ -1212,9 +1225,9 @@ class IfStatement FINAL : public Statement { ...@@ -1212,9 +1225,9 @@ class IfStatement FINAL : public Statement {
&& HasElseStatement() && else_statement()->IsJump(); && HasElseStatement() && else_statement()->IsJump();
} }
BailoutId IfId() const { return if_id_; } BailoutId IfId() const { return BailoutId(base_id() + 0); }
BailoutId ThenId() const { return then_id_; } BailoutId ThenId() const { return BailoutId(base_id() + 1); }
BailoutId ElseId() const { return else_id_; } BailoutId ElseId() const { return BailoutId(base_id() + 2); }
protected: protected:
IfStatement(Zone* zone, Expression* condition, Statement* then_statement, IfStatement(Zone* zone, Expression* condition, Statement* then_statement,
...@@ -1223,17 +1236,16 @@ class IfStatement FINAL : public Statement { ...@@ -1223,17 +1236,16 @@ class IfStatement FINAL : public Statement {
condition_(condition), condition_(condition),
then_statement_(then_statement), then_statement_(then_statement),
else_statement_(else_statement), else_statement_(else_statement),
if_id_(id_gen->GetNextId()), base_id_(id_gen->ReserveIdRange(num_ids())) {}
then_id_(id_gen->GetNextId()),
else_id_(id_gen->GetNextId()) {} static int num_ids() { return 3; }
int base_id() const { return base_id_; }
private: private:
Expression* condition_; Expression* condition_;
Statement* then_statement_; Statement* then_statement_;
Statement* else_statement_; Statement* else_statement_;
const BailoutId if_id_; const int base_id_;
const BailoutId then_id_;
const BailoutId else_id_;
}; };
...@@ -1337,14 +1349,17 @@ class DebuggerStatement FINAL : public Statement { ...@@ -1337,14 +1349,17 @@ class DebuggerStatement FINAL : public Statement {
public: public:
DECLARE_NODE_TYPE(DebuggerStatement) DECLARE_NODE_TYPE(DebuggerStatement)
BailoutId DebugBreakId() const { return debugger_id_; } BailoutId DebugBreakId() const { return BailoutId(base_id() + 0); }
protected: protected:
explicit DebuggerStatement(Zone* zone, int pos, IdGen* id_gen) explicit DebuggerStatement(Zone* zone, int pos, IdGen* id_gen)
: Statement(zone, pos), debugger_id_(id_gen->GetNextId()) {} : Statement(zone, pos), base_id_(id_gen->ReserveIdRange(num_ids())) {}
static int num_ids() { return 1; }
int base_id() const { return base_id_; }
private: private:
const BailoutId debugger_id_; const int base_id_;
}; };
...@@ -1390,11 +1405,16 @@ class Literal FINAL : public Expression { ...@@ -1390,11 +1405,16 @@ class Literal FINAL : public Expression {
uint32_t Hash(); uint32_t Hash();
static bool Match(void* literal1, void* literal2); static bool Match(void* literal1, void* literal2);
TypeFeedbackId LiteralFeedbackId() const { return reuse(id()); } TypeFeedbackId LiteralFeedbackId() const {
return TypeFeedbackId(base_id() + 0);
}
protected: protected:
Literal(Zone* zone, const AstValue* value, int position, IdGen* id_gen) Literal(Zone* zone, const AstValue* value, int position, IdGen* id_gen)
: Expression(zone, position, id_gen), value_(value) {} : Expression(zone, position, num_ids(), id_gen), value_(value) {}
static int num_ids() { return 1; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
private: private:
const AstValue* value_; const AstValue* value_;
...@@ -1415,8 +1435,9 @@ class MaterializedLiteral : public Expression { ...@@ -1415,8 +1435,9 @@ class MaterializedLiteral : public Expression {
} }
protected: protected:
MaterializedLiteral(Zone* zone, int literal_index, int pos, IdGen* id_gen) MaterializedLiteral(Zone* zone, int literal_index, int pos,
: Expression(zone, pos, id_gen), int num_ids_needed_by_subclass, IdGen* id_gen)
: Expression(zone, pos, num_ids_needed_by_subclass, id_gen),
literal_index_(literal_index), literal_index_(literal_index),
is_simple_(false), is_simple_(false),
depth_(0) {} depth_(0) {}
...@@ -1548,7 +1569,7 @@ class ObjectLiteral FINAL : public MaterializedLiteral { ...@@ -1548,7 +1569,7 @@ class ObjectLiteral FINAL : public MaterializedLiteral {
ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index, ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
int boilerplate_properties, bool has_function, int pos, int boilerplate_properties, bool has_function, int pos,
IdGen* id_gen) IdGen* id_gen)
: MaterializedLiteral(zone, literal_index, pos, id_gen), : MaterializedLiteral(zone, literal_index, pos, 0, id_gen),
properties_(properties), properties_(properties),
boilerplate_properties_(boilerplate_properties), boilerplate_properties_(boilerplate_properties),
fast_elements_(false), fast_elements_(false),
...@@ -1577,7 +1598,7 @@ class RegExpLiteral FINAL : public MaterializedLiteral { ...@@ -1577,7 +1598,7 @@ class RegExpLiteral FINAL : public MaterializedLiteral {
RegExpLiteral(Zone* zone, const AstRawString* pattern, RegExpLiteral(Zone* zone, const AstRawString* pattern,
const AstRawString* flags, int literal_index, int pos, const AstRawString* flags, int literal_index, int pos,
IdGen* id_gen) IdGen* id_gen)
: MaterializedLiteral(zone, literal_index, pos, id_gen), : MaterializedLiteral(zone, literal_index, pos, 0, id_gen),
pattern_(pattern), pattern_(pattern),
flags_(flags) { flags_(flags) {
set_depth(1); set_depth(1);
...@@ -1599,9 +1620,7 @@ class ArrayLiteral FINAL : public MaterializedLiteral { ...@@ -1599,9 +1620,7 @@ class ArrayLiteral FINAL : public MaterializedLiteral {
ZoneList<Expression*>* values() const { return values_; } ZoneList<Expression*>* values() const { return values_; }
// Return an AST id for an element that is used in simulate instructions. // Return an AST id for an element that is used in simulate instructions.
BailoutId GetIdForElement(int i) { BailoutId GetIdForElement(int i) { return BailoutId(base_id() + i); }
return BailoutId(first_element_id_.ToInt() + i);
}
// Populate the constant elements fixed array. // Populate the constant elements fixed array.
void BuildConstantElements(Isolate* isolate); void BuildConstantElements(Isolate* isolate);
...@@ -1622,14 +1641,17 @@ class ArrayLiteral FINAL : public MaterializedLiteral { ...@@ -1622,14 +1641,17 @@ class ArrayLiteral FINAL : public MaterializedLiteral {
protected: protected:
ArrayLiteral(Zone* zone, ZoneList<Expression*>* values, int literal_index, ArrayLiteral(Zone* zone, ZoneList<Expression*>* values, int literal_index,
int pos, IdGen* id_gen) int pos, IdGen* id_gen)
: MaterializedLiteral(zone, literal_index, pos, id_gen), : MaterializedLiteral(zone, literal_index, pos, num_ids(values), id_gen),
values_(values), values_(values) {}
first_element_id_(id_gen->ReserveIdRange(values->length())) {}
static int num_ids(ZoneList<Expression*>* values) { return values->length(); }
int base_id() const {
return MaterializedLiteral::base_id() + MaterializedLiteral::num_ids();
}
private: private:
Handle<FixedArray> constant_elements_; Handle<FixedArray> constant_elements_;
ZoneList<Expression*>* values_; ZoneList<Expression*>* values_;
const BailoutId first_element_id_;
}; };
...@@ -1705,7 +1727,9 @@ class Property FINAL : public Expression { ...@@ -1705,7 +1727,9 @@ class Property FINAL : public Expression {
Expression* obj() const { return obj_; } Expression* obj() const { return obj_; }
Expression* key() const { return key_; } Expression* key() const { return key_; }
BailoutId LoadId() const { return load_id_; } BailoutId LoadId() const { return BailoutId(base_id() + 0); }
TypeFeedbackId PropertyFeedbackId() { return TypeFeedbackId(base_id() + 1); }
bool IsStringAccess() const { return is_string_access_; } bool IsStringAccess() const { return is_string_access_; }
...@@ -1732,8 +1756,6 @@ class Property FINAL : public Expression { ...@@ -1732,8 +1756,6 @@ class Property FINAL : public Expression {
return obj()->IsSuperReference(); return obj()->IsSuperReference();
} }
TypeFeedbackId PropertyFeedbackId() { return reuse(id()); }
virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; } virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
virtual void SetFirstFeedbackSlot(int slot) { virtual void SetFirstFeedbackSlot(int slot) {
property_feedback_slot_ = slot; property_feedback_slot_ = slot;
...@@ -1743,19 +1765,20 @@ class Property FINAL : public Expression { ...@@ -1743,19 +1765,20 @@ class Property FINAL : public Expression {
protected: protected:
Property(Zone* zone, Expression* obj, Expression* key, int pos, IdGen* id_gen) Property(Zone* zone, Expression* obj, Expression* key, int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, num_ids(), id_gen),
obj_(obj), obj_(obj),
key_(key), key_(key),
load_id_(id_gen->GetNextId()),
property_feedback_slot_(kInvalidFeedbackSlot), property_feedback_slot_(kInvalidFeedbackSlot),
is_for_call_(false), is_for_call_(false),
is_uninitialized_(false), is_uninitialized_(false),
is_string_access_(false) {} is_string_access_(false) {}
static int num_ids() { return 2; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
private: private:
Expression* obj_; Expression* obj_;
Expression* key_; Expression* key_;
const BailoutId load_id_;
int property_feedback_slot_; int property_feedback_slot_;
SmallMapList receiver_types_; SmallMapList receiver_types_;
...@@ -1818,8 +1841,8 @@ class Call FINAL : public Expression { ...@@ -1818,8 +1841,8 @@ class Call FINAL : public Expression {
} }
bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupIterator* it); bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupIterator* it);
BailoutId ReturnId() const { return return_id_; } BailoutId ReturnId() const { return BailoutId(base_id() + 0); }
BailoutId EvalOrLookupId() const { return eval_or_lookup_id_; } BailoutId EvalOrLookupId() const { return BailoutId(base_id() + 1); }
enum CallType { enum CallType {
POSSIBLY_EVAL_CALL, POSSIBLY_EVAL_CALL,
...@@ -1841,30 +1864,25 @@ class Call FINAL : public Expression { ...@@ -1841,30 +1864,25 @@ class Call FINAL : public Expression {
protected: protected:
Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments, Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
int pos, IdGen* id_gen) int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, num_ids(), id_gen),
expression_(expression), expression_(expression),
arguments_(arguments), arguments_(arguments),
call_feedback_slot_(kInvalidFeedbackSlot), call_feedback_slot_(kInvalidFeedbackSlot) {
return_id_(id_gen->GetNextId()),
eval_or_lookup_id_(id_gen->GetNextId()) {
if (expression->IsProperty()) { if (expression->IsProperty()) {
expression->AsProperty()->mark_for_call(); expression->AsProperty()->mark_for_call();
} }
} }
static int num_ids() { return 2; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
private: private:
Expression* expression_; Expression* expression_;
ZoneList<Expression*>* arguments_; ZoneList<Expression*>* arguments_;
Handle<JSFunction> target_; Handle<JSFunction> target_;
Handle<Cell> cell_; Handle<Cell> cell_;
Handle<AllocationSite> allocation_site_; Handle<AllocationSite> allocation_site_;
int call_feedback_slot_; int call_feedback_slot_;
const BailoutId return_id_;
// TODO(jarin) Only allocate the bailout id for the POSSIBLY_EVAL_CALL and
// LOOKUP_SLOT_CALL types.
const BailoutId eval_or_lookup_id_;
}; };
...@@ -1902,28 +1920,27 @@ class CallNew FINAL : public Expression { ...@@ -1902,28 +1920,27 @@ class CallNew FINAL : public Expression {
static int feedback_slots() { return 1; } static int feedback_slots() { return 1; }
BailoutId ReturnId() const { return return_id_; } BailoutId ReturnId() const { return BailoutId(base_id() + 0); }
protected: protected:
CallNew(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments, CallNew(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
int pos, IdGen* id_gen) int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, num_ids(), id_gen),
expression_(expression), expression_(expression),
arguments_(arguments), arguments_(arguments),
is_monomorphic_(false), is_monomorphic_(false),
callnew_feedback_slot_(kInvalidFeedbackSlot), callnew_feedback_slot_(kInvalidFeedbackSlot) {}
return_id_(id_gen->GetNextId()) {}
static int num_ids() { return 1; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
private: private:
Expression* expression_; Expression* expression_;
ZoneList<Expression*>* arguments_; ZoneList<Expression*>* arguments_;
bool is_monomorphic_; bool is_monomorphic_;
Handle<JSFunction> target_; Handle<JSFunction> target_;
Handle<AllocationSite> allocation_site_; Handle<AllocationSite> allocation_site_;
int callnew_feedback_slot_; int callnew_feedback_slot_;
const BailoutId return_id_;
}; };
...@@ -1955,17 +1972,22 @@ class CallRuntime FINAL : public Expression { ...@@ -1955,17 +1972,22 @@ class CallRuntime FINAL : public Expression {
return callruntime_feedback_slot_; return callruntime_feedback_slot_;
} }
TypeFeedbackId CallRuntimeFeedbackId() const { return reuse(id()); } TypeFeedbackId CallRuntimeFeedbackId() const {
return TypeFeedbackId(base_id() + 0);
}
protected: protected:
CallRuntime(Zone* zone, const AstRawString* name, CallRuntime(Zone* zone, const AstRawString* name,
const Runtime::Function* function, const Runtime::Function* function,
ZoneList<Expression*>* arguments, int pos, IdGen* id_gen) ZoneList<Expression*>* arguments, int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, num_ids(), id_gen),
raw_name_(name), raw_name_(name),
function_(function), function_(function),
arguments_(arguments) {} arguments_(arguments) {}
static int num_ids() { return 1; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
private: private:
const AstRawString* raw_name_; const AstRawString* raw_name_;
const Runtime::Function* function_; const Runtime::Function* function_;
...@@ -1981,8 +2003,10 @@ class UnaryOperation FINAL : public Expression { ...@@ -1981,8 +2003,10 @@ class UnaryOperation FINAL : public Expression {
Token::Value op() const { return op_; } Token::Value op() const { return op_; }
Expression* expression() const { return expression_; } Expression* expression() const { return expression_; }
BailoutId MaterializeTrueId() { return materialize_true_id_; } // For unary not (Token::NOT), the AST ids where true and false will
BailoutId MaterializeFalseId() { return materialize_false_id_; } // actually be materialized, respectively.
BailoutId MaterializeTrueId() const { return BailoutId(base_id() + 0); }
BailoutId MaterializeFalseId() const { return BailoutId(base_id() + 1); }
virtual void RecordToBooleanTypeFeedback( virtual void RecordToBooleanTypeFeedback(
TypeFeedbackOracle* oracle) OVERRIDE; TypeFeedbackOracle* oracle) OVERRIDE;
...@@ -1990,22 +2014,18 @@ class UnaryOperation FINAL : public Expression { ...@@ -1990,22 +2014,18 @@ class UnaryOperation FINAL : public Expression {
protected: protected:
UnaryOperation(Zone* zone, Token::Value op, Expression* expression, int pos, UnaryOperation(Zone* zone, Token::Value op, Expression* expression, int pos,
IdGen* id_gen) IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, num_ids(), id_gen),
op_(op), op_(op),
expression_(expression), expression_(expression) {
materialize_true_id_(id_gen->GetNextId()),
materialize_false_id_(id_gen->GetNextId()) {
DCHECK(Token::IsUnaryOp(op)); DCHECK(Token::IsUnaryOp(op));
} }
static int num_ids() { return 2; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
private: private:
Token::Value op_; Token::Value op_;
Expression* expression_; Expression* expression_;
// For unary not (Token::NOT), the AST ids where true and false will
// actually be materialized, respectively.
const BailoutId materialize_true_id_;
const BailoutId materialize_false_id_;
}; };
...@@ -2023,9 +2043,13 @@ class BinaryOperation FINAL : public Expression { ...@@ -2023,9 +2043,13 @@ class BinaryOperation FINAL : public Expression {
allocation_site_ = allocation_site; allocation_site_ = allocation_site;
} }
BailoutId RightId() const { return right_id_; } // The short-circuit logical operations need an AST ID for their
// right-hand subexpression.
BailoutId RightId() const { return BailoutId(base_id() + 0); }
TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); } TypeFeedbackId BinaryOperationFeedbackId() const {
return TypeFeedbackId(base_id() + 1);
}
Maybe<int> fixed_right_arg() const { return fixed_right_arg_; } Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
void set_fixed_right_arg(Maybe<int> arg) { fixed_right_arg_ = arg; } void set_fixed_right_arg(Maybe<int> arg) { fixed_right_arg_ = arg; }
...@@ -2035,14 +2059,16 @@ class BinaryOperation FINAL : public Expression { ...@@ -2035,14 +2059,16 @@ class BinaryOperation FINAL : public Expression {
protected: protected:
BinaryOperation(Zone* zone, Token::Value op, Expression* left, BinaryOperation(Zone* zone, Token::Value op, Expression* left,
Expression* right, int pos, IdGen* id_gen) Expression* right, int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, num_ids(), id_gen),
op_(op), op_(op),
left_(left), left_(left),
right_(right), right_(right) {
right_id_(id_gen->GetNextId()) {
DCHECK(Token::IsBinaryOp(op)); DCHECK(Token::IsBinaryOp(op));
} }
static int num_ids() { return 2; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
private: private:
Token::Value op_; Token::Value op_;
Expression* left_; Expression* left_;
...@@ -2052,10 +2078,6 @@ class BinaryOperation FINAL : public Expression { ...@@ -2052,10 +2078,6 @@ class BinaryOperation FINAL : public Expression {
// TODO(rossberg): the fixed arg should probably be represented as a Constant // TODO(rossberg): the fixed arg should probably be represented as a Constant
// type for the RHS. // type for the RHS.
Maybe<int> fixed_right_arg_; Maybe<int> fixed_right_arg_;
// The short-circuit logical operations need an AST ID for their
// right-hand subexpression.
const BailoutId right_id_;
}; };
...@@ -2086,21 +2108,25 @@ class CountOperation FINAL : public Expression { ...@@ -2086,21 +2108,25 @@ class CountOperation FINAL : public Expression {
void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; } void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
void set_type(Type* type) { type_ = type; } void set_type(Type* type) { type_ = type; }
BailoutId AssignmentId() const { return assignment_id_; } BailoutId AssignmentId() const { return BailoutId(base_id() + 0); }
TypeFeedbackId CountBinOpFeedbackId() const {
TypeFeedbackId CountBinOpFeedbackId() const { return count_id_; } return TypeFeedbackId(base_id() + 1);
TypeFeedbackId CountStoreFeedbackId() const { return reuse(id()); } }
TypeFeedbackId CountStoreFeedbackId() const {
return TypeFeedbackId(base_id() + 2);
}
protected: protected:
CountOperation(Zone* zone, Token::Value op, bool is_prefix, Expression* expr, CountOperation(Zone* zone, Token::Value op, bool is_prefix, Expression* expr,
int pos, IdGen* id_gen) int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, num_ids(), id_gen),
op_(op), op_(op),
is_prefix_(is_prefix), is_prefix_(is_prefix),
store_mode_(STANDARD_STORE), store_mode_(STANDARD_STORE),
expression_(expr), expression_(expr) {}
assignment_id_(id_gen->GetNextId()),
count_id_(id_gen->GetNextId()) {} static int num_ids() { return 3; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
private: private:
Token::Value op_; Token::Value op_;
...@@ -2108,10 +2134,7 @@ class CountOperation FINAL : public Expression { ...@@ -2108,10 +2134,7 @@ class CountOperation FINAL : public Expression {
KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed, KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed,
// must have extra bit. // must have extra bit.
Type* type_; Type* type_;
Expression* expression_; Expression* expression_;
const BailoutId assignment_id_;
const TypeFeedbackId count_id_;
SmallMapList receiver_types_; SmallMapList receiver_types_;
}; };
...@@ -2125,7 +2148,9 @@ class CompareOperation FINAL : public Expression { ...@@ -2125,7 +2148,9 @@ class CompareOperation FINAL : public Expression {
Expression* right() const { return right_; } Expression* right() const { return right_; }
// Type feedback information. // Type feedback information.
TypeFeedbackId CompareOperationFeedbackId() const { return reuse(id()); } TypeFeedbackId CompareOperationFeedbackId() const {
return TypeFeedbackId(base_id() + 0);
}
Type* combined_type() const { return combined_type_; } Type* combined_type() const { return combined_type_; }
void set_combined_type(Type* type) { combined_type_ = type; } void set_combined_type(Type* type) { combined_type_ = type; }
...@@ -2137,7 +2162,7 @@ class CompareOperation FINAL : public Expression { ...@@ -2137,7 +2162,7 @@ class CompareOperation FINAL : public Expression {
protected: protected:
CompareOperation(Zone* zone, Token::Value op, Expression* left, CompareOperation(Zone* zone, Token::Value op, Expression* left,
Expression* right, int pos, IdGen* id_gen) Expression* right, int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, num_ids(), id_gen),
op_(op), op_(op),
left_(left), left_(left),
right_(right), right_(right),
...@@ -2145,6 +2170,9 @@ class CompareOperation FINAL : public Expression { ...@@ -2145,6 +2170,9 @@ class CompareOperation FINAL : public Expression {
DCHECK(Token::IsCompareOp(op)); DCHECK(Token::IsCompareOp(op));
} }
static int num_ids() { return 1; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
private: private:
Token::Value op_; Token::Value op_;
Expression* left_; Expression* left_;
...@@ -2162,25 +2190,24 @@ class Conditional FINAL : public Expression { ...@@ -2162,25 +2190,24 @@ class Conditional FINAL : public Expression {
Expression* then_expression() const { return then_expression_; } Expression* then_expression() const { return then_expression_; }
Expression* else_expression() const { return else_expression_; } Expression* else_expression() const { return else_expression_; }
BailoutId ThenId() const { return then_id_; } BailoutId ThenId() const { return BailoutId(base_id() + 0); }
BailoutId ElseId() const { return else_id_; } BailoutId ElseId() const { return BailoutId(base_id() + 1); }
protected: protected:
Conditional(Zone* zone, Expression* condition, Expression* then_expression, Conditional(Zone* zone, Expression* condition, Expression* then_expression,
Expression* else_expression, int position, IdGen* id_gen) Expression* else_expression, int position, IdGen* id_gen)
: Expression(zone, position, id_gen), : Expression(zone, position, num_ids(), id_gen),
condition_(condition), condition_(condition),
then_expression_(then_expression), then_expression_(then_expression),
else_expression_(else_expression), else_expression_(else_expression) {}
then_id_(id_gen->GetNextId()),
else_id_(id_gen->GetNextId()) {} static int num_ids() { return 2; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
private: private:
Expression* condition_; Expression* condition_;
Expression* then_expression_; Expression* then_expression_;
Expression* else_expression_; Expression* else_expression_;
const BailoutId then_id_;
const BailoutId else_id_;
}; };
...@@ -2200,10 +2227,12 @@ class Assignment FINAL : public Expression { ...@@ -2200,10 +2227,12 @@ class Assignment FINAL : public Expression {
// This check relies on the definition order of token in token.h. // This check relies on the definition order of token in token.h.
bool is_compound() const { return op() > Token::ASSIGN; } bool is_compound() const { return op() > Token::ASSIGN; }
BailoutId AssignmentId() const { return assignment_id_; } BailoutId AssignmentId() const { return BailoutId(base_id() + 0); }
// Type feedback information. // Type feedback information.
TypeFeedbackId AssignmentFeedbackId() { return reuse(id()); } TypeFeedbackId AssignmentFeedbackId() {
return TypeFeedbackId(base_id() + 1);
}
virtual bool IsMonomorphic() OVERRIDE { virtual bool IsMonomorphic() OVERRIDE {
return receiver_types_.length() == 1; return receiver_types_.length() == 1;
} }
...@@ -2224,6 +2253,9 @@ class Assignment FINAL : public Expression { ...@@ -2224,6 +2253,9 @@ class Assignment FINAL : public Expression {
Assignment(Zone* zone, Token::Value op, Expression* target, Expression* value, Assignment(Zone* zone, Token::Value op, Expression* target, Expression* value,
int pos, IdGen* id_gen); 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> template<class Visitor>
void Init(Zone* zone, AstNodeFactory<Visitor>* factory) { void Init(Zone* zone, AstNodeFactory<Visitor>* factory) {
DCHECK(Token::IsAssignmentOp(op_)); DCHECK(Token::IsAssignmentOp(op_));
...@@ -2238,8 +2270,6 @@ class Assignment FINAL : public Expression { ...@@ -2238,8 +2270,6 @@ class Assignment FINAL : public Expression {
Expression* target_; Expression* target_;
Expression* value_; Expression* value_;
BinaryOperation* binary_operation_; BinaryOperation* binary_operation_;
const BailoutId assignment_id_;
bool is_uninitialized_ : 1; bool is_uninitialized_ : 1;
KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed, KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed,
// must have extra bit. // must have extra bit.
...@@ -2300,7 +2330,7 @@ class Yield FINAL : public Expression { ...@@ -2300,7 +2330,7 @@ class Yield FINAL : public Expression {
protected: protected:
Yield(Zone* zone, Expression* generator_object, Expression* expression, Yield(Zone* zone, Expression* generator_object, Expression* expression,
Kind yield_kind, int pos, IdGen* id_gen) Kind yield_kind, int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, 0, id_gen),
generator_object_(generator_object), generator_object_(generator_object),
expression_(expression), expression_(expression),
yield_kind_(yield_kind), yield_kind_(yield_kind),
...@@ -2324,7 +2354,7 @@ class Throw FINAL : public Expression { ...@@ -2324,7 +2354,7 @@ class Throw FINAL : public Expression {
protected: protected:
Throw(Zone* zone, Expression* exception, int pos, IdGen* id_gen) Throw(Zone* zone, Expression* exception, int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), exception_(exception) {} : Expression(zone, pos, 0, id_gen), exception_(exception) {}
private: private:
Expression* exception_; Expression* exception_;
...@@ -2478,7 +2508,7 @@ class FunctionLiteral FINAL : public Expression { ...@@ -2478,7 +2508,7 @@ class FunctionLiteral FINAL : public Expression {
IsFunctionFlag is_function, IsFunctionFlag is_function,
IsParenthesizedFlag is_parenthesized, FunctionKind kind, IsParenthesizedFlag is_parenthesized, FunctionKind kind,
int position, IdGen* id_gen) int position, IdGen* id_gen)
: Expression(zone, position, id_gen), : Expression(zone, position, 0, id_gen),
raw_name_(name), raw_name_(name),
scope_(scope), scope_(scope),
body_(body), body_(body),
...@@ -2545,7 +2575,7 @@ class ClassLiteral FINAL : public Expression { ...@@ -2545,7 +2575,7 @@ class ClassLiteral FINAL : public Expression {
ClassLiteral(Zone* zone, const AstRawString* name, Expression* extends, ClassLiteral(Zone* zone, const AstRawString* name, Expression* extends,
Expression* constructor, ZoneList<Property*>* properties, Expression* constructor, ZoneList<Property*>* properties,
int start_position, int end_position, IdGen* id_gen) int start_position, int end_position, IdGen* id_gen)
: Expression(zone, start_position, id_gen), : Expression(zone, start_position, 0, id_gen),
raw_name_(name), raw_name_(name),
extends_(extends), extends_(extends),
constructor_(constructor), constructor_(constructor),
...@@ -2571,7 +2601,7 @@ class NativeFunctionLiteral FINAL : public Expression { ...@@ -2571,7 +2601,7 @@ class NativeFunctionLiteral FINAL : public Expression {
protected: protected:
NativeFunctionLiteral(Zone* zone, const AstRawString* name, NativeFunctionLiteral(Zone* zone, const AstRawString* name,
v8::Extension* extension, int pos, IdGen* id_gen) v8::Extension* extension, int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), name_(name), extension_(extension) {} : Expression(zone, pos, 0, id_gen), name_(name), extension_(extension) {}
private: private:
const AstRawString* name_; const AstRawString* name_;
...@@ -2585,7 +2615,7 @@ class ThisFunction FINAL : public Expression { ...@@ -2585,7 +2615,7 @@ class ThisFunction FINAL : public Expression {
protected: protected:
ThisFunction(Zone* zone, int pos, IdGen* id_gen) ThisFunction(Zone* zone, int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen) {} : Expression(zone, pos, 0, id_gen) {}
}; };
...@@ -2595,7 +2625,9 @@ class SuperReference FINAL : public Expression { ...@@ -2595,7 +2625,9 @@ class SuperReference FINAL : public Expression {
VariableProxy* this_var() const { return this_var_; } VariableProxy* this_var() const { return this_var_; }
TypeFeedbackId HomeObjectFeedbackId() { return reuse(id()); } TypeFeedbackId HomeObjectFeedbackId() {
return TypeFeedbackId(base_id() + 0);
}
// Type feedback information. // Type feedback information.
virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; } virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
...@@ -2611,12 +2643,16 @@ class SuperReference FINAL : public Expression { ...@@ -2611,12 +2643,16 @@ class SuperReference FINAL : public Expression {
protected: protected:
SuperReference(Zone* zone, VariableProxy* this_var, int pos, IdGen* id_gen) SuperReference(Zone* zone, VariableProxy* this_var, int pos, IdGen* id_gen)
: Expression(zone, pos, id_gen), : Expression(zone, pos, num_ids(), id_gen),
this_var_(this_var), this_var_(this_var),
homeobject_feedback_slot_(kInvalidFeedbackSlot) { homeobject_feedback_slot_(kInvalidFeedbackSlot) {
DCHECK(this_var->is_this()); DCHECK(this_var->is_this());
} }
static int num_ids() { return 1; }
int base_id() const { return Expression::base_id() + Expression::num_ids(); }
private:
VariableProxy* this_var_; VariableProxy* this_var_;
int homeobject_feedback_slot_; int homeobject_feedback_slot_;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment