Changeset 53400 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Jan 18, 2010, 4:14:49 AM (15 years ago)
Author:
Csaba Osztrogonác
Message:

Rubber-stamped by Gustavo Noronha Silva.

Rolling out r53391 and r53392 because of random crashes on buildbots.
https://bugs.webkit.org/show_bug.cgi?id=33731

  • bytecode/CodeBlock.h:

(JSC::CallLinkInfo::seenOnce):
(JSC::CallLinkInfo::setSeen):
(JSC::MethodCallLinkInfo::MethodCallLinkInfo):
(JSC::MethodCallLinkInfo::seenOnce):
(JSC::MethodCallLinkInfo::setSeen):

  • jit/JIT.cpp:

(JSC::JIT::unlinkCall):

  • jit/JITPropertyAccess.cpp:

(JSC::JIT::patchMethodCallProto):

  • runtime/UString.cpp:

(JSC::UString::spliceSubstringsWithSeparators):
(JSC::UString::replaceRange):

  • runtime/UString.h:
  • runtime/UStringImpl.cpp:

(JSC::UStringImpl::baseSharedBuffer):
(JSC::UStringImpl::sharedBuffer):
(JSC::UStringImpl::~UStringImpl):

  • runtime/UStringImpl.h:

(JSC::UntypedPtrAndBitfield::UntypedPtrAndBitfield):
(JSC::UntypedPtrAndBitfield::asPtr):
(JSC::UntypedPtrAndBitfield::operator&=):
(JSC::UntypedPtrAndBitfield::operator|=):
(JSC::UntypedPtrAndBitfield::operator&):
(JSC::UStringImpl::create):
(JSC::UStringImpl::cost):
(JSC::UStringImpl::isIdentifier):
(JSC::UStringImpl::setIsIdentifier):
(JSC::UStringImpl::ref):
(JSC::UStringImpl::deref):
(JSC::UStringImpl::checkConsistency):
(JSC::UStringImpl::UStringImpl):
(JSC::UStringImpl::bufferOwnerString):
(JSC::UStringImpl::bufferOwnership):
(JSC::UStringImpl::isStatic):

  • wtf/StringHashFunctions.h:

(WTF::stringHash):

Location:
trunk/JavaScriptCore/runtime
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/UString.cpp

    r53392 r53400  
    349349UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const
    350350{
     351    m_rep->checkConsistency();
     352
    351353    if (rangeCount == 1 && separatorCount == 0) {
    352354        int thisSize = size();
     
    390392UString UString::replaceRange(int rangeStart, int rangeLength, const UString& replacement) const
    391393{
     394    m_rep->checkConsistency();
     395
    392396    int replacementLength = replacement.size();
    393397    int totalLength = size() - rangeLength + replacementLength;
  • trunk/JavaScriptCore/runtime/UString.h

    r53391 r53400  
    3232#include <wtf/OwnFastMallocPtr.h>
    3333#include <wtf/PassRefPtr.h>
     34#include <wtf/PtrAndFlags.h>
    3435#include <wtf/RefPtr.h>
    3536#include <wtf/Vector.h>
  • trunk/JavaScriptCore/runtime/UStringImpl.cpp

    r53392 r53400  
    3636namespace JSC {
    3737 
     38SharedUChar* UStringImpl::baseSharedBuffer()
     39{
     40    ASSERT((bufferOwnership() == BufferShared)
     41        || ((bufferOwnership() == BufferOwned) && !m_dataBuffer.asPtr<void*>()));
     42
     43    if (bufferOwnership() != BufferShared)
     44        m_dataBuffer = UntypedPtrAndBitfield(SharedUChar::create(new OwnFastMallocPtr<UChar>(m_data)).releaseRef(), BufferShared);
     45
     46    return m_dataBuffer.asPtr<SharedUChar*>();
     47}
     48
    3849SharedUChar* UStringImpl::sharedBuffer()
    3950{
    40     if (m_length < s_minLengthToShare || isStatic())
     51    if (m_length < s_minLengthToShare)
     52        return 0;
     53    ASSERT(!isStatic());
     54
     55    UStringImpl* owner = bufferOwnerString();
     56    if (owner->bufferOwnership() == BufferInternal)
    4157        return 0;
    4258
    43     switch (bufferOwnership()) {
    44     case BufferInternal:
    45         return 0;
    46     case BufferOwned:
    47         m_bufferShared = SharedUChar::create(new OwnFastMallocPtr<UChar>(m_data)).releaseRef();
    48         m_refCountAndFlags &= ~s_refCountMaskBufferOwnership;
    49         m_refCountAndFlags |= BufferShared;
    50         return m_bufferShared;
    51     case BufferSubstring:
    52         return m_bufferSubstring->sharedBuffer();
    53     case BufferShared:
    54         return m_bufferShared;
    55     }
    56 
    57     ASSERT_NOT_REACHED();
    58     return 0;
     59    return owner->baseSharedBuffer();
    5960}
    6061
     
    6263{
    6364    ASSERT(!isStatic());
     65    checkConsistency();
    6466
    6567    if (isIdentifier())
    6668        Identifier::remove(this);
    6769
    68     switch (bufferOwnership()) {
    69     case BufferInternal:
    70         return;
    71     case BufferOwned:
    72         fastFree(m_data);
    73         return;
    74     case BufferSubstring:
    75         m_bufferSubstring->deref();
    76         return;
    77     case BufferShared:
    78         m_bufferSubstring->deref();
     70    if (bufferOwnership() != BufferInternal) {
     71        if (bufferOwnership() == BufferOwned)
     72            fastFree(m_data);
     73        else if (bufferOwnership() == BufferSubstring)
     74            m_dataBuffer.asPtr<UStringImpl*>()->deref();
     75        else {
     76            ASSERT(bufferOwnership() == BufferShared);
     77            m_dataBuffer.asPtr<SharedUChar*>()->deref();
     78        }
    7979    }
    8080}
    8181
    82 } // namespace JSC
     82}
  • trunk/JavaScriptCore/runtime/UStringImpl.h

    r53392 r53400  
    4141typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar;
    4242
     43class UntypedPtrAndBitfield {
     44public:
     45    UntypedPtrAndBitfield() {}
     46
     47    UntypedPtrAndBitfield(void* ptrValue, uintptr_t bitValue)
     48        : m_value(reinterpret_cast<uintptr_t>(ptrValue) | bitValue)
     49#ifndef NDEBUG
     50        , m_leaksPtr(ptrValue)
     51#endif
     52    {
     53        ASSERT(ptrValue == asPtr<void*>());
     54        ASSERT((*this & ~s_alignmentMask) == bitValue);
     55    }
     56
     57    template<typename T>
     58    T asPtr() const { return reinterpret_cast<T>(m_value & s_alignmentMask); }
     59
     60    UntypedPtrAndBitfield& operator&=(uintptr_t bits)
     61    {
     62        m_value &= bits | s_alignmentMask;
     63        return *this;
     64    }
     65
     66    UntypedPtrAndBitfield& operator|=(uintptr_t bits)
     67    {
     68        m_value |= bits & ~s_alignmentMask;
     69        return *this;
     70    }
     71
     72    uintptr_t operator&(uintptr_t mask) const
     73    {
     74        return m_value & mask & ~s_alignmentMask;
     75    }
     76
     77private:
     78    static const uintptr_t s_alignmentMask = ~static_cast<uintptr_t>(0x7);
     79    uintptr_t m_value;
     80#ifndef NDEBUG
     81        void* m_leaksPtr; // Only used to allow tools like leaks on OSX to detect that the memory is referenced.
     82#endif
     83};
     84
    4385class UStringImpl : Noncopyable {
    4486public:
     
    64106    {
    65107        ASSERT(rep);
    66         if (rep->bufferOwnership() == BufferSubstring)
    67             return adoptRef(new UStringImpl(rep->m_data + offset, length, rep->m_bufferSubstring));
    68         return adoptRef(new UStringImpl(rep->m_data + offset, length, rep));
     108        rep->checkConsistency();
     109        return adoptRef(new UStringImpl(rep->m_data + offset, length, rep->bufferOwnerString()));
    69110    }
    70111
     
    111152        // For substrings, return the cost of the base string.
    112153        if (bufferOwnership() == BufferSubstring)
    113             return m_bufferSubstring->cost();
    114         if (m_refCountAndFlags & s_refCountFlagHasReportedCost)
     154            return m_dataBuffer.asPtr<UStringImpl*>()->cost();
     155
     156        if (m_dataBuffer & s_reportedCostBit)
    115157            return 0;
    116         ASSERT(!isStatic());
    117         m_refCountAndFlags |= s_refCountFlagHasReportedCost;
     158        m_dataBuffer |= s_reportedCostBit;
    118159        return m_length;
    119160    }
     
    121162    unsigned existingHash() const { ASSERT(m_hash); return m_hash; } // fast path for Identifiers
    122163    void setHash(unsigned hash) { ASSERT(hash == computeHash(data(), m_length)); m_hash = hash; } // fast path for Identifiers
    123     bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; }
    124     void setIsIdentifier(bool isIdentifier)
    125     {
    126         ASSERT(!isStatic());
    127         if (isIdentifier)
    128             m_refCountAndFlags |= s_refCountFlagIsIdentifier;
    129         else
    130             m_refCountAndFlags &= ~s_refCountFlagIsIdentifier;
    131     }
    132 
    133     UStringImpl* ref() { m_refCountAndFlags += s_refCountIncrement; return this; }
    134     ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) delete this; }
     164    bool isIdentifier() const { return m_isIdentifier; }
     165    void setIsIdentifier(bool isIdentifier) { m_isIdentifier = isIdentifier; }
     166
     167    UStringImpl* ref() { m_refCount += s_refCountIncrement; return this; }
     168    ALWAYS_INLINE void deref() { if (!(m_refCount -= s_refCountIncrement)) delete this; }
    135169
    136170    static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
     
    149183    static UStringImpl& null() { return *s_null; }
    150184    static UStringImpl& empty() { return *s_empty; }
     185
     186    ALWAYS_INLINE void checkConsistency() const
     187    {
     188        // There is no recursion of substrings.
     189        ASSERT(bufferOwnerString()->bufferOwnership() != BufferSubstring);
     190        // Static strings cannot be put in identifier tables, because they are globally shared.
     191        ASSERT(!isStatic() || !isIdentifier());
     192    }
    151193
    152194private:
     
    164206    UStringImpl(UChar* data, int length, BufferOwnership ownership)
    165207        : m_data(data)
    166         , m_buffer(0)
    167208        , m_length(length)
    168         , m_refCountAndFlags(s_refCountIncrement | ownership)
     209        , m_refCount(s_refCountIncrement)
    169210        , m_hash(0)
     211        , m_isIdentifier(false)
     212        , m_dataBuffer(0, ownership)
    170213    {
    171214        ASSERT((ownership == BufferInternal) || (ownership == BufferOwned));
     215        checkConsistency();
    172216    }
    173217
     
    178222    UStringImpl(UChar* data, int length, StaticStringConstructType)
    179223        : m_data(data)
    180         , m_buffer(0)
    181224        , m_length(length)
    182         , m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagHasReportedCost | BufferOwned)
     225        , m_refCount(s_staticRefCountInitialValue)
    183226        , m_hash(0)
    184     {
     227        , m_isIdentifier(false)
     228        , m_dataBuffer(0, BufferOwned)
     229    {
     230        checkConsistency();
    185231    }
    186232
     
    188234    UStringImpl(UChar* data, int length, PassRefPtr<UStringImpl> base)
    189235        : m_data(data)
    190         , m_bufferSubstring(base.releaseRef())
    191236        , m_length(length)
    192         , m_refCountAndFlags(s_refCountIncrement | BufferSubstring)
     237        , m_refCount(s_refCountIncrement)
    193238        , m_hash(0)
     239        , m_isIdentifier(false)
     240        , m_dataBuffer(base.releaseRef(), BufferSubstring)
    194241    {
    195242        // Do use static strings as a base for substrings; UntypedPtrAndBitfield assumes
    196243        // that all pointers will be at least 8-byte aligned, we cannot guarantee that of
    197244        // UStringImpls that are not heap allocated.
    198         ASSERT(m_bufferSubstring->size());
    199         ASSERT(!m_bufferSubstring->isStatic());
    200         ASSERT(m_bufferSubstring->bufferOwnership() != BufferSubstring);
     245        ASSERT(m_dataBuffer.asPtr<UStringImpl*>()->size());
     246        ASSERT(!m_dataBuffer.asPtr<UStringImpl*>()->isStatic());
     247        checkConsistency();
    201248    }
    202249
     
    204251    UStringImpl(UChar* data, int length, PassRefPtr<SharedUChar> sharedBuffer)
    205252        : m_data(data)
    206         , m_bufferShared(sharedBuffer.releaseRef())
    207253        , m_length(length)
    208         , m_refCountAndFlags(s_refCountIncrement | BufferShared)
     254        , m_refCount(s_refCountIncrement)
    209255        , m_hash(0)
    210     {
     256        , m_isIdentifier(false)
     257        , m_dataBuffer(sharedBuffer.releaseRef(), BufferShared)
     258    {
     259        checkConsistency();
    211260    }
    212261
     
    217266
    218267    // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
    219     static const unsigned s_minLengthToShare = 10;
     268    static const int s_minLengthToShare = 10;
    220269    static const unsigned s_copyCharsInlineCutOff = 20;
    221 
    222     bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; }
    223     BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_refCountAndFlags & s_refCountMaskBufferOwnership); }
    224 
     270    static const uintptr_t s_bufferOwnershipMask = 3;
     271    static const uintptr_t s_reportedCostBit = 4;
    225272    // We initialize and increment/decrement the refCount for all normal (non-static) strings by the value 2.
    226273    // We initialize static strings with an odd number (specifically, 1), such that the refCount cannot reach zero.
    227     static const unsigned s_refCountMask = 0xFFFFFFF0;
    228     static const unsigned s_refCountIncrement = 0x20;
    229     static const unsigned s_refCountFlagStatic = 0x10;
    230     static const unsigned s_refCountFlagHasReportedCost = 0x8;
    231     static const unsigned s_refCountFlagIsIdentifier = 0x4;
    232     static const unsigned s_refCountMaskBufferOwnership = 0x3;
    233 
     274    static const int s_refCountIncrement = 2;
     275    static const int s_staticRefCountInitialValue = 1;
     276
     277    UStringImpl* bufferOwnerString() { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() :  this; }
     278    const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() :  this; }
     279    SharedUChar* baseSharedBuffer();
     280    unsigned bufferOwnership() const { return m_dataBuffer & s_bufferOwnershipMask; }
     281    bool isStatic() const { return m_refCount & 1; }
     282
     283    // unshared data
    234284    UChar* m_data;
    235     union {
    236         void* m_buffer;
    237         UStringImpl* m_bufferSubstring;
    238         SharedUChar* m_bufferShared;
    239     };
    240     unsigned m_length;
    241     unsigned m_refCountAndFlags;
    242     mutable unsigned m_hash;
     285    int m_length;
     286    unsigned m_refCount;
     287    mutable unsigned m_hash : 31;
     288    mutable unsigned m_isIdentifier : 1;
     289    UntypedPtrAndBitfield m_dataBuffer;
    243290
    244291    JS_EXPORTDATA static UStringImpl* s_null;
Note: See TracChangeset for help on using the changeset viewer.