Index: src/ast.h |
diff --git a/src/ast.h b/src/ast.h |
index 07227b105c50818d32ff4219ef0038436ba28bfe..fb79d04dcceea031666b0b962588080d7f32d08b 100644 |
--- a/src/ast.h |
+++ b/src/ast.h |
@@ -177,19 +177,51 @@ enum AstPropertiesFlag { |
}; |
+class FeedbackSlotInterface { |
+ public: |
+ virtual ~FeedbackSlotInterface() {} |
+ virtual int GetFeedbackSlotCount(Isolate* isolate) = 0; |
+ virtual void SetFirstFeedbackSlot(int slot) = 0; |
+}; |
+ |
+ |
class AstProperties V8_FINAL BASE_EMBEDDED { |
public: |
class Flags : public EnumSet<AstPropertiesFlag, int> {}; |
- AstProperties() : node_count_(0) { } |
+ AstProperties() : node_count_(0), slot_nodes_(NULL), slot_count_(-1) { |
+ } |
+ |
+ ZoneList<FeedbackSlotInterface*>* slot_nodes() { |
+ ASSERT(slot_count_ == -1); |
+ return slot_nodes_; |
+ } |
+ void set_slot_count(int count) { |
+ ASSERT(slot_count_ == -1); |
+ slot_count_ = count; |
+ slot_nodes_ = NULL; // We are done with this funny list. |
+ } |
+ |
+ // Returns -1 if the work hasn't been done yet. |
+ int slot_count() { |
+ return slot_count_; |
+ } |
Flags* flags() { return &flags_; } |
int node_count() { return node_count_; } |
void add_node_count(int count) { node_count_ += count; } |
+ void add_slot_node(Zone* zone, FeedbackSlotInterface* slot) { |
+ if (slot_nodes_ == NULL) { |
+ slot_nodes_ = new(zone) ZoneList<FeedbackSlotInterface*>(10, zone); |
+ } |
+ slot_nodes_->Add(slot, zone); |
+ } |
private: |
Flags flags_; |
int node_count_; |
+ ZoneList<FeedbackSlotInterface*>* slot_nodes_; |
+ int slot_count_; |
}; |
@@ -213,6 +245,9 @@ class AstNode: public ZoneObject { |
virtual NodeType node_type() const = 0; |
int position() const { return position_; } |
+ static const int kInvalidFeedbackSlot = -1; |
+ virtual FeedbackSlotInterface* SupportsFeedbackSlots() { return NULL; } |
+ |
// Type testing & conversion functions overridden by concrete subclasses. |
#define DECLARE_NODE_FUNCTIONS(type) \ |
bool Is##type() { return node_type() == AstNode::k##type; } \ |
@@ -914,7 +949,8 @@ class ForEachStatement : public IterationStatement { |
}; |
-class ForInStatement V8_FINAL : public ForEachStatement { |
+class ForInStatement V8_FINAL : public ForEachStatement, |
+ public FeedbackSlotInterface { |
public: |
DECLARE_NODE_TYPE(ForInStatement) |
@@ -922,7 +958,16 @@ class ForInStatement V8_FINAL : public ForEachStatement { |
return subject(); |
} |
- TypeFeedbackId ForInFeedbackId() const { return reuse(PrepareId()); } |
+ // Type feedback information. |
+ virtual FeedbackSlotInterface* SupportsFeedbackSlots() { return this; } |
+ virtual int GetFeedbackSlotCount(Isolate* isolate) { return 1; } |
+ virtual void SetFirstFeedbackSlot(int slot) { for_in_feedback_slot_ = slot; } |
+ |
+ int ForInFeedbackSlot() { |
+ ASSERT(for_in_feedback_slot_ != kInvalidFeedbackSlot); |
+ return for_in_feedback_slot_; |
+ } |
+ |
enum ForInType { FAST_FOR_IN, SLOW_FOR_IN }; |
ForInType for_in_type() const { return for_in_type_; } |
void set_for_in_type(ForInType type) { for_in_type_ = type; } |
@@ -936,11 +981,13 @@ class ForInStatement V8_FINAL : public ForEachStatement { |
ForInStatement(Zone* zone, ZoneStringList* labels, int pos) |
: ForEachStatement(zone, labels, pos), |
for_in_type_(SLOW_FOR_IN), |
+ for_in_feedback_slot_(kInvalidFeedbackSlot), |
body_id_(GetNextId(zone)), |
prepare_id_(GetNextId(zone)) { |
} |
ForInType for_in_type_; |
+ int for_in_feedback_slot_; |
const BailoutId body_id_; |
const BailoutId prepare_id_; |
}; |
@@ -1733,7 +1780,7 @@ class Property V8_FINAL : public Expression { |
}; |
-class Call V8_FINAL : public Expression { |
+class Call V8_FINAL : public Expression, public FeedbackSlotInterface { |
public: |
DECLARE_NODE_TYPE(Call) |
@@ -1741,6 +1788,18 @@ class Call V8_FINAL : public Expression { |
ZoneList<Expression*>* arguments() const { return arguments_; } |
// Type feedback information. |
+ virtual FeedbackSlotInterface* SupportsFeedbackSlots() { return this; } |
+ virtual int GetFeedbackSlotCount(Isolate* isolate); |
+ virtual void SetFirstFeedbackSlot(int slot) { |
+ call_feedback_slot_ = slot; |
+ } |
+ |
+ bool HasCallFeedbackSlot() const { |
+ return call_feedback_slot_ != kInvalidFeedbackSlot; |
+ } |
+ int CallFeedbackSlot() const { return call_feedback_slot_; } |
+ |
+ // Type feedback information. |
TypeFeedbackId CallFeedbackId() const { return reuse(id()); } |
void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
virtual SmallMapList* GetReceiverTypes() V8_OVERRIDE { |
@@ -1811,6 +1870,7 @@ class Call V8_FINAL : public Expression { |
is_monomorphic_(false), |
keyed_array_call_is_holey_(true), |
check_type_(RECEIVER_MAP_CHECK), |
+ call_feedback_slot_(kInvalidFeedbackSlot), |
return_id_(GetNextId(zone)) { } |
private: |
@@ -1824,12 +1884,13 @@ class Call V8_FINAL : public Expression { |
Handle<JSFunction> target_; |
Handle<JSObject> holder_; |
Handle<Cell> cell_; |
+ int call_feedback_slot_; |
const BailoutId return_id_; |
}; |
-class CallNew V8_FINAL : public Expression { |
+class CallNew V8_FINAL : public Expression, public FeedbackSlotInterface { |
public: |
DECLARE_NODE_TYPE(CallNew) |
@@ -1837,6 +1898,17 @@ class CallNew V8_FINAL : public Expression { |
ZoneList<Expression*>* arguments() const { return arguments_; } |
// Type feedback information. |
+ virtual FeedbackSlotInterface* SupportsFeedbackSlots() { return this; } |
+ virtual int GetFeedbackSlotCount(Isolate* isolate) { return 1; } |
+ virtual void SetFirstFeedbackSlot(int slot) { |
+ callnew_feedback_slot_ = slot; |
+ } |
+ |
+ int CallNewFeedbackSlot() { |
+ ASSERT(callnew_feedback_slot_ != kInvalidFeedbackSlot); |
+ return callnew_feedback_slot_; |
+ } |
+ |
TypeFeedbackId CallNewFeedbackId() const { return reuse(id()); } |
void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
virtual bool IsMonomorphic() V8_OVERRIDE { return is_monomorphic_; } |
@@ -1846,6 +1918,8 @@ class CallNew V8_FINAL : public Expression { |
return allocation_site_; |
} |
+ static int feedback_slots() { return 1; } |
+ |
BailoutId ReturnId() const { return return_id_; } |
protected: |
@@ -1858,6 +1932,7 @@ class CallNew V8_FINAL : public Expression { |
arguments_(arguments), |
is_monomorphic_(false), |
elements_kind_(GetInitialFastElementsKind()), |
+ callnew_feedback_slot_(kInvalidFeedbackSlot), |
return_id_(GetNextId(zone)) { } |
private: |
@@ -1868,6 +1943,8 @@ class CallNew V8_FINAL : public Expression { |
Handle<JSFunction> target_; |
ElementsKind elements_kind_; |
Handle<AllocationSite> allocation_site_; |
+ Handle<Cell> allocation_info_cell_; |
+ int callnew_feedback_slot_; |
const BailoutId return_id_; |
}; |
@@ -2357,7 +2434,15 @@ class FunctionLiteral V8_FINAL : public Expression { |
void set_ast_properties(AstProperties* ast_properties) { |
ast_properties_ = *ast_properties; |
} |
- |
+ ZoneList<FeedbackSlotInterface*>* slot_nodes() { |
+ return ast_properties_.slot_nodes(); |
+ } |
+ int slot_count() { |
+ return ast_properties_.slot_count(); |
+ } |
+ void set_slot_count(int count) { |
+ ast_properties_.set_slot_count(count); |
+ } |
bool dont_optimize() { return dont_optimize_reason_ != kNoReason; } |
BailoutReason dont_optimize_reason() { return dont_optimize_reason_; } |
void set_dont_optimize_reason(BailoutReason reason) { |
@@ -2881,7 +2966,9 @@ private: \ |
class AstConstructionVisitor BASE_EMBEDDED { |
public: |
- AstConstructionVisitor() : dont_optimize_reason_(kNoReason) { } |
+ explicit AstConstructionVisitor(Zone* zone) |
+ : dont_optimize_reason_(kNoReason), |
mvstanton
2014/01/30 15:13:41
pass the deferred worker here.
mvstanton
2014/01/30 17:37:41
As it turns out, the AstConstructionVisitor can cr
|
+ zone_(zone) { } |
AstProperties* ast_properties() { return &properties_; } |
BailoutReason dont_optimize_reason() { return dont_optimize_reason_; } |
@@ -2901,13 +2988,22 @@ class AstConstructionVisitor BASE_EMBEDDED { |
dont_optimize_reason_ = reason; |
} |
+ void AddFeedbackSlotInterface(FeedbackSlotInterface* fsi) { |
+ if (fsi != NULL) { |
+ properties_.add_slot_node(zone_, fsi); |
+ } |
+ } |
+ |
AstProperties properties_; |
BailoutReason dont_optimize_reason_; |
+ Zone* zone_; |
}; |
class AstNullVisitor BASE_EMBEDDED { |
public: |
+ explicit AstNullVisitor(Zone* zone) {} |
+ |
// Node visitors. |
#define DEF_VISIT(type) \ |
void Visit##type(type* node) {} |
@@ -2923,7 +3019,9 @@ class AstNullVisitor BASE_EMBEDDED { |
template<class Visitor> |
class AstNodeFactory V8_FINAL BASE_EMBEDDED { |
public: |
- explicit AstNodeFactory(Zone* zone) : zone_(zone) { } |
+ explicit AstNodeFactory(Zone* zone) |
+ : zone_(zone), |
+ visitor_(zone) { } |
Visitor* visitor() { return &visitor_; } |