Changeset 38925 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Dec 2, 2008, 4:17:24 PM (16 years ago)
Author:
[email protected]
Message:

2008-12-02 Geoffrey Garen <[email protected]>

Reviewed by Sam Weinig.


Cleaned up SegmentedVector by abstracting segment access into helper
functions.


SunSpider reports no change.

  • bytecompiler/SegmentedVector.h: (JSC::SegmentedVector::SegmentedVector): (JSC::SegmentedVector::~SegmentedVector): (JSC::SegmentedVector::size): (JSC::SegmentedVector::at): (JSC::SegmentedVector::operator[]): (JSC::SegmentedVector::last): (JSC::SegmentedVector::append): (JSC::SegmentedVector::removeLast): (JSC::SegmentedVector::grow): (JSC::SegmentedVector::clear): (JSC::SegmentedVector::deleteAllSegments): (JSC::SegmentedVector::segmentFor): (JSC::SegmentedVector::subscriptFor): (JSC::SegmentedVector::ensureSegmentsFor): (JSC::SegmentedVector::ensureSegment):
Location:
trunk/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r38917 r38925  
     12008-12-02  Geoffrey Garen  <[email protected]>
     2
     3        Reviewed by Sam Weinig.
     4       
     5        Cleaned up SegmentedVector by abstracting segment access into helper
     6        functions.
     7       
     8        SunSpider reports no change.
     9
     10        * bytecompiler/SegmentedVector.h:
     11        (JSC::SegmentedVector::SegmentedVector):
     12        (JSC::SegmentedVector::~SegmentedVector):
     13        (JSC::SegmentedVector::size):
     14        (JSC::SegmentedVector::at):
     15        (JSC::SegmentedVector::operator[]):
     16        (JSC::SegmentedVector::last):
     17        (JSC::SegmentedVector::append):
     18        (JSC::SegmentedVector::removeLast):
     19        (JSC::SegmentedVector::grow):
     20        (JSC::SegmentedVector::clear):
     21        (JSC::SegmentedVector::deleteAllSegments):
     22        (JSC::SegmentedVector::segmentFor):
     23        (JSC::SegmentedVector::subscriptFor):
     24        (JSC::SegmentedVector::ensureSegmentsFor):
     25        (JSC::SegmentedVector::ensureSegment):
     26
    1272008-12-02  Geoffrey Garen  <[email protected]>
    228
  • trunk/JavaScriptCore/bytecompiler/SegmentedVector.h

    r38887 r38925  
    3434namespace JSC {
    3535
     36    // SegmentedVector is just like Vector, but it doesn't move the values
     37    // stored in its buffer when it grows. Therefore, it is safe to keep
     38    // pointers into a SegmentedVector.
    3639    template <typename T, size_t SegmentSize> class SegmentedVector {
    3740    public:
    3841        SegmentedVector()
    3942            : m_size(0)
    40             , m_currentSegmentIndex(0)
    4143        {
    4244            m_segments.append(&m_inlineSegment);
     
    4547        ~SegmentedVector()
    4648        {
    47             for (size_t i = 1; i < m_segments.size(); i++)
    48                 delete m_segments[i];
     49            deleteAllSegments();
     50        }
     51
     52        size_t size() const { return m_size; }
     53
     54        T& at(size_t index)
     55        {
     56            if (index < SegmentSize)
     57                return m_inlineSegment[index];
     58            return segmentFor(index)->at(subscriptFor(index));
     59        }
     60
     61        T& operator[](size_t index)
     62        {
     63            return at(index);
    4964        }
    5065
    5166        T& last()
    5267        {
    53             ASSERT(m_size);
    54             return m_segments[m_currentSegmentIndex]->last();
     68            return at(size() - 1);
    5569        }
    5670
    5771        template <typename U> void append(const U& value)
    5872        {
    59             if (!(m_size % SegmentSize) && m_size) {
    60                 if (m_currentSegmentIndex == m_segments.size() - 1)
    61                     m_segments.append(new Segment);
    62                 m_currentSegmentIndex++;
     73            ++m_size;
     74
     75            if (m_size <= SegmentSize) {
     76                m_inlineSegment.uncheckedAppend(value);
     77                return;
    6378            }
    64             m_segments[m_currentSegmentIndex]->uncheckedAppend(value);
    65             m_size++;
     79
     80            if (!segmentExistsFor(m_size - 1))
     81                m_segments.append(new Segment);
     82            segmentFor(m_size - 1)->uncheckedAppend(value);
    6683        }
    6784
    6885        void removeLast()
    6986        {
    70             ASSERT(m_size);
    71             m_size--;
    72             m_segments[m_currentSegmentIndex]->removeLast();
    73             if (!(m_size % SegmentSize) && m_size >= SegmentSize)
    74                 m_currentSegmentIndex--;
     87            if (m_size <= SegmentSize)
     88                m_inlineSegment.removeLast();
     89            else
     90                segmentFor(m_size - 1)->removeLast();
     91            --m_size;
    7592        }
    7693
    77         size_t size() const
     94        void grow(size_t size)
    7895        {
    79             return m_size;
    80         }
    81 
    82         T& operator[](size_t index)
    83         {
    84             ASSERT(index < m_size);
    85             if (index < SegmentSize)
    86                 return m_inlineSegment[index];
    87             return m_segments[index / SegmentSize]->at(index % SegmentSize);
    88         }
    89 
    90         void grow(size_t newSize)
    91         {
    92             if (newSize <= m_size)
    93                 return;
    94 
    95             if (newSize <= SegmentSize) {
    96                 m_inlineSegment.resize(newSize);
    97                 m_size = newSize;
    98                 return;
    99             }
    100 
    101             size_t newNumSegments = newSize / SegmentSize;
    102             size_t extra = newSize % SegmentSize;
    103             if (extra)
    104                 newNumSegments++;
    105             size_t oldNumSegments = m_segments.size();
    106 
    107             if (newNumSegments == oldNumSegments) {
    108                 m_segments.last()->resize(extra);
    109                 m_size = newSize;
    110                 return;
    111             }
    112 
    113             m_segments.last()->resize(SegmentSize);
    114 
    115             m_segments.resize(newNumSegments);
    116 
    117             ASSERT(oldNumSegments < m_segments.size());
    118             for (size_t i = oldNumSegments; i < (newNumSegments - 1); i++) {
    119                 Segment* segment = new Segment;
    120                 segment->resize(SegmentSize);
    121                 m_segments[i] = segment;
    122             }
    123 
    124             Segment* segment = new Segment;
    125             segment->resize(extra ? extra : SegmentSize);
    126             m_currentSegmentIndex = newNumSegments - 1;
    127             m_segments[m_currentSegmentIndex] = segment;
    128             m_size = newSize;
     96            ASSERT(size > m_size);
     97            ensureSegmentsFor(size);
     98            m_size = size;
    12999        }
    130100
    131101        void clear()
    132102        {
    133             for (size_t i = 1; i < m_segments.size(); i++)
    134                 delete m_segments[i];
     103            deleteAllSegments();
    135104            m_segments.resize(1);
    136             m_inlineSegment.resize(0);
    137             m_currentSegmentIndex = 0;
     105            m_inlineSegment.clear();
    138106            m_size = 0;
    139107        }
     
    141109    private:
    142110        typedef Vector<T, SegmentSize> Segment;
     111       
     112        void deleteAllSegments()
     113        {
     114            // Skip the first segment, because it's our inline segment, which was
     115            // not created by new.
     116            for (size_t i = 1; i < m_segments.size(); i++)
     117                delete m_segments[i];
     118        }
     119       
     120        bool segmentExistsFor(size_t index)
     121        {
     122            return index / SegmentSize < m_segments.size();
     123        }
     124       
     125        Segment* segmentFor(size_t index)
     126        {
     127            return m_segments[index / SegmentSize];
     128        }
     129       
     130        size_t subscriptFor(size_t index)
     131        {
     132            return index % SegmentSize;
     133        }
     134       
     135        void ensureSegmentsFor(size_t size)
     136        {
     137            size_t segmentCount = m_size / SegmentSize;
     138            if (m_size % SegmentSize)
     139                ++segmentCount;
     140            segmentCount = std::max<size_t>(segmentCount, 1); // We always have at least our inline segment.
     141
     142            size_t neededSegmentCount = size / SegmentSize;
     143            if (size % SegmentSize)
     144                ++neededSegmentCount;
     145
     146            // Fill up to N - 1 segments.
     147            size_t end = neededSegmentCount - 1;
     148            for (size_t i = segmentCount - 1; i < end; ++i)
     149                ensureSegment(i, SegmentSize);
     150           
     151            // Grow segment N to accomodate the remainder.
     152            ensureSegment(end, subscriptFor(size - 1) + 1);
     153        }
     154
     155        void ensureSegment(size_t segmentIndex, size_t size)
     156        {
     157            ASSERT(segmentIndex <= m_segments.size());
     158            if (segmentIndex == m_segments.size())
     159                m_segments.append(new Segment);
     160            m_segments[segmentIndex]->grow(size);
     161        }
    143162
    144163        size_t m_size;
    145         size_t m_currentSegmentIndex;
    146 
    147164        Segment m_inlineSegment;
    148165        Vector<Segment*, 32> m_segments;
Note: See TracChangeset for help on using the changeset viewer.