Changeset 183624 in webkit


Ignore:
Timestamp:
Apr 30, 2015 1:37:51 AM (9 years ago)
Author:
Yusuke Suzuki
Message:

Use the default hash value for Symbolized StringImpl
https://bugs.webkit.org/show_bug.cgi?id=144347

Reviewed by Darin Adler.

Source/JavaScriptCore:

Before this patch, symbolized StringImpl* has a special hash value
to avoid the hash collision with the other normal StringImpl*.
I guess that it is introduced when private symbols are introduced.
However, it prevents using symbolized StringImpl* in the other place
For example, using it as WTFString cause a problem because of its special hash value.

When only using private symbols, they are not exposed to the outside of JSC,
so we can handle it carefully. But now, it's extended to symbols.
So I think storing a special hash value in StringImpl* causes an error.

To avoid this, I propose using the usual hash value in symbolized StringImpl*.
And to provide significantly different hash value when using it as symbol,
store the additional hash value in symbolized StringImpl*. It is used when
the hash value is required by IdentifierRepHash.

  • runtime/Identifier.h:

(JSC::IdentifierRepHash::hash):

  • runtime/Lookup.h:

(JSC::HashTable::entry):

  • runtime/PropertyMapHashTable.h:

(JSC::PropertyTable::find):
(JSC::PropertyTable::get):

  • runtime/Structure.cpp:

(JSC::PropertyTable::checkConsistency):

Source/WTF:

Use a default hash value calculation for symbolized StringImpl.

  • wtf/text/StringImpl.cpp:

(WTF::StringImpl::createSymbol):

  • wtf/text/StringImpl.h:

(WTF::StringImpl::StringImpl):
(WTF::StringImpl::symbolAwareHash):
(WTF::StringImpl::existingSymbolAwareHash):
(WTF::StringImpl::hashForSymbol):

  • wtf/text/StringStatics.cpp:

(WTF::StringImpl::nextHashForSymbol):
(WTF::StringImpl::hashAndFlagsForSymbol): Deleted.

Location:
trunk/Source
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r183615 r183624  
     12015-04-30  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Use the default hash value for Symbolized StringImpl
     4        https://bugs.webkit.org/show_bug.cgi?id=144347
     5
     6        Reviewed by Darin Adler.
     7
     8        Before this patch, symbolized StringImpl* has a special hash value
     9        to avoid the hash collision with the other normal StringImpl*.
     10        I guess that it is introduced when private symbols are introduced.
     11        However, it prevents using symbolized StringImpl* in the other place
     12        For example, using it as WTFString cause a problem because of its special hash value.
     13
     14        When only using private symbols, they are not exposed to the outside of JSC,
     15        so we can handle it carefully. But now, it's extended to symbols.
     16        So I think storing a special hash value in StringImpl* causes an error.
     17
     18        To avoid this, I propose using the usual hash value in symbolized StringImpl*.
     19        And to provide significantly different hash value when using it as symbol,
     20        store the additional hash value in symbolized StringImpl*. It is used when
     21        the hash value is required by IdentifierRepHash.
     22
     23        * runtime/Identifier.h:
     24        (JSC::IdentifierRepHash::hash):
     25        * runtime/Lookup.h:
     26        (JSC::HashTable::entry):
     27        * runtime/PropertyMapHashTable.h:
     28        (JSC::PropertyTable::find):
     29        (JSC::PropertyTable::get):
     30        * runtime/Structure.cpp:
     31        (JSC::PropertyTable::checkConsistency):
     32
    1332015-04-29  Benjamin Poulain  <bpoulain@apple.com>
    234
  • trunk/Source/JavaScriptCore/runtime/Identifier.h

    r182452 r183624  
    281281
    282282struct IdentifierRepHash : PtrHash<RefPtr<StringImpl>> {
    283     static unsigned hash(const RefPtr<StringImpl>& key) { return key->existingHash(); }
    284     static unsigned hash(StringImpl* key) { return key->existingHash(); }
     283    static unsigned hash(const RefPtr<StringImpl>& key) { return key->existingSymbolAwareHash(); }
     284    static unsigned hash(StringImpl* key) { return key->existingSymbolAwareHash(); }
    285285};
    286286
  • trunk/Source/JavaScriptCore/runtime/Lookup.h

    r182205 r183624  
    104104        ASSERT(keys);
    105105
    106         int indexEntry = impl->existingHash() & indexMask;
     106        int indexEntry = IdentifierRepHash::hash(impl) & indexMask;
    107107        int valueIndex = index[indexEntry].value;
    108108        if (valueIndex == -1)
  • trunk/Source/JavaScriptCore/runtime/PropertyMapHashTable.h

    r182747 r183624  
    272272    ASSERT(key);
    273273    ASSERT(key->isAtomic() || key->isSymbol());
    274     unsigned hash = key->existingHash();
     274    unsigned hash = IdentifierRepHash::hash(key);
    275275    unsigned step = 0;
    276276
     
    287287
    288288        if (!step)
    289             step = WTF::doubleHash(key->existingHash()) | 1;
     289            step = WTF::doubleHash(IdentifierRepHash::hash(key)) | 1;
    290290
    291291#if DUMP_PROPERTYMAP_STATS
     
    295295#if DUMP_PROPERTYMAP_COLLISIONS
    296296        dataLog("PropertyTable collision for ", key, " (", hash, ") with step ", step, "\n");
    297         dataLog("Collided with ", table()[entryIndex - 1].key, "(", table()[entryIndex - 1].key->existingHash(), ")\n");
     297        dataLog("Collided with ", table()[entryIndex - 1].key, "(", IdentifierRepHash::hash(table()[entryIndex - 1].key), ")\n");
    298298#endif
    299299
     
    310310        return nullptr;
    311311
    312     unsigned hash = key->existingHash();
     312    unsigned hash = IdentifierRepHash::hash(key);
    313313    unsigned step = 0;
    314314
     
    329329
    330330        if (!step)
    331             step = WTF::doubleHash(key->existingHash()) | 1;
     331            step = WTF::doubleHash(IdentifierRepHash::hash(key)) | 1;
    332332        hash += step;
    333333    }
  • trunk/Source/JavaScriptCore/runtime/Structure.cpp

    r182747 r183624  
    11631163            continue;
    11641164        ++nonEmptyEntryCount;
    1165         unsigned i = rep->existingHash();
     1165        unsigned i = IdentifierRepHash::hash(rep);
    11661166        unsigned k = 0;
    11671167        unsigned entryIndex;
     
    11721172                break;
    11731173            if (k == 0)
    1174                 k = 1 | doubleHash(rep->existingHash());
     1174                k = 1 | doubleHash(IdentifierRepHash::hash(rep));
    11751175            i += k;
    11761176        }
  • trunk/Source/WTF/ChangeLog

    r183608 r183624  
     12015-04-30  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Use the default hash value for Symbolized StringImpl
     4        https://bugs.webkit.org/show_bug.cgi?id=144347
     5
     6        Reviewed by Darin Adler.
     7
     8        Use a default hash value calculation for symbolized StringImpl.
     9
     10        * wtf/text/StringImpl.cpp:
     11        (WTF::StringImpl::createSymbol):
     12        * wtf/text/StringImpl.h:
     13        (WTF::StringImpl::StringImpl):
     14        (WTF::StringImpl::symbolAwareHash):
     15        (WTF::StringImpl::existingSymbolAwareHash):
     16        (WTF::StringImpl::hashForSymbol):
     17        * wtf/text/StringStatics.cpp:
     18        (WTF::StringImpl::nextHashForSymbol):
     19        (WTF::StringImpl::hashAndFlagsForSymbol): Deleted.
     20
    1212015-04-29  Alexey Proskuryakov  <ap@apple.com>
    222
  • trunk/Source/WTF/wtf/text/StringImpl.cpp

    r182915 r183624  
    299299    // 2. the pointer to the owner string
    300300    // 3. the pointer to the symbol registry
    301     StringImpl* stringImpl = static_cast<StringImpl*>(fastMalloc(allocationSize<StringImpl*>(2)));
     301    // 4. the placeholder for symbol aware hash value (allocated size is pointer size, but only 4 bytes are used)
     302    StringImpl* stringImpl = static_cast<StringImpl*>(fastMalloc(allocationSize<StringImpl*>(3)));
    302303    if (rep->is8Bit())
    303304        return adoptRef(*new (NotNull, stringImpl) StringImpl(CreateSymbol, rep->m_data8, rep->length(), ownerRep));
  • trunk/Source/WTF/wtf/text/StringImpl.h

    r182915 r183624  
    300300        , m_length(length)
    301301        , m_data8(characters)
    302         , m_hashAndFlags(hashAndFlagsForSymbol(s_hashFlag8BitBuffer | StringSymbol | BufferSubstring))
     302        , m_hashAndFlags(s_hashFlag8BitBuffer | StringSymbol | BufferSubstring)
    303303    {
    304304        ASSERT(is8Bit());
     
    308308        substringBuffer() = base.leakRef();
    309309        symbolRegistry() = nullptr;
     310        hashForSymbol() = nextHashForSymbol();
    310311
    311312        STRING_STATS_ADD_8BIT_STRING2(m_length, true);
     
    317318        , m_length(length)
    318319        , m_data16(characters)
    319         , m_hashAndFlags(hashAndFlagsForSymbol(StringSymbol | BufferSubstring))
     320        , m_hashAndFlags(StringSymbol | BufferSubstring)
    320321    {
    321322        ASSERT(!is8Bit());
     
    325326        substringBuffer() = base.leakRef();
    326327        symbolRegistry() = nullptr;
     328        hashForSymbol() = nextHashForSymbol();
    327329
    328330        STRING_STATS_ADD_16BIT_STRING2(m_length, true);
     
    561563        return hashSlowCase();
    562564    }
    563    
     565
     566    unsigned symbolAwareHash() const
     567    {
     568        if (isSymbol())
     569            return hashForSymbol();
     570        return hash();
     571    }
     572
     573    unsigned existingSymbolAwareHash() const
     574    {
     575        if (isSymbol())
     576            return hashForSymbol();
     577        return existingHash();
     578    }
     579
    564580    bool isStatic() const { return m_refCount & s_refCountFlagIsStaticString; }
    565581
     
    781797    }
    782798
     799    const unsigned& hashForSymbol() const
     800    {
     801        return const_cast<StringImpl*>(this)->hashForSymbol();
     802    }
     803
     804    unsigned& hashForSymbol()
     805    {
     806        ASSERT(isSymbol());
     807        return *reinterpret_cast<unsigned*>((tailPointer<SymbolRegistry*>() + 2));
     808    }
     809
    783810private:
    784811    bool requiresCopy() const
     
    847874    template <typename CharType> static Ref<StringImpl> createInternal(const CharType*, unsigned);
    848875    WTF_EXPORT_PRIVATE NEVER_INLINE unsigned hashSlowCase() const;
    849     WTF_EXPORT_PRIVATE static unsigned hashAndFlagsForSymbol(unsigned flags);
     876    WTF_EXPORT_PRIVATE static unsigned nextHashForSymbol();
    850877
    851878    // The bottom bit in the ref count indicates a static (immortal) string.
  • trunk/Source/WTF/wtf/text/StringStatics.cpp

    r182205 r183624  
    4848}
    4949
    50 // Set the hash early, so that all symbol StringImpls have a hash,
    51 // and don't use the normal hashing algorithm - the unique nature of these
    52 // keys means that we don't need them to match any other string (in fact,
    53 // that's exactly the oposite of what we want!), and the normal hash would
    54 // lead to lots of conflicts.
    55 unsigned StringImpl::hashAndFlagsForSymbol(unsigned flags)
     50// In addition to the normal hash value, store specialized hash value for
     51// symbolized StringImpl*. And don't use the normal hash value for symbolized
     52// StringImpl* when they are treated as Identifiers. Unique nature of these
     53// symbolized StringImpl* keys means that we don't need them to match any other
     54// string (in fact, that's exactly the oposite of what we want!), and the
     55// normal hash would lead to lots of conflicts.
     56unsigned StringImpl::nextHashForSymbol()
    5657{
    57     static unsigned s_nextHashAndFlagsForSymbol = 0;
    58     s_nextHashAndFlagsForSymbol += 1 << s_flagCount;
    59     s_nextHashAndFlagsForSymbol |= 1 << 31;
    60     unsigned flagsForSymbol = ((flags & s_flagMask) & (~s_hashMaskStringKind)) | StringSymbol;
    61     return s_nextHashAndFlagsForSymbol | flagsForSymbol;
     58    static unsigned s_nextHashForSymbol = 0;
     59    s_nextHashForSymbol += 1 << s_flagCount;
     60    s_nextHashForSymbol |= 1 << 31;
     61    return s_nextHashForSymbol;
    6262}
    6363
Note: See TracChangeset for help on using the changeset viewer.