Ignore:
Timestamp:
Apr 22, 2010, 1:31:04 PM (15 years ago)
Author:
[email protected]
Message:

https://bugs.webkit.org/show_bug.cgi?id=37978
Unify JSC::IdentifierTable and WebCore::AtomicStringTable implementations.

Reviewed by Geoff Garen.

These two classes both implement a HashSet of uniqued StringImpls, with
translator classes to avoid unnecessary object creation. The only difference
between the classes is which flag (isIdentifier or inTable) is set.
Combine the two classes using a template predicated on which flag to use.

New class AtomicStringTable created, containing all the goodness from
IdentifierTable & AtomicStringTable, expect for Identifier's literalTable,
which has been moved onto JSGlobalData. Removed duplicate string translator
classes. Renamed StringImpl's inTable flag to more explicit 'isAtomic',
and set this on the empty string (which matches Identifier behaviour, and
removes a redundant check for zero-length).

(JSC::createLiteralTable):
(JSC::deleteLiteralTable):
(JSC::Identifier::add):
(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:

(WTF::WTFThreadData::atomicStringTable):

  • wtf/text/AtomicString.cpp:

(WebCore::table):
(WebCore::operator==):
(WebCore::AtomicString::add):
(WebCore::AtomicString::find):
(WebCore::AtomicString::remove):

  • wtf/text/AtomicStringTable.h: Added.

(WTF::CStringTranslator::hash):
(WTF::CStringTranslator::equal):
(WTF::CStringTranslator::translate):
(WTF::UCharBufferTranslator::hash):
(WTF::UCharBufferTranslator::equal):
(WTF::UCharBufferTranslator::translate):
(WTF::HashAndCharactersTranslator::hash):
(WTF::HashAndCharactersTranslator::equal):
(WTF::HashAndCharactersTranslator::translate):
(WTF::IdentifierOrAtomicStringTable::remove):
(WTF::::~IdentifierOrAtomicStringTable):
(WTF::::add):
(WTF::::find):

  • wtf/text/StringImpl.cpp:

(WebCore::StringImpl::~StringImpl):

  • wtf/text/StringImpl.h:

(WebCore::StringImpl::isAtomic):
(WebCore::StringImpl::setIsAtomic):
(WebCore::equal):

  • wtf/text/StringImplBase.h:

(WTF::StringImplBase::StringImplBase):

File:
1 edited

Legend:

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

    r58003 r58114  
    3030#include <wtf/HashSet.h>
    3131#include <wtf/WTFThreadData.h>
     32#include <wtf/text/AtomicStringTable.h>
    3233#include <wtf/text/StringHash.h>
    3334
     
    3637namespace JSC {
    3738
    38 IdentifierTable::~IdentifierTable()
     39class LiteralTable : public HashMap<const char*, RefPtr<StringImpl>, PtrHash<const char*> > {};
     40
     41LiteralTable* createLiteralTable()
    3942{
    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    return new LiteralTable;
    4344}
    44 std::pair<HashSet<StringImpl*>::iterator, bool> IdentifierTable::add(StringImpl* value)
     45
     46void deleteLiteralTable(LiteralTable* table)
    4547{
    46     std::pair<HashSet<StringImpl*>::iterator, bool> result = m_table.add(value);
    47     (*result.first)->setIsIdentifier(true);
    48     return result;
    49 }
    50 template<typename U, typename V>
    51 std::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;
     48    delete table;
    5649}
    5750
     
    8780}
    8881
    89 struct 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 
    11282PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c)
    11383{
     
    11989        return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0])));
    12090
    121     IdentifierTable& identifierTable = *globalData->identifierTable;
    122     LiteralIdentifierTable& literalIdentifierTable = identifierTable.literalTable();
     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;
    12395
    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());
     96    RefPtr<StringImpl> addedString = globalData->identifierTable->add(c);
     97    result.first->second = addedString.get();
    13598
    13699    return addedString.release();
     
    141104    return add(&exec->globalData(), c);
    142105}
    143 
    144 struct UCharBuffer {
    145     const UChar* s;
    146     unsigned int length;
    147 };
    148 
    149 struct 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 };
    170106
    171107PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar* s, int length)
     
    178114    if (!length)
    179115        return UString::Rep::empty();
    180     UCharBuffer buf = {s, length};
    181     pair<HashSet<UString::Rep*>::iterator, bool> addResult = globalData->identifierTable->add<UCharBuffer, IdentifierUCharBufferTranslator>(buf);
    182116
    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;
     117    return globalData->identifierTable->add(s, length);
    186118}
    187119
     
    206138    }
    207139
    208     return *globalData->identifierTable->add(r).first;
     140    return globalData->identifierTable->add(r);
    209141}
    210142
Note: See TracChangeset for help on using the changeset viewer.