Changeset 57912 in webkit for trunk/JavaScriptCore


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
Files:
9 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r57908 r57912  
    66
    77        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
     8
     92010-04-20  Gavin Barraclough  <[email protected]>
     10
     11        Reviewed by Geoff Garen.
     12
     13        Bug 37869 - Move URopeImpl to its own .h/.cpp
     14       
     15        Currently Ropes are implemented by the class URopeImpl, which is defined in
     16        UStringImpl.h, and then typedefed to the name JSString::Rope. Remove the
     17        typedef, and rename all uses of URopeImpl and JSString::Rope to just RopeImpl.
     18
     19        Move RopeImpl to its own header, and remove all remaining references to ropes
     20        from UStringImpl (rename UStringOrRopeImpl to UStringImplBase, rename or move
     21        the isRope & deref methods from UStringOrRopeImpl).
     22
     23        * JavaScriptCore.xcodeproj/project.pbxproj:
     24        * runtime/JSString.cpp:
     25        (JSC::JSString::resolveRope):
     26        * runtime/JSString.h:
     27        (JSC::):
     28        (JSC::RopeBuilder::JSString):
     29        (JSC::RopeBuilder::~JSString):
     30        (JSC::RopeBuilder::appendStringInConstruct):
     31        (JSC::RopeBuilder::JSStringFinalizerStruct::):
     32        * runtime/RopeImpl.cpp: Copied from JavaScriptCore/runtime/UStringImpl.cpp.
     33        (JSC::RopeImpl::derefFibersNonRecursive):
     34        (JSC::RopeImpl::destructNonRecursive):
     35        * runtime/RopeImpl.h: Copied from JavaScriptCore/runtime/UStringImpl.h.
     36        (JSC::RopeImpl::tryCreateUninitialized):
     37        (JSC::RopeImpl::isRope):
     38        (JSC::RopeImpl::deref):
     39        (JSC::RopeImpl::RopeImpl):
     40        * runtime/UStringImpl.cpp:
     41        * runtime/UStringImpl.h:
     42        (JSC::UStringImplBase::isInvalid):
     43        (JSC::UStringImplBase::ref):
     44        (JSC::UStringImplBase::UStringImplBase):
     45        (JSC::UStringImplBase::):
     46        (JSC::UStringImpl::UStringImpl):
    847
    9482010-04-20  Gavin Barraclough  <[email protected]>
  • trunk/JavaScriptCore/GNUmakefile.am

    r57904 r57912  
    499499        JavaScriptCore/runtime/RegExpPrototype.cpp \
    500500        JavaScriptCore/runtime/RegExpPrototype.h \
     501        JavaScriptCore/runtime/RopeImpl.cpp \
     502        JavaScriptCore/runtime/RopeImpl.h \
    501503        JavaScriptCore/runtime/ScopeChain.cpp \
    502504        JavaScriptCore/runtime/ScopeChain.h \
  • trunk/JavaScriptCore/JavaScriptCore.pro

    r57904 r57912  
    178178    runtime/RegExpObject.cpp \
    179179    runtime/RegExpPrototype.cpp \
     180    runtime/RopeImpl.cpp \
    180181    runtime/ScopeChain.cpp \
    181182    runtime/SmallStrings.cpp \
  • trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

    r57192 r57912  
    11391139                        <File
    11401140                                RelativePath="..\..\runtime\RegExpPrototype.h"
     1141                                >
     1142                        </File>
     1143                        <File
     1144                                RelativePath="..\..\runtime\RopeImpl.cpp"
     1145                                >
     1146                        </File>
     1147                        <File
     1148                                RelativePath="..\..\runtime\RopeImpl.h"
    11411149                                >
    11421150                        </File>
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r57904 r57912  
    215215                86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */; };
    216216                86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */; };
     217                86B99AB8117E391E00DF5A90 /* RopeImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */; };
     218                86B99AB9117E391E00DF5A90 /* RopeImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AB7117E391E00DF5A90 /* RopeImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
    217219                86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; };
    218220                86CA032E1038E8440028A609 /* Executable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CA032D1038E8440028A609 /* Executable.cpp */; };
     
    754756                86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; };
    755757                86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerARMv7.h; sourceTree = "<group>"; };
     758                86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RopeImpl.cpp; sourceTree = "<group>"; };
     759                86B99AB7117E391E00DF5A90 /* RopeImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RopeImpl.h; sourceTree = "<group>"; };
    756760                86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssembler.h; sourceTree = "<group>"; };
    757761                86CA032D1038E8440028A609 /* Executable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Executable.cpp; sourceTree = "<group>"; };
     
    16251629                                BCD202BF0E1706A7002C7E82 /* RegExpPrototype.cpp */,
    16261630                                BCD202C00E1706A7002C7E82 /* RegExpPrototype.h */,
     1631                                86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */,
     1632                                86B99AB7117E391E00DF5A90 /* RopeImpl.h */,
    16271633                                9374D3A8038D9D74008635CE /* ScopeChain.cpp */,
    16281634                                9374D3A7038D9D74008635CE /* ScopeChain.h */,
     
    20742080                                868BFA18117CF19900B908B1 /* WTFString.h in Headers */,
    20752081                                868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */,
     2082                                86B99AB9117E391E00DF5A90 /* RopeImpl.h in Headers */,
    20762083                        );
    20772084                        runOnlyForDeploymentPostprocessing = 0;
     
    25212528                                868BFA0E117CEFD100B908B1 /* StringImpl.cpp in Sources */,
    25222529                                868BFA17117CF19900B908B1 /* WTFString.cpp in Sources */,
     2530                                86B99AB8117E391E00DF5A90 /* RopeImpl.cpp in Sources */,
    25232531                        );
    25242532                        runOnlyForDeploymentPostprocessing = 0;
  • 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.