diff --git a/js/src/jit/BacktrackingAllocator.cpp b/js/src/jit/BacktrackingAllocator.cpp index 14a35bea2..ce2bc6569 100644 --- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -71,11 +71,39 @@ InsertSortedList(InlineForwardList &list, T* value) // LiveRange ///////////////////////////////////////////////////////////////////// +inline void +LiveRange::noteAddedUse(UsePosition* use) +{ + LUse::Policy policy = use->usePolicy(); + usesSpillWeight_ += BacktrackingAllocator::SpillWeightFromUsePolicy(policy); + if (policy == LUse::FIXED) + ++numFixedUses_; +} + +inline void +LiveRange::noteRemovedUse(UsePosition* use) +{ + LUse::Policy policy = use->usePolicy(); + usesSpillWeight_ -= BacktrackingAllocator::SpillWeightFromUsePolicy(policy); + if (policy == LUse::FIXED) + --numFixedUses_; + MOZ_ASSERT_IF(!hasUses(), !usesSpillWeight_ && !numFixedUses_); +} + void LiveRange::addUse(UsePosition* use) { MOZ_ASSERT(covers(use->pos)); InsertSortedList(uses_, use); + noteAddedUse(use); +} + +UsePosition* +LiveRange::popUse() +{ + UsePosition* ret = uses_.popFront(); + noteRemovedUse(ret); + return ret; } void @@ -89,6 +117,7 @@ LiveRange::distributeUses(LiveRange* other) UsePosition* use = *iter; if (other->covers(use->pos)) { uses_.removeAndIncrement(iter); + noteRemovedUse(use); other->addUse(use); } else { iter++; @@ -2494,28 +2523,9 @@ BacktrackingAllocator::computeSpillWeight(LiveBundle* bundle) } } - for (UsePositionIterator iter = range->usesBegin(); iter; iter++) { - LUse* use = iter->use; - - switch (use->policy()) { - case LUse::ANY: - usesTotal += 1000; - break; - - case LUse::FIXED: - fixed = true; - case LUse::REGISTER: - usesTotal += 2000; - break; - - case LUse::KEEPALIVE: - break; - - default: - // Note: RECOVERED_INPUT will not appear in UsePositionIterator. - MOZ_CRASH("Bad use"); - } - } + usesTotal += range->usesSpillWeight(); + if (range->numFixedUses() > 0) + fixed = true; } // Bundles with fixed uses are given a higher spill weight, since they must diff --git a/js/src/jit/BacktrackingAllocator.h b/js/src/jit/BacktrackingAllocator.h index 8cff8e23d..67bb9a9a5 100644 --- a/js/src/jit/BacktrackingAllocator.h +++ b/js/src/jit/BacktrackingAllocator.h @@ -123,6 +123,8 @@ class Requirement CodePosition position_; }; +// We may want the cache-friendlier version in +// https://hg.mozilla.org/mozilla-central/raw-file/df79199f9f0fcde01ddc2eccf2a5368cb7b801aa/js/src/jit/BacktrackingAllocator.h struct UsePosition : public TempObject, public InlineForwardListNode { @@ -141,6 +143,9 @@ struct UsePosition : public TempObject, ? CodePosition::INPUT : CodePosition::OUTPUT)); } + LUse::Policy usePolicy() const { + return use->policy(); + } }; typedef InlineForwardListIterator UsePositionIterator; @@ -231,15 +236,29 @@ class LiveRange : public TempObject // All uses of the virtual register in this range, ordered by location. InlineForwardList uses_; + // Total spill weight that calculate from all the uses' policy. Because the + // use's policy can't be changed after initialization, we can update the + // weight whenever a use is added to or remove from this range. This way, we + // don't need to iterate all the uses every time computeSpillWeight() is + // called. + size_t usesSpillWeight_; + + // Number of uses that have policy LUse::FIXED. + uint32_t numFixedUses_; + // Whether this range contains the virtual register's definition. bool hasDefinition_; LiveRange(uint32_t vreg, Range range) - : vreg_(vreg), bundle_(nullptr), range_(range), hasDefinition_(false) + : vreg_(vreg), bundle_(nullptr), range_(range), usesSpillWeight_(0), + numFixedUses_(0), hasDefinition_(false) { MOZ_ASSERT(!range.empty()); } + void noteAddedUse(UsePosition* use); + void noteRemovedUse(UsePosition* use); + public: static LiveRange* New(TempAllocator& alloc, uint32_t vreg, CodePosition from, CodePosition to) { @@ -287,9 +306,7 @@ class LiveRange : public TempObject bool hasUses() const { return !!usesBegin(); } - UsePosition* popUse() { - return uses_.popFront(); - } + UsePosition* popUse(); bool hasDefinition() const { return hasDefinition_; @@ -316,6 +333,13 @@ class LiveRange : public TempObject hasDefinition_ = true; } + size_t usesSpillWeight() { + return usesSpillWeight_; + } + uint32_t numFixedUses() { + return numFixedUses_; + } + // Return a string describing this range. This is not re-entrant! #ifdef DEBUG const char* toString() const; @@ -636,6 +660,20 @@ class BacktrackingAllocator : protected RegisterAllocator bool go(); + static size_t SpillWeightFromUsePolicy(LUse::Policy policy) { + switch (policy) { + case LUse::ANY: + return 1000; + + case LUse::REGISTER: + case LUse::FIXED: + return 2000; + + default: + return 0; + } + } + private: typedef Vector LiveRangeVector;