Changeset 58114 in webkit for trunk/JavaScriptCore/runtime


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):

Location:
trunk/JavaScriptCore/runtime
Files:
4 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
  • trunk/JavaScriptCore/runtime/Identifier.h

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

    r58012 r58114  
    130130#endif
    131131    , identifierTable(createIdentifierTable())
     132    , literalTable(createLiteralTable())
    132133    , propertyNames(new CommonIdentifiers(this))
    133134    , emptyList(new MarkedArgumentBuffer)
     
    194195    delete propertyNames;
    195196    deleteIdentifierTable(identifierTable);
     197    deleteLiteralTable(literalTable);
    196198
    197199    delete clientData;
  • trunk/JavaScriptCore/runtime/JSGlobalData.h

    r58012 r58114  
    5757    class JSObject;
    5858    class Lexer;
     59    class LiteralTable;
    5960    class Parser;
    6061    class Stringifier;
     
    144145
    145146        IdentifierTable* identifierTable;
     147        LiteralTable* literalTable;
    146148        CommonIdentifiers* propertyNames;
    147149        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.
Note: See TracChangeset for help on using the changeset viewer.