| Index: src/ast.h
|
| diff --git a/src/ast.h b/src/ast.h
|
| index 847d9cae2b68bcbb93d8b4711a2b110ccd2b30e0..fe9a7fd11f9c7d49cbf74323eb0c4643363e4c75 100644
|
| --- a/src/ast.h
|
| +++ b/src/ast.h
|
| @@ -157,11 +157,25 @@ enum AstPropertiesFlag {
|
| };
|
|
|
|
|
| +class FeedbackVectorRequirements {
|
| + public:
|
| + FeedbackVectorRequirements(int slots, int ic_slots)
|
| + : slots_(slots), ic_slots_(ic_slots) {}
|
| +
|
| + int slots() const { return slots_; }
|
| + int ic_slots() const { return ic_slots_; }
|
| +
|
| + private:
|
| + int slots_;
|
| + int ic_slots_;
|
| +};
|
| +
|
| +
|
| class AstProperties FINAL BASE_EMBEDDED {
|
| public:
|
| class Flags : public EnumSet<AstPropertiesFlag, int> {};
|
|
|
| -AstProperties() : node_count_(0), feedback_slots_(0) {}
|
| + AstProperties() : node_count_(0), feedback_slots_(0), ic_feedback_slots_(0) {}
|
|
|
| Flags* flags() { return &flags_; }
|
| int node_count() { return node_count_; }
|
| @@ -172,10 +186,14 @@ AstProperties() : node_count_(0), feedback_slots_(0) {}
|
| feedback_slots_ += count;
|
| }
|
|
|
| + int ic_feedback_slots() const { return ic_feedback_slots_; }
|
| + void increase_ic_feedback_slots(int count) { ic_feedback_slots_ += count; }
|
| +
|
| private:
|
| Flags flags_;
|
| int node_count_;
|
| int feedback_slots_;
|
| + int ic_feedback_slots_;
|
| };
|
|
|
|
|
| @@ -237,11 +255,13 @@ class AstNode: public ZoneObject {
|
| // node types which don't actually have this. Note that this is conceptually
|
| // not really nice, but multiple inheritance would introduce yet another
|
| // vtable entry per node, something we don't want for space reasons.
|
| - virtual int ComputeFeedbackSlotCount() {
|
| - UNREACHABLE();
|
| - return 0;
|
| + virtual FeedbackVectorRequirements ComputeFeedbackRequirements() {
|
| + return FeedbackVectorRequirements(0, 0);
|
| }
|
| virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) { UNREACHABLE(); }
|
| + virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) {
|
| + UNREACHABLE();
|
| + }
|
|
|
| private:
|
| // Hidden to prevent accidental usage. It would have to load the
|
| @@ -945,7 +965,9 @@ class ForInStatement FINAL : public ForEachStatement {
|
| }
|
|
|
| // Type feedback information.
|
| - virtual int ComputeFeedbackSlotCount() { return 1; }
|
| + virtual FeedbackVectorRequirements ComputeFeedbackRequirements() {
|
| + return FeedbackVectorRequirements(1, 0);
|
| + }
|
| virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
| for_in_feedback_slot_ = slot;
|
| }
|
| @@ -1692,12 +1714,16 @@ class VariableProxy FINAL : public Expression {
|
| // Bind this proxy to the variable var. Interfaces must match.
|
| void BindTo(Variable* var);
|
|
|
| - virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
|
| - virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
| + virtual FeedbackVectorRequirements ComputeFeedbackRequirements() {
|
| + return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
|
| + }
|
| + virtual void SetFirstICFeedbackSlot(FeedbackVectorICSlot slot) {
|
| variable_feedback_slot_ = slot;
|
| }
|
|
|
| - FeedbackVectorSlot VariableFeedbackSlot() { return variable_feedback_slot_; }
|
| + FeedbackVectorICSlot VariableFeedbackSlot() {
|
| + return variable_feedback_slot_;
|
| + }
|
|
|
| protected:
|
| VariableProxy(Zone* zone, Variable* var, int position, IdGen* id_gen);
|
| @@ -1708,7 +1734,7 @@ class VariableProxy FINAL : public Expression {
|
| bool is_this_ : 1;
|
| bool is_assigned_ : 1;
|
| bool is_resolved_ : 1;
|
| - FeedbackVectorSlot variable_feedback_slot_;
|
| + FeedbackVectorICSlot variable_feedback_slot_;
|
| union {
|
| const AstRawString* raw_name_; // if !is_resolved_
|
| Variable* var_; // if is_resolved_
|
| @@ -1759,12 +1785,14 @@ class Property FINAL : public Expression {
|
| return obj()->IsSuperReference();
|
| }
|
|
|
| - virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
|
| - virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
| + virtual FeedbackVectorRequirements ComputeFeedbackRequirements() {
|
| + return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
|
| + }
|
| + virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) {
|
| property_feedback_slot_ = slot;
|
| }
|
|
|
| - FeedbackVectorSlot PropertyFeedbackSlot() const {
|
| + FeedbackVectorICSlot PropertyFeedbackSlot() const {
|
| return property_feedback_slot_;
|
| }
|
|
|
| @@ -1774,7 +1802,7 @@ class Property FINAL : public Expression {
|
| is_for_call_(false),
|
| is_uninitialized_(false),
|
| is_string_access_(false),
|
| - property_feedback_slot_(FeedbackVectorSlot::Invalid()),
|
| + property_feedback_slot_(FeedbackVectorICSlot::Invalid()),
|
| obj_(obj),
|
| key_(key) {}
|
|
|
| @@ -1785,7 +1813,7 @@ class Property FINAL : public Expression {
|
| bool is_for_call_ : 1;
|
| bool is_uninitialized_ : 1;
|
| bool is_string_access_ : 1;
|
| - FeedbackVectorSlot property_feedback_slot_;
|
| + FeedbackVectorICSlot property_feedback_slot_;
|
| Expression* obj_;
|
| Expression* key_;
|
| SmallMapList receiver_types_;
|
| @@ -1800,13 +1828,15 @@ class Call FINAL : public Expression {
|
| ZoneList<Expression*>* arguments() const { return arguments_; }
|
|
|
| // Type feedback information.
|
| - virtual int ComputeFeedbackSlotCount() { return 1; }
|
| - virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
| + virtual FeedbackVectorRequirements ComputeFeedbackRequirements() {
|
| + return FeedbackVectorRequirements(0, 1);
|
| + }
|
| + virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) {
|
| call_feedback_slot_ = slot;
|
| }
|
|
|
| bool HasCallFeedbackSlot() const { return !call_feedback_slot_.IsInvalid(); }
|
| - FeedbackVectorSlot CallFeedbackSlot() const { return call_feedback_slot_; }
|
| + FeedbackVectorICSlot CallFeedbackSlot() const { return call_feedback_slot_; }
|
|
|
| virtual SmallMapList* GetReceiverTypes() OVERRIDE {
|
| if (expression()->IsProperty()) {
|
| @@ -1868,7 +1898,7 @@ class Call FINAL : public Expression {
|
| Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
|
| int pos, IdGen* id_gen)
|
| : Expression(zone, pos, num_ids(), id_gen),
|
| - call_feedback_slot_(FeedbackVectorSlot::Invalid()),
|
| + call_feedback_slot_(FeedbackVectorICSlot::Invalid()),
|
| expression_(expression),
|
| arguments_(arguments) {
|
| if (expression->IsProperty()) {
|
| @@ -1880,7 +1910,7 @@ class Call FINAL : public Expression {
|
| int base_id() const { return Expression::base_id() + Expression::num_ids(); }
|
|
|
| private:
|
| - FeedbackVectorSlot call_feedback_slot_;
|
| + FeedbackVectorICSlot call_feedback_slot_;
|
| Expression* expression_;
|
| ZoneList<Expression*>* arguments_;
|
| Handle<JSFunction> target_;
|
| @@ -1897,8 +1927,8 @@ class CallNew FINAL : public Expression {
|
| ZoneList<Expression*>* arguments() const { return arguments_; }
|
|
|
| // Type feedback information.
|
| - virtual int ComputeFeedbackSlotCount() {
|
| - return FLAG_pretenuring_call_new ? 2 : 1;
|
| + virtual FeedbackVectorRequirements ComputeFeedbackRequirements() {
|
| + return FeedbackVectorRequirements(FLAG_pretenuring_call_new ? 2 : 1, 0);
|
| }
|
| virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
| callnew_feedback_slot_ = slot;
|
| @@ -1958,14 +1988,15 @@ class CallRuntime FINAL : public Expression {
|
| bool is_jsruntime() const { return function_ == NULL; }
|
|
|
| // Type feedback information.
|
| - virtual int ComputeFeedbackSlotCount() {
|
| - return (FLAG_vector_ics && is_jsruntime()) ? 1 : 0;
|
| + virtual FeedbackVectorRequirements ComputeFeedbackRequirements() {
|
| + return FeedbackVectorRequirements(
|
| + 0, (FLAG_vector_ics && is_jsruntime()) ? 1 : 0);
|
| }
|
| - virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
| + virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) {
|
| callruntime_feedback_slot_ = slot;
|
| }
|
|
|
| - FeedbackVectorSlot CallRuntimeFeedbackSlot() {
|
| + FeedbackVectorICSlot CallRuntimeFeedbackSlot() {
|
| return callruntime_feedback_slot_;
|
| }
|
|
|
| @@ -1981,7 +2012,7 @@ class CallRuntime FINAL : public Expression {
|
| raw_name_(name),
|
| function_(function),
|
| arguments_(arguments),
|
| - callruntime_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
|
| + callruntime_feedback_slot_(FeedbackVectorICSlot::Invalid()) {}
|
|
|
| static int num_ids() { return 1; }
|
| int base_id() const { return Expression::base_id() + Expression::num_ids(); }
|
| @@ -1990,7 +2021,7 @@ class CallRuntime FINAL : public Expression {
|
| const AstRawString* raw_name_;
|
| const Runtime::Function* function_;
|
| ZoneList<Expression*>* arguments_;
|
| - FeedbackVectorSlot callruntime_feedback_slot_;
|
| + FeedbackVectorICSlot callruntime_feedback_slot_;
|
| };
|
|
|
|
|
| @@ -2316,22 +2347,23 @@ class Yield FINAL : public Expression {
|
| }
|
|
|
| // Type feedback information.
|
| - virtual int ComputeFeedbackSlotCount() {
|
| - return (FLAG_vector_ics && yield_kind() == kDelegating) ? 3 : 0;
|
| + virtual FeedbackVectorRequirements ComputeFeedbackRequirements() {
|
| + return FeedbackVectorRequirements(
|
| + 0, (FLAG_vector_ics && yield_kind() == kDelegating) ? 3 : 0);
|
| }
|
| - virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
| + virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) {
|
| yield_first_feedback_slot_ = slot;
|
| }
|
|
|
| - FeedbackVectorSlot KeyedLoadFeedbackSlot() {
|
| + FeedbackVectorICSlot KeyedLoadFeedbackSlot() {
|
| return yield_first_feedback_slot_;
|
| }
|
|
|
| - FeedbackVectorSlot DoneFeedbackSlot() {
|
| + FeedbackVectorICSlot DoneFeedbackSlot() {
|
| return KeyedLoadFeedbackSlot().next();
|
| }
|
|
|
| - FeedbackVectorSlot ValueFeedbackSlot() { return DoneFeedbackSlot().next(); }
|
| + FeedbackVectorICSlot ValueFeedbackSlot() { return DoneFeedbackSlot().next(); }
|
|
|
| protected:
|
| Yield(Zone* zone, Expression* generator_object, Expression* expression,
|
| @@ -2341,14 +2373,14 @@ class Yield FINAL : public Expression {
|
| expression_(expression),
|
| yield_kind_(yield_kind),
|
| index_(-1),
|
| - yield_first_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
|
| + yield_first_feedback_slot_(FeedbackVectorICSlot::Invalid()) {}
|
|
|
| private:
|
| Expression* generator_object_;
|
| Expression* expression_;
|
| Kind yield_kind_;
|
| int index_;
|
| - FeedbackVectorSlot yield_first_feedback_slot_;
|
| + FeedbackVectorICSlot yield_first_feedback_slot_;
|
| };
|
|
|
|
|
| @@ -2498,6 +2530,7 @@ class FunctionLiteral FINAL : public Expression {
|
| int slot_count() {
|
| return ast_properties_.feedback_slots();
|
| }
|
| + int ic_slot_count() { return ast_properties_.ic_feedback_slots(); }
|
| bool dont_optimize() { return dont_optimize_reason_ != kNoReason; }
|
| BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
|
| void set_dont_optimize_reason(BailoutReason reason) {
|
| @@ -2636,12 +2669,14 @@ class SuperReference FINAL : public Expression {
|
| }
|
|
|
| // Type feedback information.
|
| - virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
|
| - virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) {
|
| + virtual FeedbackVectorRequirements ComputeFeedbackRequirements() {
|
| + return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
|
| + }
|
| + virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) {
|
| homeobject_feedback_slot_ = slot;
|
| }
|
|
|
| - FeedbackVectorSlot HomeObjectFeedbackSlot() {
|
| + FeedbackVectorICSlot HomeObjectFeedbackSlot() {
|
| DCHECK(!FLAG_vector_ics || !homeobject_feedback_slot_.IsInvalid());
|
| return homeobject_feedback_slot_;
|
| }
|
| @@ -2650,7 +2685,7 @@ class SuperReference FINAL : public Expression {
|
| SuperReference(Zone* zone, VariableProxy* this_var, int pos, IdGen* id_gen)
|
| : Expression(zone, pos, num_ids(), id_gen),
|
| this_var_(this_var),
|
| - homeobject_feedback_slot_(FeedbackVectorSlot::Invalid()) {
|
| + homeobject_feedback_slot_(FeedbackVectorICSlot::Invalid()) {
|
| DCHECK(this_var->is_this());
|
| }
|
|
|
| @@ -2659,7 +2694,7 @@ class SuperReference FINAL : public Expression {
|
|
|
| private:
|
| VariableProxy* this_var_;
|
| - FeedbackVectorSlot homeobject_feedback_slot_;
|
| + FeedbackVectorICSlot homeobject_feedback_slot_;
|
| };
|
|
|
|
|
| @@ -3123,11 +3158,16 @@ class AstConstructionVisitor BASE_EMBEDDED {
|
| }
|
|
|
| void add_slot_node(AstNode* slot_node) {
|
| - int count = slot_node->ComputeFeedbackSlotCount();
|
| - if (count > 0) {
|
| + FeedbackVectorRequirements reqs = slot_node->ComputeFeedbackRequirements();
|
| + if (reqs.slots() > 0) {
|
| slot_node->SetFirstFeedbackSlot(
|
| FeedbackVectorSlot(properties_.feedback_slots()));
|
| - properties_.increase_feedback_slots(count);
|
| + properties_.increase_feedback_slots(reqs.slots());
|
| + }
|
| + if (reqs.ic_slots() > 0) {
|
| + slot_node->SetFirstFeedbackICSlot(
|
| + FeedbackVectorICSlot(properties_.ic_feedback_slots()));
|
| + properties_.increase_ic_feedback_slots(reqs.ic_slots());
|
| }
|
| }
|
|
|
|
|