explicit AstNumberingVisitor(Isolate* isolate, Zone* zone)
: AstVisitor(),
next_id_(BailoutId::FirstUsable().ToInt()),
+ ic_slot_cache_(FLAG_vector_ics ? 4 : 0),
dont_optimize_reason_(kNoReason) {
InitializeAstVisitor(isolate, zone);
}
template <typename Node>
void ReserveFeedbackSlots(Node* node) {
FeedbackVectorRequirements reqs =
- node->ComputeFeedbackRequirements(isolate());
+ node->ComputeFeedbackRequirements(isolate(), &ic_slot_cache_);
if (reqs.slots() > 0) {
node->SetFirstFeedbackSlot(FeedbackVectorSlot(properties_.slots()));
properties_.increase_slots(reqs.slots());
}
if (reqs.ic_slots() > 0) {
int ic_slots = properties_.ic_slots();
- node->SetFirstFeedbackICSlot(FeedbackVectorICSlot(ic_slots));
+ node->SetFirstFeedbackICSlot(FeedbackVectorICSlot(ic_slots),
+ &ic_slot_cache_);
properties_.increase_ic_slots(reqs.ic_slots());
if (FLAG_vector_ics) {
for (int i = 0; i < reqs.ic_slots(); i++) {
int next_id_;
AstProperties properties_;
+ // The slot cache allows us to reuse certain vector IC slots. It's only used
+ // if FLAG_vector_ics is true.
+ ICSlotCache ic_slot_cache_;
BailoutReason dont_optimize_reason_;
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
}
+void VariableProxy::SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
+ ICSlotCache* cache) {
+ variable_feedback_slot_ = slot;
+ if (var()->IsUnallocated()) {
+ cache->Add(VariableICSlotPair(var(), slot));
+ }
+}
+
+
+FeedbackVectorRequirements VariableProxy::ComputeFeedbackRequirements(
+ Isolate* isolate, const ICSlotCache* cache) {
+ if (UsesVariableFeedbackSlot()) {
+ // VariableProxies that point to the same Variable within a function can
+ // make their loads from the same IC slot.
+ if (var()->IsUnallocated()) {
+ for (int i = 0; i < cache->length(); i++) {
+ VariableICSlotPair& pair = cache->at(i);
+ if (pair.variable() == var()) {
+ variable_feedback_slot_ = pair.slot();
+ return FeedbackVectorRequirements(0, 0);
+ }
+ }
+ }
+ return FeedbackVectorRequirements(0, 1);
+ }
+ return FeedbackVectorRequirements(0, 0);
+}
+
+
Assignment::Assignment(Zone* zone, Token::Value op, Expression* target,
Expression* value, int pos)
: Expression(zone, pos),
}
-FeedbackVectorRequirements Call::ComputeFeedbackRequirements(Isolate* isolate) {
+FeedbackVectorRequirements Call::ComputeFeedbackRequirements(
+ Isolate* isolate, const ICSlotCache* cache) {
int ic_slots = IsUsingCallFeedbackICSlot(isolate) ? 1 : 0;
int slots = IsUsingCallFeedbackSlot(isolate) ? 1 : 0;
// A Call uses either a slot or an IC slot.
};
+class VariableICSlotPair FINAL {
+ public:
+ VariableICSlotPair(Variable* variable, FeedbackVectorICSlot slot)
+ : variable_(variable), slot_(slot) {}
+ VariableICSlotPair()
+ : variable_(NULL), slot_(FeedbackVectorICSlot::Invalid()) {}
+
+ Variable* variable() const { return variable_; }
+ FeedbackVectorICSlot slot() const { return slot_; }
+
+ private:
+ Variable* variable_;
+ FeedbackVectorICSlot slot_;
+};
+
+
+typedef List<VariableICSlotPair> ICSlotCache;
+
+
class AstProperties FINAL BASE_EMBEDDED {
public:
class Flags : public EnumSet<AstPropertiesFlag, int> {};
// not really nice, but multiple inheritance would introduce yet another
// vtable entry per node, something we don't want for space reasons.
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
- Isolate* isolate) {
+ Isolate* isolate, const ICSlotCache* cache) {
return FeedbackVectorRequirements(0, 0);
}
virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) { UNREACHABLE(); }
- virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) {
+ virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
+ ICSlotCache* cache) {
UNREACHABLE();
}
// Each ICSlot stores a kind of IC which the participating node should know.
// Type feedback information.
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
- Isolate* isolate) OVERRIDE {
+ Isolate* isolate, const ICSlotCache* cache) OVERRIDE {
return FeedbackVectorRequirements(1, 0);
}
void SetFirstFeedbackSlot(FeedbackVectorSlot slot) OVERRIDE {
}
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
- Isolate* isolate) OVERRIDE {
- return FeedbackVectorRequirements(0, UsesVariableFeedbackSlot() ? 1 : 0);
- }
+ Isolate* isolate, const ICSlotCache* cache) OVERRIDE;
- void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
- variable_feedback_slot_ = slot;
- }
+ void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
+ ICSlotCache* cache) OVERRIDE;
Code::Kind FeedbackICSlotKind(int index) OVERRIDE { return Code::LOAD_IC; }
FeedbackVectorICSlot VariableFeedbackSlot() {
DCHECK(!UsesVariableFeedbackSlot() || !variable_feedback_slot_.IsInvalid());
}
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
- Isolate* isolate) OVERRIDE {
+ Isolate* isolate, const ICSlotCache* cache) OVERRIDE {
return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
}
- void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
+ void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
+ ICSlotCache* cache) OVERRIDE {
property_feedback_slot_ = slot;
}
Code::Kind FeedbackICSlotKind(int index) OVERRIDE {
// Type feedback information.
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
- Isolate* isolate) OVERRIDE;
- void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
+ Isolate* isolate, const ICSlotCache* cache) OVERRIDE;
+ void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
+ ICSlotCache* cache) OVERRIDE {
ic_slot_or_slot_ = slot.ToInt();
}
void SetFirstFeedbackSlot(FeedbackVectorSlot slot) OVERRIDE {
// Type feedback information.
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
- Isolate* isolate) OVERRIDE {
+ Isolate* isolate, const ICSlotCache* cache) OVERRIDE {
return FeedbackVectorRequirements(FLAG_pretenuring_call_new ? 2 : 1, 0);
}
void SetFirstFeedbackSlot(FeedbackVectorSlot slot) OVERRIDE {
return FLAG_vector_ics && is_jsruntime();
}
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
- Isolate* isolate) OVERRIDE {
+ Isolate* isolate, const ICSlotCache* cache) OVERRIDE {
return FeedbackVectorRequirements(0, HasCallRuntimeFeedbackSlot() ? 1 : 0);
}
- void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
+ void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
+ ICSlotCache* cache) OVERRIDE {
callruntime_feedback_slot_ = slot;
}
Code::Kind FeedbackICSlotKind(int index) OVERRIDE { return Code::LOAD_IC; }
return FLAG_vector_ics && (yield_kind() == kDelegating);
}
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
- Isolate* isolate) OVERRIDE {
+ Isolate* isolate, const ICSlotCache* cache) OVERRIDE {
return FeedbackVectorRequirements(0, HasFeedbackSlots() ? 3 : 0);
}
- void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
+ void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
+ ICSlotCache* cache) OVERRIDE {
yield_first_feedback_slot_ = slot;
}
Code::Kind FeedbackICSlotKind(int index) OVERRIDE {
// Type feedback information.
virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
- Isolate* isolate) OVERRIDE {
+ Isolate* isolate, const ICSlotCache* cache) OVERRIDE {
return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
}
- void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
+ void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
+ ICSlotCache* cache) OVERRIDE {
homeobject_feedback_slot_ = slot;
}
Code::Kind FeedbackICSlotKind(int index) OVERRIDE { return Code::LOAD_IC; }