Changeset 57912 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Apr 20, 2010, 1:33:56 PM (15 years ago)
Author:
[email protected]
Message:

JavaScriptCore: Add missing .def file entries.

Reviewed by NOBODY (windows build fix).

WebCore: Speculative tiger build fix.

Reviewed by NOBODY (build fix).

  • WebCore.NPAPI.exp:
  • WebCore.PluginHostProcess.exp:
  • WebCore.base.exp:
Location:
trunk/JavaScriptCore/runtime
Files:
4 edited
2 copied

Legend:

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

    r57019 r57912  
    5252    else {
    5353        for (unsigned i = 0; i < m_fiberCount; ++i) {
    54             m_other.m_fibers[i]->deref();
     54            RopeImpl::deref(m_other.m_fibers[i]);
    5555            m_other.m_fibers[i] = 0;
    5656        }
     
    6363    UChar* position = buffer + m_length;
    6464
    65     // Start with the current Rope.
    66     Vector<Rope::Fiber, 32> workQueue;
    67     Rope::Fiber currentFiber;
     65    // Start with the current RopeImpl.
     66    Vector<RopeImpl::Fiber, 32> workQueue;
     67    RopeImpl::Fiber currentFiber;
    6868    for (unsigned i = 0; i < (m_fiberCount - 1); ++i)
    6969        workQueue.append(m_other.m_fibers[i]);
    7070    currentFiber = m_other.m_fibers[m_fiberCount - 1];
    7171    while (true) {
    72         if (currentFiber->isRope()) {
    73             Rope* rope = static_cast<URopeImpl*>(currentFiber);
     72        if (RopeImpl::isRope(currentFiber)) {
     73            RopeImpl* rope = static_cast<RopeImpl*>(currentFiber);
    7474            // Copy the contents of the current rope into the workQueue, with the last item in 'currentFiber'
    7575            // (we will be working backwards over the rope).
     
    8989                ASSERT(buffer == position);
    9090                for (unsigned i = 0; i < m_fiberCount; ++i) {
    91                     m_other.m_fibers[i]->deref();
     91                    RopeImpl::deref(m_other.m_fibers[i]);
    9292                    m_other.m_fibers[i] = 0;
    9393                }
  • trunk/JavaScriptCore/runtime/JSString.h

    r57055 r57912  
    3030#include "PropertyDescriptor.h"
    3131#include "PropertySlot.h"
     32#include "RopeImpl.h"
    3233
    3334namespace JSC {
     
    6768        friend class JSGlobalData;
    6869
    69         typedef URopeImpl Rope;
    70 
    7170        class RopeBuilder {
    7271        public:
    7372            RopeBuilder(unsigned fiberCount)
    7473                : m_index(0)
    75                 , m_rope(Rope::tryCreateUninitialized(fiberCount))
     74                , m_rope(RopeImpl::tryCreateUninitialized(fiberCount))
    7675            {
    7776            }
     
    7978            bool isOutOfMemory() { return !m_rope; }
    8079
    81             void append(Rope::Fiber& fiber)
     80            void append(RopeImpl::Fiber& fiber)
    8281            {
    8382                ASSERT(m_rope);
     
    9897            }
    9998
    100             PassRefPtr<Rope> release()
     99            PassRefPtr<RopeImpl> release()
    101100            {
    102101                ASSERT(m_index == m_rope->fiberCount());
     
    108107        private:
    109108            unsigned m_index;
    110             RefPtr<Rope> m_rope;
     109            RefPtr<RopeImpl> m_rope;
    111110        };
    112111
     
    138137            ASSERT(!m_value.isNull());
    139138        }
    140         JSString(JSGlobalData* globalData, PassRefPtr<Rope> rope)
     139        JSString(JSGlobalData* globalData, PassRefPtr<RopeImpl> rope)
    141140            : JSCell(globalData->stringStructure.get())
    142141            , m_length(rope->length())
     
    217216            ASSERT(vptr() == JSGlobalData::jsStringVPtr);
    218217            for (unsigned i = 0; i < m_fiberCount; ++i)
    219                 m_other.m_fibers[i]->deref();
     218                RopeImpl::deref(m_other.m_fibers[i]);
    220219
    221220            if (!m_fiberCount && m_other.m_finalizerCallback)
     
    269268            if (jsString->isRope()) {
    270269                for (unsigned i = 0; i < jsString->m_fiberCount; ++i) {
    271                     Rope::Fiber fiber = jsString->m_other.m_fibers[i];
     270                    RopeImpl::Fiber fiber = jsString->m_other.m_fibers[i];
    272271                    fiber->ref();
    273272                    m_other.m_fibers[index++] = fiber;
     
    310309        static const unsigned s_maxInternalRopeLength = 3;
    311310
    312         // A string is represented either by a UString or a Rope.
     311        // A string is represented either by a UString or a RopeImpl.
    313312        unsigned m_length;
    314313        mutable UString m_value;
     
    318317            JSStringFinalizerStruct() : m_finalizerCallback(0) {}
    319318            union {
    320                 mutable Rope::Fiber m_fibers[s_maxInternalRopeLength];
     319                mutable RopeImpl::Fiber m_fibers[s_maxInternalRopeLength];
    321320                struct {
    322321                    JSStringFinalizerCallback m_finalizerCallback;
  • trunk/JavaScriptCore/runtime/RopeImpl.cpp

    r57903 r57912  
    2525
    2626#include "config.h"
    27 #include "UStringImpl.h"
    28 
    29 #include "Identifier.h"
    30 #include "StdLibExtras.h"
    31 #include "UString.h"
    32 #include <wtf/unicode/UTF8.h>
    33 
    34 using namespace WTF::Unicode;
    35 using namespace std;
     27#include "RopeImpl.h"
    3628
    3729namespace JSC {
    3830
    39 static const unsigned minLengthToShare = 20;
    40 
    41 UStringImpl::~UStringImpl()
    42 {
    43     ASSERT(!isStatic());
    44 
    45     if (isIdentifier())
    46         Identifier::remove(this);
    47 
    48     BufferOwnership ownership = bufferOwnership();
    49     if (ownership != BufferInternal) {
    50         if (ownership == BufferOwned) {
    51             ASSERT(!m_sharedBuffer);
    52             ASSERT(m_data);
    53             fastFree(const_cast<UChar*>(m_data));
    54         } else if (ownership == BufferSubstring) {
    55             ASSERT(m_substringBuffer);
    56             m_substringBuffer->deref();
    57         } else {
    58             ASSERT(ownership == BufferShared);
    59             ASSERT(m_sharedBuffer);
    60             m_sharedBuffer->deref();
    61         }
    62     }
    63 }
    64 
    65 UStringImpl* UStringImpl::empty()
    66 {
    67     // FIXME: This works around a bug in our port of PCRE, that a regular expression
    68     // run on the empty string may still perform a read from the first element, and
    69     // as such we need this to be a valid pointer. No code should ever be reading
    70     // from a zero length string, so this should be able to be a non-null pointer
    71     // into the zero-page.
    72     // Replace this with 'reinterpret_cast<UChar*>(static_cast<intptr_t>(1))' once
    73     // PCRE goes away.
    74     static UChar emptyUCharData = 0;
    75     DEFINE_STATIC_LOCAL(UStringImpl, emptyString, (&emptyUCharData, 0, ConstructStaticString));
    76     return &emptyString;
    77 }
    78 
    79 PassRefPtr<UStringImpl> UStringImpl::createUninitialized(unsigned length, UChar*& data)
    80 {
    81     if (!length) {
    82         data = 0;
    83         return empty();
    84     }
    85 
    86     // Allocate a single buffer large enough to contain the StringImpl
    87     // struct as well as the data which it contains. This removes one
    88     // heap allocation from this call.
    89     if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar)))
    90         CRASH();
    91     size_t size = sizeof(UStringImpl) + length * sizeof(UChar);
    92     UStringImpl* string = static_cast<UStringImpl*>(fastMalloc(size));
    93 
    94     data = reinterpret_cast<UChar*>(string + 1);
    95     return adoptRef(new (string) UStringImpl(length));
    96 }
    97 
    98 PassRefPtr<UStringImpl> UStringImpl::create(const UChar* characters, unsigned length)
    99 {
    100     if (!characters || !length)
    101         return empty();
    102 
    103     UChar* data;
    104     PassRefPtr<UStringImpl> string = createUninitialized(length, data);
    105     memcpy(data, characters, length * sizeof(UChar));
    106     return string;
    107 }
    108 
    109 PassRefPtr<UStringImpl> UStringImpl::create(const char* characters, unsigned length)
    110 {
    111     if (!characters || !length)
    112         return empty();
    113 
    114     UChar* data;
    115     PassRefPtr<UStringImpl> string = createUninitialized(length, data);
    116     for (unsigned i = 0; i != length; ++i) {
    117         unsigned char c = characters[i];
    118         data[i] = c;
    119     }
    120     return string;
    121 }
    122 
    123 PassRefPtr<UStringImpl> UStringImpl::create(const char* string)
    124 {
    125     if (!string)
    126         return empty();
    127     return create(string, strlen(string));
    128 }
    129 
    130 PassRefPtr<UStringImpl> UStringImpl::create(const UChar* buffer, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
    131 {
    132     if (!length)
    133         return empty();
    134     return adoptRef(new UStringImpl(buffer, length, sharedBuffer));
    135 }
    136 
    137 SharedUChar* UStringImpl::sharedBuffer()
    138 {
    139     if (m_length < minLengthToShare)
    140         return 0;
    141     // All static strings are smaller that the minimim length to share.
    142     ASSERT(!isStatic());
    143 
    144     BufferOwnership ownership = bufferOwnership();
    145 
    146     if (ownership == BufferInternal)
    147         return 0;
    148     if (ownership == BufferSubstring)
    149         return m_substringBuffer->sharedBuffer();
    150     if (ownership == BufferOwned) {
    151         ASSERT(!m_sharedBuffer);
    152         m_sharedBuffer = SharedUChar::create(new SharableUChar(m_data)).releaseRef();
    153         m_refCountAndFlags = (m_refCountAndFlags & ~s_refCountMaskBufferOwnership) | BufferShared;
    154     }
    155 
    156     ASSERT(bufferOwnership() == BufferShared);
    157     ASSERT(m_sharedBuffer);
    158     return m_sharedBuffer;
    159 }
    160 
    161 void URopeImpl::derefFibersNonRecursive(Vector<URopeImpl*, 32>& workQueue)
     31void RopeImpl::derefFibersNonRecursive(Vector<RopeImpl*, 32>& workQueue)
    16232{
    16333    unsigned length = fiberCount();
    16434    for (unsigned i = 0; i < length; ++i) {
    16535        Fiber& fiber = fibers(i);
    166         if (fiber->isRope()) {
    167             URopeImpl* nextRope = static_cast<URopeImpl*>(fiber);
     36        if (isRope(fiber)) {
     37            RopeImpl* nextRope = static_cast<RopeImpl*>(fiber);
    16838            if (nextRope->hasOneRef())
    16939                workQueue.append(nextRope);
     
    17545}
    17646
    177 void URopeImpl::destructNonRecursive()
     47void RopeImpl::destructNonRecursive()
    17848{
    179     Vector<URopeImpl*, 32> workQueue;
     49    Vector<RopeImpl*, 32> workQueue;
    18050
    18151    derefFibersNonRecursive(workQueue);
     
    18353
    18454    while (!workQueue.isEmpty()) {
    185         URopeImpl* rope = workQueue.last();
     55        RopeImpl* rope = workQueue.last();
    18656        workQueue.removeLast();
    18757        rope->derefFibersNonRecursive(workQueue);
  • trunk/JavaScriptCore/runtime/RopeImpl.h

    r57903 r57912  
    11/*
    2  * Copyright (C) 2009 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #ifndef UStringImpl_h
    27 #define UStringImpl_h
     26#ifndef RopeImpl_h
     27#define RopeImpl_h
    2828
    29 #include <limits>
    30 #include <wtf/CrossThreadRefCounted.h>
    31 #include <wtf/OwnFastMallocPtr.h>
    32 #include <wtf/PossiblyNull.h>
    33 #include <wtf/StringHashFunctions.h>
    34 #include <wtf/Vector.h>
    35 #include <wtf/unicode/Unicode.h>
     29#include "UStringImpl.h"
    3630
    3731namespace JSC {
    3832
    39 class IdentifierTable;
     33class RopeImpl : public UStringImplBase {
     34public:
     35    // A RopeImpl is composed from a set of smaller strings called Fibers.
     36    // Each Fiber in a rope is either UStringImpl or another RopeImpl.
     37    typedef UStringImplBase* Fiber;
    4038
    41 typedef OwnFastMallocPtr<const UChar> SharableUChar;
    42 typedef CrossThreadRefCounted<SharableUChar> SharedUChar;
    43 
    44 class UStringOrRopeImpl : public Noncopyable {
    45 public:
    46     bool isRope() { return (m_refCountAndFlags & s_refCountIsRope) == s_refCountIsRope; }
    47     unsigned length() const { return m_length; }
    48 
    49     void ref() { m_refCountAndFlags += s_refCountIncrement; }
    50     inline void deref();
    51 
    52 protected:
    53     enum BufferOwnership {
    54         BufferInternal,
    55         BufferOwned,
    56         BufferSubstring,
    57         BufferShared,
    58     };
    59 
    60     using Noncopyable::operator new;
    61     void* operator new(size_t, void* inPlace) { return inPlace; }
    62 
    63     // For SmallStringStorage, which allocates an array and uses an in-place new.
    64     UStringOrRopeImpl() { }
    65 
    66     UStringOrRopeImpl(unsigned length, BufferOwnership ownership)
    67         : m_refCountAndFlags(s_refCountIncrement | s_refCountFlagShouldReportedCost | ownership)
    68         , m_length(length)
    69     {
    70         ASSERT(!isRope());
    71     }
    72 
    73     enum StaticStringConstructType { ConstructStaticString };
    74     UStringOrRopeImpl(unsigned length, StaticStringConstructType)
    75         : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsIdentifier | BufferOwned)
    76         , m_length(length)
    77     {
    78         ASSERT(!isRope());
    79     }
    80 
    81     enum RopeConstructType { ConstructRope };
    82     UStringOrRopeImpl(RopeConstructType)
    83         : m_refCountAndFlags(s_refCountIncrement | s_refCountIsRope)
    84         , m_length(0)
    85     {
    86         ASSERT(isRope());
    87     }
    88 
    89     // The bottom 5 bits hold flags, the top 27 bits hold the ref count.
    90     // When dereferencing UStringImpls we check for the ref count AND the
    91     // static bit both being zero - static strings are never deleted.
    92     static const unsigned s_refCountMask = 0xFFFFFFE0;
    93     static const unsigned s_refCountIncrement = 0x20;
    94     static const unsigned s_refCountFlagStatic = 0x10;
    95     static const unsigned s_refCountFlagShouldReportedCost = 0x8;
    96     static const unsigned s_refCountFlagIsIdentifier = 0x4;
    97     static const unsigned s_refCountMaskBufferOwnership = 0x3;
    98     // Use an otherwise invalid permutation of flags (static & shouldReportedCost -
    99     // static strings do not set shouldReportedCost in the constructor, and this bit
    100     // is only ever cleared, not set) to identify objects that are ropes.
    101     static const unsigned s_refCountIsRope = s_refCountFlagStatic | s_refCountFlagShouldReportedCost;
    102 
    103     unsigned m_refCountAndFlags;
    104     unsigned m_length;
    105 };
    106 
    107 class UStringImpl : public UStringOrRopeImpl {
    108     friend struct CStringTranslator;
    109     friend struct UCharBufferTranslator;
    110     friend class JIT;
    111     friend class SmallStringsStorage;
    112     friend class UStringOrRopeImpl;
    113     friend void initializeUString();
    114 private:
    115     // For SmallStringStorage, which allocates an array and uses an in-place new.
    116     UStringImpl() { }
    117 
    118     // Used to construct static strings, which have an special refCount that can never hit zero.
    119     // This means that the static string will never be destroyed, which is important because
    120     // static strings will be shared across threads & ref-counted in a non-threadsafe manner.
    121     UStringImpl(const UChar* characters, unsigned length, StaticStringConstructType)
    122         : UStringOrRopeImpl(length, ConstructStaticString)
    123         , m_data(characters)
    124         , m_buffer(0)
    125         , m_hash(0)
    126     {
    127         hash();
    128     }
    129 
    130     // Create a normal string with internal storage (BufferInternal)
    131     UStringImpl(unsigned length)
    132         : UStringOrRopeImpl(length, BufferInternal)
    133         , m_data(reinterpret_cast<UChar*>(this + 1))
    134         , m_buffer(0)
    135         , m_hash(0)
    136     {
    137         ASSERT(m_data);
    138         ASSERT(m_length);
    139     }
    140 
    141     // Create a UStringImpl adopting ownership of the provided buffer (BufferOwned)
    142     UStringImpl(const UChar* characters, unsigned length)
    143         : UStringOrRopeImpl(length, BufferOwned)
    144         , m_data(characters)
    145         , m_buffer(0)
    146         , m_hash(0)
    147     {
    148         ASSERT(m_data);
    149         ASSERT(m_length);
    150     }
    151 
    152     // Used to create new strings that are a substring of an existing UStringImpl (BufferSubstring)
    153     UStringImpl(const UChar* characters, unsigned length, PassRefPtr<UStringImpl> base)
    154         : UStringOrRopeImpl(length, BufferSubstring)
    155         , m_data(characters)
    156         , m_substringBuffer(base.releaseRef())
    157         , m_hash(0)
    158     {
    159         ASSERT(m_data);
    160         ASSERT(m_length);
    161         ASSERT(m_substringBuffer->bufferOwnership() != BufferSubstring);
    162     }
    163 
    164     // Used to construct new strings sharing an existing SharedUChar (BufferShared)
    165     UStringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
    166         : UStringOrRopeImpl(length, BufferShared)
    167         , m_data(characters)
    168         , m_sharedBuffer(sharedBuffer.releaseRef())
    169         , m_hash(0)
    170     {
    171         ASSERT(m_data);
    172         ASSERT(m_length);
    173     }
    174 
    175     // For use only by Identifier's XXXTranslator helpers.
    176     void setHash(unsigned hash)
    177     {
    178         ASSERT(!isStatic());
    179         ASSERT(!m_hash);
    180         ASSERT(hash == computeHash(m_data, m_length));
    181         m_hash = hash;
    182     }
    183 
    184 public:
    185     ~UStringImpl();
    186 
    187     static PassRefPtr<UStringImpl> create(const UChar*, unsigned length);
    188     static PassRefPtr<UStringImpl> create(const char*, unsigned length);
    189     static PassRefPtr<UStringImpl> create(const char*);
    190     static PassRefPtr<UStringImpl> create(const UChar*, unsigned length, PassRefPtr<SharedUChar>);
    191     static PassRefPtr<UStringImpl> create(PassRefPtr<UStringImpl> rep, unsigned offset, unsigned length)
    192     {
    193         ASSERT(rep);
    194         ASSERT(length <= rep->length());
    195 
    196         if (!length)
    197             return empty();
    198 
    199         UStringImpl* ownerRep = (rep->bufferOwnership() == BufferSubstring) ? rep->m_substringBuffer : rep.get();
    200         return adoptRef(new UStringImpl(rep->m_data + offset, length, ownerRep));
    201     }
    202 
    203     static PassRefPtr<UStringImpl> createUninitialized(unsigned length, UChar*& output);
    204     static PassRefPtr<UStringImpl> tryCreateUninitialized(unsigned length, UChar*& output)
    205     {
    206         if (!length) {
    207             output = 0;
    208             return empty();
    209         }
    210 
    211         if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar)))
    212             return 0;
    213         UStringImpl* resultImpl;
    214         if (!tryFastMalloc(sizeof(UChar) * length + sizeof(UStringImpl)).getValue(resultImpl))
    215             return 0;
    216         output = reinterpret_cast<UChar*>(resultImpl + 1);
    217         return adoptRef(new(resultImpl) UStringImpl(length));
    218     }
    219 
    220     template<size_t inlineCapacity>
    221     static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
    222     {
    223         if (size_t size = vector.size()) {
    224             ASSERT(vector.data());
    225             return adoptRef(new UStringImpl(vector.releaseBuffer(), size));
    226         }
    227         return empty();
    228     }
    229 
    230     SharedUChar* sharedBuffer();
    231     const UChar* characters() const { return m_data; }
    232 
    233     size_t cost()
    234     {
    235         // For substrings, return the cost of the base string.
    236         if (bufferOwnership() == BufferSubstring)
    237             return m_substringBuffer->cost();
    238 
    239         if (m_refCountAndFlags & s_refCountFlagShouldReportedCost) {
    240             m_refCountAndFlags &= ~s_refCountFlagShouldReportedCost;
    241             return m_length;
    242         }
    243         return 0;
    244     }
    245 
    246     bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; }
    247     void setIsIdentifier(bool isIdentifier)
    248     {
    249         ASSERT(!isStatic());
    250         if (isIdentifier)
    251             m_refCountAndFlags |= s_refCountFlagIsIdentifier;
    252         else
    253             m_refCountAndFlags &= ~s_refCountFlagIsIdentifier;
    254     }
    255 
    256     unsigned hash() const { if (!m_hash) m_hash = computeHash(m_data, m_length); return m_hash; }
    257     unsigned existingHash() const { ASSERT(m_hash); return m_hash; }
    258     static unsigned computeHash(const UChar* data, unsigned length) { return WTF::stringHash(data, length); }
    259     static unsigned computeHash(const char* data, unsigned length) { return WTF::stringHash(data, length); }
    260     static unsigned computeHash(const char* data) { return WTF::stringHash(data); }
    261 
    262     ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; }
    263 
    264     static UStringImpl* empty();
    265 
    266     static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
    267     {
    268         if (numCharacters <= s_copyCharsInlineCutOff) {
    269             for (unsigned i = 0; i < numCharacters; ++i)
    270                 destination[i] = source[i];
    271         } else
    272             memcpy(destination, source, numCharacters * sizeof(UChar));
    273     }
    274 
    275 private:
    276     // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
    277     static const unsigned s_copyCharsInlineCutOff = 20;
    278 
    279     BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_refCountAndFlags & s_refCountMaskBufferOwnership); }
    280     bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; }
    281 
    282     const UChar* m_data;
    283     union {
    284         void* m_buffer;
    285         UStringImpl* m_substringBuffer;
    286         SharedUChar* m_sharedBuffer;
    287     };
    288     mutable unsigned m_hash;
    289 };
    290 
    291 class URopeImpl : public UStringOrRopeImpl {
    292     friend class UStringOrRopeImpl;
    293 public:
    294     // A URopeImpl is composed from a set of smaller strings called Fibers.
    295     // Each Fiber in a rope is either UStringImpl or another URopeImpl.
    296     typedef UStringOrRopeImpl* Fiber;
    297 
    298     // Creates a URopeImpl comprising of 'fiberCount' Fibers.
    299     // The URopeImpl is constructed in an uninitialized state - initialize must be called for each Fiber in the URopeImpl.
    300     static PassRefPtr<URopeImpl> tryCreateUninitialized(unsigned fiberCount)
     39    // Creates a RopeImpl comprising of 'fiberCount' Fibers.
     40    // The RopeImpl is constructed in an uninitialized state - initialize must be called for each Fiber in the RopeImpl.
     41    static PassRefPtr<RopeImpl> tryCreateUninitialized(unsigned fiberCount)
    30142    {
    30243        void* allocation;
    303         if (tryFastMalloc(sizeof(URopeImpl) + (fiberCount - 1) * sizeof(Fiber)).getValue(allocation))
    304             return adoptRef(new (allocation) URopeImpl(fiberCount));
     44        if (tryFastMalloc(sizeof(RopeImpl) + (fiberCount - 1) * sizeof(Fiber)).getValue(allocation))
     45            return adoptRef(new (allocation) RopeImpl(fiberCount));
    30546        return 0;
    30647    }
     
    31859    ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) destructNonRecursive(); }
    31960
     61    static bool isRope(Fiber fiber)
     62    {
     63        return !fiber->isStringImpl();
     64    }
     65
     66    static void deref(Fiber fiber)
     67    {
     68        if (isRope(fiber))
     69            static_cast<RopeImpl*>(fiber)->deref();
     70        else
     71            static_cast<UStringImpl*>(fiber)->deref();
     72    }
     73
    32074private:
    321     URopeImpl(unsigned fiberCount) : UStringOrRopeImpl(ConstructRope), m_fiberCount(fiberCount) {}
     75    RopeImpl(unsigned fiberCount) : UStringImplBase(ConstructNonStringImpl), m_fiberCount(fiberCount) {}
    32276
    32377    void destructNonRecursive();
    324     void derefFibersNonRecursive(Vector<URopeImpl*, 32>& workQueue);
     78    void derefFibersNonRecursive(Vector<RopeImpl*, 32>& workQueue);
    32579
    32680    bool hasOneRef() { return (m_refCountAndFlags & s_refCountMask) == s_refCountIncrement; }
     
    33084};
    33185
    332 inline void UStringOrRopeImpl::deref()
    333 {
    334     if (isRope())
    335         static_cast<URopeImpl*>(this)->deref();
    336     else
    337         static_cast<UStringImpl*>(this)->deref();
    338 }
    339 
    340 bool equal(const UStringImpl*, const UStringImpl*);
    341 
    34286}
    34387
  • trunk/JavaScriptCore/runtime/UStringImpl.cpp

    r57748 r57912  
    159159}
    160160
    161 void URopeImpl::derefFibersNonRecursive(Vector<URopeImpl*, 32>& workQueue)
    162 {
    163     unsigned length = fiberCount();
    164     for (unsigned i = 0; i < length; ++i) {
    165         Fiber& fiber = fibers(i);
    166         if (fiber->isRope()) {
    167             URopeImpl* nextRope = static_cast<URopeImpl*>(fiber);
    168             if (nextRope->hasOneRef())
    169                 workQueue.append(nextRope);
    170             else
    171                 nextRope->deref();
    172         } else
    173             static_cast<UStringImpl*>(fiber)->deref();
    174     }
    175 }
    176 
    177 void URopeImpl::destructNonRecursive()
    178 {
    179     Vector<URopeImpl*, 32> workQueue;
    180 
    181     derefFibersNonRecursive(workQueue);
    182     delete this;
    183 
    184     while (!workQueue.isEmpty()) {
    185         URopeImpl* rope = workQueue.last();
    186         workQueue.removeLast();
    187         rope->derefFibersNonRecursive(workQueue);
    188         delete rope;
    189     }
    190 }
    191 
    192161} // namespace JSC
  • trunk/JavaScriptCore/runtime/UStringImpl.h

    r57851 r57912  
    4242typedef CrossThreadRefCounted<SharableUChar> SharedUChar;
    4343
    44 class UStringOrRopeImpl : public Noncopyable {
     44class UStringImplBase : public Noncopyable {
    4545public:
    46     bool isRope() { return (m_refCountAndFlags & s_refCountIsRope) == s_refCountIsRope; }
     46    bool isStringImpl() { return (m_refCountAndFlags & s_refCountInvalidForStringImpl) != s_refCountInvalidForStringImpl; }
    4747    unsigned length() const { return m_length; }
    4848
    4949    void ref() { m_refCountAndFlags += s_refCountIncrement; }
    50     inline void deref();
    5150
    5251protected:
     
    6261
    6362    // For SmallStringStorage, which allocates an array and uses an in-place new.
    64     UStringOrRopeImpl() { }
    65 
    66     UStringOrRopeImpl(unsigned length, BufferOwnership ownership)
     63    UStringImplBase() { }
     64
     65    UStringImplBase(unsigned length, BufferOwnership ownership)
    6766        : m_refCountAndFlags(s_refCountIncrement | s_refCountFlagShouldReportedCost | ownership)
    6867        , m_length(length)
    6968    {
    70         ASSERT(!isRope());
     69        ASSERT(isStringImpl());
    7170    }
    7271
    7372    enum StaticStringConstructType { ConstructStaticString };
    74     UStringOrRopeImpl(unsigned length, StaticStringConstructType)
     73    UStringImplBase(unsigned length, StaticStringConstructType)
    7574        : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsIdentifier | BufferOwned)
    7675        , m_length(length)
    7776    {
    78         ASSERT(!isRope());
    79     }
    80 
    81     enum RopeConstructType { ConstructRope };
    82     UStringOrRopeImpl(RopeConstructType)
    83         : m_refCountAndFlags(s_refCountIncrement | s_refCountIsRope)
     77        ASSERT(isStringImpl());
     78    }
     79
     80    // This constructor is not used when creating UStringImpl objects,
     81    // and sets the flags into a state marking the object as such.
     82    enum NonStringImplConstructType { ConstructNonStringImpl };
     83    UStringImplBase(NonStringImplConstructType)
     84        : m_refCountAndFlags(s_refCountIncrement | s_refCountInvalidForStringImpl)
    8485        , m_length(0)
    8586    {
    86         ASSERT(isRope());
     87        ASSERT(!isStringImpl());
    8788    }
    8889
     
    9697    static const unsigned s_refCountFlagIsIdentifier = 0x4;
    9798    static const unsigned s_refCountMaskBufferOwnership = 0x3;
    98     // Use an otherwise invalid permutation of flags (static & shouldReportedCost -
    99     // static strings do not set shouldReportedCost in the constructor, and this bit
    100     // is only ever cleared, not set) to identify objects that are ropes.
    101     static const unsigned s_refCountIsRope = s_refCountFlagStatic | s_refCountFlagShouldReportedCost;
     99    // An invalid permutation of flags (static & shouldReportedCost - static strings do not
     100    // set shouldReportedCost in the constructor, and this bit is only ever cleared, not set).
     101    // Used by "ConstructNonStringImpl" constructor, above.
     102    static const unsigned s_refCountInvalidForStringImpl = s_refCountFlagStatic | s_refCountFlagShouldReportedCost;
    102103
    103104    unsigned m_refCountAndFlags;
     
    105106};
    106107
    107 class UStringImpl : public UStringOrRopeImpl {
     108class UStringImpl : public UStringImplBase {
    108109    friend struct CStringTranslator;
    109110    friend struct UCharBufferTranslator;
    110111    friend class JIT;
    111112    friend class SmallStringsStorage;
    112     friend class UStringOrRopeImpl;
    113113    friend void initializeUString();
    114114private:
     
    120120    // static strings will be shared across threads & ref-counted in a non-threadsafe manner.
    121121    UStringImpl(const UChar* characters, unsigned length, StaticStringConstructType)
    122         : UStringOrRopeImpl(length, ConstructStaticString)
     122        : UStringImplBase(length, ConstructStaticString)
    123123        , m_data(characters)
    124124        , m_buffer(0)
     
    130130    // Create a normal string with internal storage (BufferInternal)
    131131    UStringImpl(unsigned length)
    132         : UStringOrRopeImpl(length, BufferInternal)
     132        : UStringImplBase(length, BufferInternal)
    133133        , m_data(reinterpret_cast<UChar*>(this + 1))
    134134        , m_buffer(0)
     
    141141    // Create a UStringImpl adopting ownership of the provided buffer (BufferOwned)
    142142    UStringImpl(const UChar* characters, unsigned length)
    143         : UStringOrRopeImpl(length, BufferOwned)
     143        : UStringImplBase(length, BufferOwned)
    144144        , m_data(characters)
    145145        , m_buffer(0)
     
    152152    // Used to create new strings that are a substring of an existing UStringImpl (BufferSubstring)
    153153    UStringImpl(const UChar* characters, unsigned length, PassRefPtr<UStringImpl> base)
    154         : UStringOrRopeImpl(length, BufferSubstring)
     154        : UStringImplBase(length, BufferSubstring)
    155155        , m_data(characters)
    156156        , m_substringBuffer(base.releaseRef())
     
    164164    // Used to construct new strings sharing an existing SharedUChar (BufferShared)
    165165    UStringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
    166         : UStringOrRopeImpl(length, BufferShared)
     166        : UStringImplBase(length, BufferShared)
    167167        , m_data(characters)
    168168        , m_sharedBuffer(sharedBuffer.releaseRef())
     
    289289};
    290290
    291 class URopeImpl : public UStringOrRopeImpl {
    292     friend class UStringOrRopeImpl;
    293 public:
    294     // A URopeImpl is composed from a set of smaller strings called Fibers.
    295     // Each Fiber in a rope is either UStringImpl or another URopeImpl.
    296     typedef UStringOrRopeImpl* Fiber;
    297 
    298     // Creates a URopeImpl comprising of 'fiberCount' Fibers.
    299     // The URopeImpl is constructed in an uninitialized state - initialize must be called for each Fiber in the URopeImpl.
    300     static PassRefPtr<URopeImpl> tryCreateUninitialized(unsigned fiberCount)
    301     {
    302         void* allocation;
    303         if (tryFastMalloc(sizeof(URopeImpl) + (fiberCount - 1) * sizeof(Fiber)).getValue(allocation))
    304             return adoptRef(new (allocation) URopeImpl(fiberCount));
    305         return 0;
    306     }
    307 
    308     void initializeFiber(unsigned &index, Fiber fiber)
    309     {
    310         m_fibers[index++] = fiber;
    311         fiber->ref();
    312         m_length += fiber->length();
    313     }
    314 
    315     unsigned fiberCount() { return m_fiberCount; }
    316     Fiber& fibers(unsigned index) { return m_fibers[index]; }
    317 
    318     ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) destructNonRecursive(); }
    319 
    320 private:
    321     URopeImpl(unsigned fiberCount) : UStringOrRopeImpl(ConstructRope), m_fiberCount(fiberCount) {}
    322 
    323     void destructNonRecursive();
    324     void derefFibersNonRecursive(Vector<URopeImpl*, 32>& workQueue);
    325 
    326     bool hasOneRef() { return (m_refCountAndFlags & s_refCountMask) == s_refCountIncrement; }
    327 
    328     unsigned m_fiberCount;
    329     Fiber m_fibers[1];
    330 };
    331 
    332 inline void UStringOrRopeImpl::deref()
    333 {
    334     if (isRope())
    335         static_cast<URopeImpl*>(this)->deref();
    336     else
    337         static_cast<UStringImpl*>(this)->deref();
     291bool equal(const UStringImpl*, const UStringImpl*);
     292
    338293}
    339294
    340 bool equal(const UStringImpl*, const UStringImpl*);
    341 
    342 }
    343 
    344295#endif
Note: See TracChangeset for help on using the changeset viewer.