Changeset 58712 in webkit


Ignore:
Timestamp:
May 3, 2010, 4:03:37 PM (15 years ago)
Author:
[email protected]
Message:

Rolling out r58114 - this introduced memory leaks of
AtomicStrings then workers terminated.

Reviewed by NOBODY (reverting previous commit).

(JSC::ThunkHelpers::stringImplDataOffset):

  • runtime/Identifier.cpp:

(JSC::IdentifierTable::~IdentifierTable):
(JSC::IdentifierTable::add):
(JSC::IdentifierCStringTranslator::hash):
(JSC::IdentifierCStringTranslator::equal):
(JSC::IdentifierCStringTranslator::translate):
(JSC::Identifier::add):
(JSC::IdentifierUCharBufferTranslator::hash):
(JSC::IdentifierUCharBufferTranslator::equal):
(JSC::IdentifierUCharBufferTranslator::translate):
(JSC::Identifier::addSlowCase):

  • runtime/Identifier.h:
  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::JSGlobalData):
(JSC::JSGlobalData::~JSGlobalData):

  • runtime/JSGlobalData.h:
  • wtf/WTFThreadData.cpp:

(WTF::WTFThreadData::WTFThreadData):
(WTF::WTFThreadData::~WTFThreadData):

  • wtf/WTFThreadData.h:

(JSC::IdentifierTable::remove):
(JSC::IdentifierTable::literalTable):
(WTF::WTFThreadData::atomicStringTable):

  • wtf/text/AtomicString.cpp:

(WebCore::AtomicStringTable::create):
(WebCore::AtomicStringTable::table):
(WebCore::AtomicStringTable::destroy):
(WebCore::stringTable):
(WebCore::CStringTranslator::hash):
(WebCore::CStringTranslator::equal):
(WebCore::CStringTranslator::translate):
(WebCore::operator==):
(WebCore::AtomicString::add):
(WebCore::equal):
(WebCore::UCharBufferTranslator::hash):
(WebCore::UCharBufferTranslator::equal):
(WebCore::UCharBufferTranslator::translate):
(WebCore::HashAndCharactersTranslator::hash):
(WebCore::HashAndCharactersTranslator::equal):
(WebCore::HashAndCharactersTranslator::translate):
(WebCore::AtomicString::find):
(WebCore::AtomicString::remove):

  • wtf/text/AtomicStringTable.h: Removed.
  • wtf/text/StringImpl.cpp:

(WebCore::StringImpl::~StringImpl):

  • wtf/text/StringImpl.h:

(WebCore::StringImpl::inTable):
(WebCore::StringImpl::setInTable):
(WebCore::equal):

  • wtf/text/StringImplBase.h:

(WTF::StringImplBase::StringImplBase):

Location:
trunk/JavaScriptCore
Files:
1 deleted
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r58709 r58712  
     12010-05-03  Gavin Barraclough  <[email protected]>
     2
     3        Reviewed by NOBODY (reverting previous commit).
     4
     5        Rolling out r58114 - this introduced memory leaks of
     6        AtomicStrings then workers terminated.
     7
     8        * GNUmakefile.am:
     9        * JavaScriptCore.gypi:
     10        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
     11        * JavaScriptCore.xcodeproj/project.pbxproj:
     12        * jit/ThunkGenerators.cpp:
     13        (JSC::ThunkHelpers::stringImplDataOffset):
     14        * runtime/Identifier.cpp:
     15        (JSC::IdentifierTable::~IdentifierTable):
     16        (JSC::IdentifierTable::add):
     17        (JSC::IdentifierCStringTranslator::hash):
     18        (JSC::IdentifierCStringTranslator::equal):
     19        (JSC::IdentifierCStringTranslator::translate):
     20        (JSC::Identifier::add):
     21        (JSC::IdentifierUCharBufferTranslator::hash):
     22        (JSC::IdentifierUCharBufferTranslator::equal):
     23        (JSC::IdentifierUCharBufferTranslator::translate):
     24        (JSC::Identifier::addSlowCase):
     25        * runtime/Identifier.h:
     26        * runtime/JSGlobalData.cpp:
     27        (JSC::JSGlobalData::JSGlobalData):
     28        (JSC::JSGlobalData::~JSGlobalData):
     29        * runtime/JSGlobalData.h:
     30        * wtf/WTFThreadData.cpp:
     31        (WTF::WTFThreadData::WTFThreadData):
     32        (WTF::WTFThreadData::~WTFThreadData):
     33        * wtf/WTFThreadData.h:
     34        (JSC::IdentifierTable::remove):
     35        (JSC::IdentifierTable::literalTable):
     36        (WTF::WTFThreadData::atomicStringTable):
     37        * wtf/text/AtomicString.cpp:
     38        (WebCore::AtomicStringTable::create):
     39        (WebCore::AtomicStringTable::table):
     40        (WebCore::AtomicStringTable::destroy):
     41        (WebCore::stringTable):
     42        (WebCore::CStringTranslator::hash):
     43        (WebCore::CStringTranslator::equal):
     44        (WebCore::CStringTranslator::translate):
     45        (WebCore::operator==):
     46        (WebCore::AtomicString::add):
     47        (WebCore::equal):
     48        (WebCore::UCharBufferTranslator::hash):
     49        (WebCore::UCharBufferTranslator::equal):
     50        (WebCore::UCharBufferTranslator::translate):
     51        (WebCore::HashAndCharactersTranslator::hash):
     52        (WebCore::HashAndCharactersTranslator::equal):
     53        (WebCore::HashAndCharactersTranslator::translate):
     54        (WebCore::AtomicString::find):
     55        (WebCore::AtomicString::remove):
     56        * wtf/text/AtomicStringTable.h: Removed.
     57        * wtf/text/StringImpl.cpp:
     58        (WebCore::StringImpl::~StringImpl):
     59        * wtf/text/StringImpl.h:
     60        (WebCore::StringImpl::inTable):
     61        (WebCore::StringImpl::setInTable):
     62        (WebCore::equal):
     63        * wtf/text/StringImplBase.h:
     64        (WTF::StringImplBase::StringImplBase):
     65
    1662010-05-03  Kevin Watters  <[email protected]>
    267
  • trunk/JavaScriptCore/GNUmakefile.am

    r58537 r58712  
    311311        JavaScriptCore/wtf/text/AtomicString.h \
    312312        JavaScriptCore/wtf/text/AtomicStringImpl.h \
    313         JavaScriptCore/wtf/text/AtomicStringTable.h \
    314313        JavaScriptCore/wtf/text/CString.cpp \
    315314        JavaScriptCore/wtf/text/CString.h \
  • trunk/JavaScriptCore/JavaScriptCore.gypi

    r58537 r58712  
    428428            'wtf/text/AtomicString.h',
    429429            'wtf/text/AtomicStringImpl.h',
    430             'wtf/text/AtomicStringTable.h',
    431430            'wtf/text/CString.cpp',
    432431            'wtf/text/CString.h',
  • trunk/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj

    r58206 r58712  
    569569                        >
    570570                </File>
    571                 <File
    572                         RelativePath="..\..\wtf\text\AtomicStringTable.h"
    573                         >
    574                 </File>
    575571                <File
    576572                        RelativePath="..\..\wtf\text\CString.cpp"
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r58537 r58712  
    220220                86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
    221221                86B99AE4117E578100DF5A90 /* StringImplBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE2117E578100DF5A90 /* StringImplBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
    222                 86B99DA711800F8500DF5A90 /* AtomicStringTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99DA611800F8500DF5A90 /* AtomicStringTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
    223222                86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; };
    224223                86CA032E1038E8440028A609 /* Executable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CA032D1038E8440028A609 /* Executable.cpp */; };
     
    773772                86B99AE1117E578100DF5A90 /* StringBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringBuffer.h; path = text/StringBuffer.h; sourceTree = "<group>"; };
    774773                86B99AE2117E578100DF5A90 /* StringImplBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringImplBase.h; path = text/StringImplBase.h; sourceTree = "<group>"; };
    775                 86B99DA611800F8500DF5A90 /* AtomicStringTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AtomicStringTable.h; path = text/AtomicStringTable.h; sourceTree = "<group>"; };
    776774                86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssembler.h; sourceTree = "<group>"; };
    777775                86CA032D1038E8440028A609 /* Executable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Executable.cpp; sourceTree = "<group>"; };
     
    17091707                                868BFA01117CEFD100B908B1 /* AtomicString.h */,
    17101708                                868BFA02117CEFD100B908B1 /* AtomicStringImpl.h */,
    1711                                 86B99DA611800F8500DF5A90 /* AtomicStringTable.h */,
    17121709                                86565740115BE3DA00291F40 /* CString.cpp */,
    17131710                                86565741115BE3DA00291F40 /* CString.h */,
     
    21232120                                86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */,
    21242121                                86B99AE4117E578100DF5A90 /* StringImplBase.h in Headers */,
    2125                                 86B99DA711800F8500DF5A90 /* AtomicStringTable.h in Headers */,
    21262122                                511FC4CB117EE2A800425272 /* MD5.h in Headers */,
    21272123                                BC5F7BBE11823B590052C02C /* Atomics.h in Headers */,
  • trunk/JavaScriptCore/jit/ThunkGenerators.cpp

    r58475 r58712  
    2626#include "config.h"
    2727#include "ThunkGenerators.h"
     28#include <wtf/text/StringImpl.h>
    2829
    2930#include "SpecializedThunkJIT.h"
     
    3435
    3536struct ThunkHelpers {
    36     static unsigned stringImplDataOffset() { return StringImpl::dataOffset(); }
     37    static unsigned stringImplDataOffset() { return WebCore::StringImpl::dataOffset(); }
    3738    static unsigned jsStringLengthOffset() { return OBJECT_OFFSETOF(JSString, m_length); }
    3839    static unsigned jsStringValueOffset() { return OBJECT_OFFSETOF(JSString, m_value); }
  • trunk/JavaScriptCore/runtime/Identifier.cpp

    r58114 r58712  
    3030#include <wtf/HashSet.h>
    3131#include <wtf/WTFThreadData.h>
    32 #include <wtf/text/AtomicStringTable.h>
    3332#include <wtf/text/StringHash.h>
    3433
     
    3736namespace JSC {
    3837
    39 class LiteralTable : public HashMap<const char*, RefPtr<StringImpl>, PtrHash<const char*> > {};
    40 
    41 LiteralTable* createLiteralTable()
    42 {
    43     return new LiteralTable;
    44 }
    45 
    46 void deleteLiteralTable(LiteralTable* table)
    47 {
    48     delete table;
     38IdentifierTable::~IdentifierTable()
     39{
     40    HashSet<StringImpl*>::iterator end = m_table.end();
     41    for (HashSet<StringImpl*>::iterator iter = m_table.begin(); iter != end; ++iter)
     42        (*iter)->setIsIdentifier(false);
     43}
     44std::pair<HashSet<StringImpl*>::iterator, bool> IdentifierTable::add(StringImpl* value)
     45{
     46    std::pair<HashSet<StringImpl*>::iterator, bool> result = m_table.add(value);
     47    (*result.first)->setIsIdentifier(true);
     48    return result;
     49}
     50template<typename U, typename V>
     51std::pair<HashSet<StringImpl*>::iterator, bool> IdentifierTable::add(U value)
     52{
     53    std::pair<HashSet<StringImpl*>::iterator, bool> result = m_table.add<U, V>(value);
     54    (*result.first)->setIsIdentifier(true);
     55    return result;
    4956}
    5057
     
    8087}
    8188
     89struct IdentifierCStringTranslator {
     90    static unsigned hash(const char* c)
     91    {
     92        return UString::Rep::computeHash(c);
     93    }
     94
     95    static bool equal(UString::Rep* r, const char* s)
     96    {
     97        return Identifier::equal(r, s);
     98    }
     99
     100    static void translate(UString::Rep*& location, const char* c, unsigned hash)
     101    {
     102        size_t length = strlen(c);
     103        UChar* d;
     104        UString::Rep* r = UString::Rep::createUninitialized(length, d).releaseRef();
     105        for (size_t i = 0; i != length; i++)
     106            d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
     107        r->setHash(hash);
     108        location = r;
     109    }
     110};
     111
    82112PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c)
    83113{
     
    89119        return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0])));
    90120
    91     LiteralTable* literalTable = globalData->literalTable;
    92     pair<LiteralTable::iterator, bool> result = literalTable->add(c, 0);
    93     if (!result.second) // pre-existing entry
    94         return result.first->second;
    95 
    96     RefPtr<StringImpl> addedString = globalData->identifierTable->add(c);
    97     result.first->second = addedString.get();
     121    IdentifierTable& identifierTable = *globalData->identifierTable;
     122    LiteralIdentifierTable& literalIdentifierTable = identifierTable.literalTable();
     123
     124    const LiteralIdentifierTable::iterator& iter = literalIdentifierTable.find(c);
     125    if (iter != literalIdentifierTable.end())
     126        return iter->second;
     127
     128    pair<HashSet<UString::Rep*>::iterator, bool> addResult = identifierTable.add<const char*, IdentifierCStringTranslator>(c);
     129
     130    // If the string is newly-translated, then we need to adopt it.
     131    // The boolean in the pair tells us if that is so.
     132    RefPtr<UString::Rep> addedString = addResult.second ? adoptRef(*addResult.first) : *addResult.first;
     133
     134    literalIdentifierTable.add(c, addedString.get());
    98135
    99136    return addedString.release();
     
    104141    return add(&exec->globalData(), c);
    105142}
     143
     144struct UCharBuffer {
     145    const UChar* s;
     146    unsigned int length;
     147};
     148
     149struct IdentifierUCharBufferTranslator {
     150    static unsigned hash(const UCharBuffer& buf)
     151    {
     152        return UString::Rep::computeHash(buf.s, buf.length);
     153    }
     154
     155    static bool equal(UString::Rep* str, const UCharBuffer& buf)
     156    {
     157        return Identifier::equal(str, buf.s, buf.length);
     158    }
     159
     160    static void translate(UString::Rep*& location, const UCharBuffer& buf, unsigned hash)
     161    {
     162        UChar* d;
     163        UString::Rep* r = UString::Rep::createUninitialized(buf.length, d).releaseRef();
     164        for (unsigned i = 0; i != buf.length; i++)
     165            d[i] = buf.s[i];
     166        r->setHash(hash);
     167        location = r;
     168    }
     169};
    106170
    107171PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar* s, int length)
     
    114178    if (!length)
    115179        return UString::Rep::empty();
    116 
    117     return globalData->identifierTable->add(s, length);
     180    UCharBuffer buf = {s, length};
     181    pair<HashSet<UString::Rep*>::iterator, bool> addResult = globalData->identifierTable->add<UCharBuffer, IdentifierUCharBufferTranslator>(buf);
     182
     183    // If the string is newly-translated, then we need to adopt it.
     184    // The boolean in the pair tells us if that is so.
     185    return addResult.second ? adoptRef(*addResult.first) : *addResult.first;
    118186}
    119187
     
    138206    }
    139207
    140     return globalData->identifierTable->add(r);
     208    return *globalData->identifierTable->add(r).first;
    141209}
    142210
  • trunk/JavaScriptCore/runtime/Identifier.h

    r58114 r58712  
    138138    IdentifierTable* createIdentifierTable();
    139139    void deleteIdentifierTable(IdentifierTable*);
    140     LiteralTable* createLiteralTable();
    141     void deleteLiteralTable(LiteralTable*);
    142140
    143141} // namespace JSC
  • trunk/JavaScriptCore/runtime/JSGlobalData.cpp

    r58133 r58712  
    130130#endif
    131131    , identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
    132     , literalTable(createLiteralTable())
    133132    , propertyNames(new CommonIdentifiers(this))
    134133    , emptyList(new MarkedArgumentBuffer)
     
    196195    if (globalDataType != Default)
    197196        deleteIdentifierTable(identifierTable);
    198     deleteLiteralTable(literalTable);
    199197
    200198    delete clientData;
  • trunk/JavaScriptCore/runtime/JSGlobalData.h

    r58286 r58712  
    5757    class JSObject;
    5858    class Lexer;
    59     class LiteralTable;
    6059    class Parser;
    6160    class Stringifier;
     
    156155
    157156        IdentifierTable* identifierTable;
    158         LiteralTable* literalTable;
    159157        CommonIdentifiers* propertyNames;
    160158        const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
  • trunk/JavaScriptCore/wtf/WTFThreadData.cpp

    r58133 r58712  
    2727#include "config.h"
    2828#include "WTFThreadData.h"
    29 #include <wtf/text/AtomicStringTable.h>
    3029
    3130namespace WTF {
     
    3837
    3938WTFThreadData::WTFThreadData()
    40     : m_atomicStringTable(new WebCore::AtomicStringTable())
     39    : m_atomicStringTable(0)
     40    , m_atomicStringTableDestructor(0)
    4141#if USE(JSC)
    4242    , m_defaultIdentifierTable(new JSC::IdentifierTable())
     
    4848WTFThreadData::~WTFThreadData()
    4949{
    50     delete m_atomicStringTable;
     50    if (m_atomicStringTableDestructor)
     51        m_atomicStringTableDestructor(m_atomicStringTable);
    5152#if USE(JSC)
    5253    delete m_defaultIdentifierTable;
  • trunk/JavaScriptCore/wtf/WTFThreadData.h

    r58114 r58712  
    2828#define WTFThreadData_h
    2929
     30#include <wtf/HashMap.h>
     31#include <wtf/HashSet.h>
    3032#include <wtf/Noncopyable.h>
     33#include <wtf/text/StringHash.h>
    3134
    3235// This was ENABLE(WORKERS) in WebCore, but this is not defined when compiling JSC.
     
    4447
    4548// FIXME: This is a temporary layering violation while we move more string code to WTF.
    46 namespace JSC {
    47 class IdentifierTable;
    48 }
    49 
    50 // FIXME: This is a temporary layering violation while we move more string code to WTF.
    5149namespace WebCore {
    5250class AtomicStringTable;
     51class StringImpl;
    5352}
     53using WebCore::StringImpl;
     54
     55typedef void (*AtomicStringTableDestructor)(WebCore::AtomicStringTable*);
     56
     57#if USE(JSC)
     58// FIXME: This is a temporary layering violation while we move more string code to WTF.
     59namespace JSC {
     60
     61typedef HashMap<const char*, RefPtr<StringImpl>, PtrHash<const char*> > LiteralIdentifierTable;
     62
     63class IdentifierTable : public FastAllocBase {
     64public:
     65    ~IdentifierTable();
     66
     67    std::pair<HashSet<StringImpl*>::iterator, bool> add(StringImpl* value);
     68    template<typename U, typename V>
     69    std::pair<HashSet<StringImpl*>::iterator, bool> add(U value);
     70
     71    void remove(StringImpl* r) { m_table.remove(r); }
     72
     73    LiteralIdentifierTable& literalTable() { return m_literalTable; }
     74
     75private:
     76    HashSet<StringImpl*> m_table;
     77    LiteralIdentifierTable m_literalTable;
     78};
     79
     80}
     81#endif
    5482
    5583namespace WTF {
     
    6088    ~WTFThreadData();
    6189
    62     WebCore::AtomicStringTable& atomicStringTable()
     90    WebCore::AtomicStringTable* atomicStringTable()
    6391    {
    64         return *m_atomicStringTable;
     92        return m_atomicStringTable;
    6593    }
    6694
     
    92120private:
    93121    WebCore::AtomicStringTable* m_atomicStringTable;
     122    AtomicStringTableDestructor m_atomicStringTableDestructor;
    94123
    95124#if USE(JSC)
     
    104133#endif
    105134    friend WTFThreadData& wtfThreadData();
     135    friend class WebCore::AtomicStringTable;
    106136};
    107137
  • trunk/JavaScriptCore/wtf/text/AtomicString.cpp

    r58179 r58712  
    3232#include <wtf/Threading.h>
    3333#include <wtf/WTFThreadData.h>
    34 #include <wtf/text/AtomicStringTable.h>
    3534
    3635namespace WebCore {
    3736
    38 static inline AtomicStringTable& table()
    39 {
    40     return wtfThreadData().atomicStringTable();
    41 }
     37class AtomicStringTable {
     38public:
     39    static AtomicStringTable* create()
     40    {
     41        AtomicStringTable* table = new AtomicStringTable;
     42
     43        WTFThreadData& data = wtfThreadData();
     44        data.m_atomicStringTable = table;
     45        data.m_atomicStringTableDestructor = AtomicStringTable::destroy;
     46
     47        return table;
     48    }
     49
     50    HashSet<StringImpl*>& table()
     51    {
     52        return m_table;
     53    }
     54
     55private:
     56    static void destroy(AtomicStringTable* table)
     57    {
     58        delete table;
     59    }
     60
     61    HashSet<StringImpl*> m_table;
     62};
     63
     64static inline HashSet<StringImpl*>& stringTable()
     65{
     66    // Once possible we should make this non-lazy (constructed in WTFThreadData's constructor).
     67    AtomicStringTable* table = wtfThreadData().atomicStringTable();
     68    if (UNLIKELY(!table))
     69        table = AtomicStringTable::create();
     70    return table->table();
     71}
     72
     73struct CStringTranslator {
     74    static unsigned hash(const char* c)
     75    {
     76        return StringImpl::computeHash(c);
     77    }
     78
     79    static bool equal(StringImpl* r, const char* s)
     80    {
     81        int length = r->length();
     82        const UChar* d = r->characters();
     83        for (int i = 0; i != length; ++i) {
     84            unsigned char c = s[i];
     85            if (d[i] != c)
     86                return false;
     87        }
     88        return s[length] == 0;
     89    }
     90
     91    static void translate(StringImpl*& location, const char* const& c, unsigned hash)
     92    {
     93        location = StringImpl::create(c).releaseRef();
     94        location->setHash(hash);
     95        location->setInTable();
     96    }
     97};
    4298
    4399bool operator==(const AtomicString& a, const char* b)
     
    48104    if ((!impl || !impl->characters()) || !b)
    49105        return false;
    50     return ::equal(impl, b);
     106    return CStringTranslator::equal(impl, b);
    51107}
    52108
     
    56112        return 0;
    57113    if (!*c)
    58         return StringImpl::empty();
    59     return table().add(c);
    60 }
     114        return StringImpl::empty();   
     115    pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<const char*, CStringTranslator>(c);
     116    if (!addResult.second)
     117        return *addResult.first;
     118    return adoptRef(*addResult.first);
     119}
     120
     121struct UCharBuffer {
     122    const UChar* s;
     123    unsigned length;
     124};
     125
     126static inline bool equal(StringImpl* string, const UChar* characters, unsigned length)
     127{
     128    if (string->length() != length)
     129        return false;
     130
     131    // FIXME: perhaps we should have a more abstract macro that indicates when
     132    // going 4 bytes at a time is unsafe
     133#if CPU(ARM) || CPU(SH4)
     134    const UChar* stringCharacters = string->characters();
     135    for (unsigned i = 0; i != length; ++i) {
     136        if (*stringCharacters++ != *characters++)
     137            return false;
     138    }
     139    return true;
     140#else
     141    /* Do it 4-bytes-at-a-time on architectures where it's safe */
     142
     143    const uint32_t* stringCharacters = reinterpret_cast<const uint32_t*>(string->characters());
     144    const uint32_t* bufferCharacters = reinterpret_cast<const uint32_t*>(characters);
     145
     146    unsigned halfLength = length >> 1;
     147    for (unsigned i = 0; i != halfLength; ++i) {
     148        if (*stringCharacters++ != *bufferCharacters++)
     149            return false;
     150    }
     151
     152    if (length & 1 &&  *reinterpret_cast<const uint16_t*>(stringCharacters) != *reinterpret_cast<const uint16_t*>(bufferCharacters))
     153        return false;
     154
     155    return true;
     156#endif
     157}
     158
     159struct UCharBufferTranslator {
     160    static unsigned hash(const UCharBuffer& buf)
     161    {
     162        return StringImpl::computeHash(buf.s, buf.length);
     163    }
     164
     165    static bool equal(StringImpl* const& str, const UCharBuffer& buf)
     166    {
     167        return WebCore::equal(str, buf.s, buf.length);
     168    }
     169
     170    static void translate(StringImpl*& location, const UCharBuffer& buf, unsigned hash)
     171    {
     172        location = StringImpl::create(buf.s, buf.length).releaseRef();
     173        location->setHash(hash);
     174        location->setInTable();
     175    }
     176};
     177
     178struct HashAndCharacters {
     179    unsigned hash;
     180    const UChar* characters;
     181    unsigned length;
     182};
     183
     184struct HashAndCharactersTranslator {
     185    static unsigned hash(const HashAndCharacters& buffer)
     186    {
     187        ASSERT(buffer.hash == StringImpl::computeHash(buffer.characters, buffer.length));
     188        return buffer.hash;
     189    }
     190
     191    static bool equal(StringImpl* const& string, const HashAndCharacters& buffer)
     192    {
     193        return WebCore::equal(string, buffer.characters, buffer.length);
     194    }
     195
     196    static void translate(StringImpl*& location, const HashAndCharacters& buffer, unsigned hash)
     197    {
     198        location = StringImpl::create(buffer.characters, buffer.length).releaseRef();
     199        location->setHash(hash);
     200        location->setInTable();
     201    }
     202};
    61203
    62204PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length)
     
    68210        return StringImpl::empty();
    69211   
    70     return table().add(s, length);
     212    UCharBuffer buf = { s, length };
     213    pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<UCharBuffer, UCharBufferTranslator>(buf);
     214
     215    // If the string is newly-translated, then we need to adopt it.
     216    // The boolean in the pair tells us if that is so.
     217    return addResult.second ? adoptRef(*addResult.first) : *addResult.first;
    71218}
    72219
     
    78225    if (length == 0)
    79226        return StringImpl::empty();
    80 
    81     return table().add(s, length, existingHash);
     227   
     228    HashAndCharacters buffer = { existingHash, s, length };
     229    pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<HashAndCharacters, HashAndCharactersTranslator>(buffer);
     230    if (!addResult.second)
     231        return *addResult.first;
     232    return adoptRef(*addResult.first);
    82233}
    83234
     
    87238        return 0;
    88239
    89     unsigned length = 0;
     240    int length = 0;
    90241    while (s[length] != UChar(0))
    91242        length++;
     
    94245        return StringImpl::empty();
    95246
    96     return table().add(s, length);
     247    UCharBuffer buf = {s, length};
     248    pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<UCharBuffer, UCharBufferTranslator>(buf);
     249
     250    // If the string is newly-translated, then we need to adopt it.
     251    // The boolean in the pair tells us if that is so.
     252    return addResult.second ? adoptRef(*addResult.first) : *addResult.first;
    97253}
    98254
    99255PassRefPtr<StringImpl> AtomicString::add(StringImpl* r)
    100256{
    101     if (!r || r->isAtomic())
     257    if (!r || r->inTable())
    102258        return r;
    103259
    104     // The singleton empty string is atomic.
    105     ASSERT(r->length());
     260    if (r->length() == 0)
     261        return StringImpl::empty();
    106262   
    107     return table().add(r);
     263    StringImpl* result = *stringTable().add(r).first;
     264    if (result == r)
     265        r->setInTable();
     266    return result;
    108267}
    109268
     
    115274    if (length == 0)
    116275        return static_cast<AtomicStringImpl*>(StringImpl::empty());
    117    
    118     return static_cast<AtomicStringImpl*>(table().find(s, length, existingHash));
     276
     277    HashAndCharacters buffer = { existingHash, s, length };
     278    HashSet<StringImpl*>::iterator iterator = stringTable().find<HashAndCharacters, HashAndCharactersTranslator>(buffer);
     279    if (iterator == stringTable().end())
     280        return 0;
     281    return static_cast<AtomicStringImpl*>(*iterator);
    119282}
    120283
    121284void AtomicString::remove(StringImpl* r)
    122285{
    123     table().remove(r);
     286    stringTable().remove(r);
    124287}
    125288   
  • trunk/JavaScriptCore/wtf/text/StringImpl.cpp

    r58114 r58712  
    3131#include <wtf/StdLibExtras.h>
    3232#include <wtf/WTFThreadData.h>
    33 #include <wtf/text/AtomicStringTable.h>
    3433
    3534using namespace WTF;
     
    4443    ASSERT(!isStatic());
    4544
    46     if (isAtomic())
     45    if (inTable())
    4746        AtomicString::remove(this);
    4847#if USE(JSC)
  • trunk/JavaScriptCore/wtf/text/StringImpl.h

    r58392 r58712  
    4444// FIXME: This is a temporary layering violation while we move string code to WTF.
    4545// Landing the file moves in one patch, will follow on with patches to change the namespaces.
    46 namespace WTF {
    47 
    48 struct CStringTranslator;
    49 struct UCharBufferTranslator;
    50 struct HashAndCharactersTranslator;
     46namespace JSC {
     47
     48struct IdentifierCStringTranslator;
     49struct IdentifierUCharBufferTranslator;
    5150
    5251}
     
    5857class StringBuffer;
    5958
     59struct CStringTranslator;
     60struct HashAndCharactersTranslator;
    6061struct StringHash;
     62struct UCharBufferTranslator;
    6163
    6264enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive };
     
    6769
    6870class StringImpl : public StringImplBase {
    69     friend struct WTF::CStringTranslator;
    70     friend struct WTF::UCharBufferTranslator;
    71     friend struct WTF::HashAndCharactersTranslator;
     71    friend struct JSC::IdentifierCStringTranslator;
     72    friend struct JSC::IdentifierUCharBufferTranslator;
     73    friend struct CStringTranslator;
     74    friend struct HashAndCharactersTranslator;
     75    friend struct UCharBufferTranslator;
    7276    friend class AtomicStringImpl;
    7377private:
     
    220224    bool hasTerminatingNullCharacter() const { return m_refCountAndFlags & s_refCountFlagHasTerminatingNullCharacter; }
    221225
    222     bool isAtomic() const { return m_refCountAndFlags & s_refCountFlagIsAtomic; }
    223     void setIsAtomic(bool inTable)
    224     {
    225         ASSERT(!isStatic());
    226         if (inTable)
    227             m_refCountAndFlags |= s_refCountFlagIsAtomic;
    228         else
    229             m_refCountAndFlags &= s_refCountFlagIsAtomic;
    230     }
     226    bool inTable() const { return m_refCountAndFlags & s_refCountFlagInTable; }
     227    void setInTable() { m_refCountAndFlags |= s_refCountFlagInTable; }
    231228
    232229    unsigned hash() const { if (!m_hash) m_hash = computeHash(m_data, m_length); return m_hash; }
     
    336333bool equal(const StringImpl*, const char*);
    337334inline bool equal(const char* a, StringImpl* b) { return equal(b, a); }
    338 inline bool equal(StringImpl* string, const UChar* characters, unsigned length)
    339 {
    340     if (string->length() != length)
    341         return false;
    342 
    343     // FIXME: perhaps we should have a more abstract macro that indicates when
    344     // going 4 bytes at a time is unsafe
    345 #if CPU(ARM) || CPU(SH4)
    346     const UChar* stringCharacters = string->characters();
    347     for (unsigned i = 0; i != length; ++i) {
    348         if (*stringCharacters++ != *characters++)
    349             return false;
    350     }
    351     return true;
    352 #else
    353     /* Do it 4-bytes-at-a-time on architectures where it's safe */
    354 
    355     const uint32_t* stringCharacters = reinterpret_cast<const uint32_t*>(string->characters());
    356     const uint32_t* bufferCharacters = reinterpret_cast<const uint32_t*>(characters);
    357 
    358     unsigned halfLength = length >> 1;
    359     for (unsigned i = 0; i != halfLength; ++i) {
    360         if (*stringCharacters++ != *bufferCharacters++)
    361             return false;
    362     }
    363 
    364     if (length & 1 &&  *reinterpret_cast<const uint16_t*>(stringCharacters) != *reinterpret_cast<const uint16_t*>(bufferCharacters))
    365         return false;
    366 
    367     return true;
    368 #endif
    369 }
    370335
    371336bool equalIgnoringCase(StringImpl*, StringImpl*);
     
    410375
    411376using WebCore::equal;
    412 using WebCore::StringImpl;
    413377
    414378namespace WTF {
  • trunk/JavaScriptCore/wtf/text/StringImplBase.h

    r58114 r58712  
    6161    enum StaticStringConstructType { ConstructStaticString };
    6262    StringImplBase(unsigned length, StaticStringConstructType)
    63         : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsAtomic | s_refCountFlagIsIdentifier | BufferOwned)
     63        : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsIdentifier | BufferOwned)
    6464        , m_length(length)
    6565    {
     
    8484    static const unsigned s_refCountFlagStatic = 0x40;
    8585    static const unsigned s_refCountFlagHasTerminatingNullCharacter = 0x20;
    86     static const unsigned s_refCountFlagIsAtomic = 0x10;
     86    static const unsigned s_refCountFlagInTable = 0x10;
    8787    static const unsigned s_refCountFlagShouldReportedCost = 0x8;
    8888    static const unsigned s_refCountFlagIsIdentifier = 0x4;
Note: See TracChangeset for help on using the changeset viewer.