Ignore:
Timestamp:
Dec 1, 2008, 1:07:07 AM (16 years ago)
Author:
[email protected]
Message:

2008-12-01 Cameron Zwarich <[email protected]>

Reviewed by Sam Weinig.

Preliminary work for bug 20340: SegmentedVector segment allocations can lead to unsafe use of temporary registers
<https://bugs.webkit.org/show_bug.cgi?id=20340>

SegmentedVector currently frees segments and reallocates them when used
as a stack. This can lead to unsafe use of pointers into freed segments.

In order to fix this problem, SegmentedVector will be changed to only
grow and never shrink, with the sole exception of clearing all of its
data, a capability that is required by Lexer. This patch changes the
public interface to only allow for these capabilities.

  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::BytecodeGenerator): Use reserveCapacity() instead of resize() for m_globals and m_parameters.
  • bytecompiler/SegmentedVector.h: (JSC::SegmentedVector::resize): Removed. (JSC::SegmentedVector::reserveCapacity): Added. (JSC::SegmentedVector::clear): Added. (JSC::SegmentedVector::shrink): Removed. (JSC::SegmentedVector::grow): Removed.
  • parser/Lexer.cpp: (JSC::Lexer::clear): Use clear() instead of resize(0).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/bytecompiler/SegmentedVector.h

    r38632 r38856  
    8686        }
    8787
    88         void resize(size_t size)
     88        void reserveCapacity(size_t newCapacity)
    8989        {
    90             if (size < m_size)
    91                 shrink(size);
    92             else if (size > m_size)
    93                 grow(size);
    94             ASSERT(size == m_size);
    95         }
     90            if (newCapacity <= m_size)
     91                return;
    9692
    97     private:
    98         void shrink(size_t size)
    99         {
    100             ASSERT(size < m_size);
    101             size_t numSegments = size / SegmentSize;
    102             size_t extra = size % SegmentSize;
    103             if (extra)
    104                 numSegments++;
    105             if (!numSegments) {
    106                 for (size_t i = 1; i < m_segments.size(); i++)
    107                     delete m_segments[i];
    108                 m_segments.resize(1);
    109                 m_inlineSegment.resize(0);
    110                 m_size = size;
     93            if (newCapacity <= SegmentSize) {
     94                m_inlineSegment.resize(newCapacity);
     95                m_size = newCapacity;
    11196                return;
    11297            }
    11398
    114             for (size_t i = numSegments; i < m_segments.size(); i++)
    115                 delete m_segments[i];
    116 
    117             m_segments.resize(numSegments);
    118             if (extra)
    119                 m_segments.last()->resize(extra);
    120             m_size = size;
    121         }
    122 
    123         void grow(size_t size)
    124         {
    125             ASSERT(size > m_size);
    126             if (size <= SegmentSize) {
    127                 m_inlineSegment.resize(size);
    128                 m_size = size;
    129                 return;
    130             }
    131 
    132             size_t numSegments = size / SegmentSize;
    133             size_t extra = size % SegmentSize;
     99            size_t numSegments = newCapacity / SegmentSize;
     100            size_t extra = newCapacity % SegmentSize;
    134101            if (extra)
    135102                numSegments++;
     
    138105            if (numSegments == oldSize) {
    139106                m_segments.last()->resize(extra);
    140                 m_size = size;
     107                m_size = newCapacity;
    141108                return;
    142109            }
     
    156123            segment->resize(extra ? extra : SegmentSize);
    157124            m_segments[numSegments - 1] = segment;
    158             m_size = size;
     125            m_size = newCapacity;
    159126        }
    160127
     128        void clear()
     129        {
     130            for (size_t i = 1; i < m_segments.size(); i++)
     131                delete m_segments[i];
     132            m_segments.resize(1);
     133            m_inlineSegment.resize(0);
     134            m_size = 0;
     135        }
     136
     137    private:
    161138        typedef Vector<T, SegmentSize> Segment;
    162139        size_t m_size;
Note: See TracChangeset for help on using the changeset viewer.