Changeset 38856 in webkit for trunk/JavaScriptCore


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).
Location:
trunk/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r38854 r38856  
     12008-12-01  Cameron Zwarich  <[email protected]>
     2
     3        Reviewed by Sam Weinig.
     4
     5        Preliminary work for bug 20340: SegmentedVector segment allocations can lead to unsafe use of temporary registers
     6        <https://bugs.webkit.org/show_bug.cgi?id=20340>
     7
     8        SegmentedVector currently frees segments and reallocates them when used
     9        as a stack. This can lead to unsafe use of pointers into freed segments.
     10
     11        In order to fix this problem, SegmentedVector will be changed to only
     12        grow and never shrink, with the sole exception of clearing all of its
     13        data, a capability that is required by Lexer. This patch changes the
     14        public interface to only allow for these capabilities.
     15
     16        * bytecompiler/BytecodeGenerator.cpp:
     17        (JSC::BytecodeGenerator::BytecodeGenerator): Use reserveCapacity()
     18        instead of resize() for m_globals and m_parameters.
     19        * bytecompiler/SegmentedVector.h:
     20        (JSC::SegmentedVector::resize): Removed.
     21        (JSC::SegmentedVector::reserveCapacity): Added.
     22        (JSC::SegmentedVector::clear): Added.
     23        (JSC::SegmentedVector::shrink): Removed.
     24        (JSC::SegmentedVector::grow): Removed.
     25        * parser/Lexer.cpp:
     26        (JSC::Lexer::clear): Use clear() instead of resize(0).
     27
    1282008-11-30  Sam Weinig  <[email protected]>
    229
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r38635 r38856  
    243243
    244244    // Add previously defined symbols to bookkeeping.
    245     m_globals.resize(symbolTable->size());
     245    m_globals.reserveCapacity(symbolTable->size());
    246246    SymbolTable::iterator end = symbolTable->end();
    247247    for (SymbolTable::iterator it = symbolTable->begin(); it != end; ++it)
     
    342342    size_t parameterCount = functionBody->parameterCount();
    343343    m_nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1;
    344     m_parameters.resize(1 + parameterCount); // reserve space for "this"
     344    m_parameters.reserveCapacity(1 + parameterCount); // reserve space for "this"
    345345
    346346    // Add "this" as a parameter
  • 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;
  • trunk/JavaScriptCore/parser/Lexer.cpp

    r38638 r38856  
    881881void Lexer::clear()
    882882{
    883     m_identifiers.resize(0);
     883    m_identifiers.clear();
    884884
    885885    Vector<char> newBuffer8;
Note: See TracChangeset for help on using the changeset viewer.