diff options
Diffstat (limited to 'js/src/vm/JSAtomUtils.cpp')
-rw-r--r-- | js/src/vm/JSAtomUtils.cpp | 159 |
1 files changed, 45 insertions, 114 deletions
diff --git a/js/src/vm/JSAtomUtils.cpp b/js/src/vm/JSAtomUtils.cpp index ab8e4b2e30..2f8b066f0c 100644 --- a/js/src/vm/JSAtomUtils.cpp +++ b/js/src/vm/JSAtomUtils.cpp @@ -62,113 +62,30 @@ extern bool GetUTF8AtomizationData(JSContext* cx, const JS::UTF8Chars& utf8, JS::SmallestEncoding* encoding, HashNumber* hashNum); -struct js::AtomHasher::Lookup { - union { - const JS::Latin1Char* latin1Chars; - const char16_t* twoByteChars; - const char* utf8Bytes; - }; - enum { TwoByteChar, Latin1, UTF8 } type; - size_t length; - size_t byteLength; - const JSAtom* atom; /* Optional. */ - JS::AutoCheckCannotGC nogc; - - HashNumber hash; - - MOZ_ALWAYS_INLINE Lookup(const char* utf8Bytes, size_t byteLen, size_t length, - HashNumber hash) - : utf8Bytes(utf8Bytes), - type(UTF8), - length(length), - byteLength(byteLen), - atom(nullptr), - hash(hash) {} - - MOZ_ALWAYS_INLINE Lookup(const char16_t* chars, size_t length) - : twoByteChars(chars), - type(TwoByteChar), - length(length), - atom(nullptr), - hash(mozilla::HashString(chars, length)) {} - - MOZ_ALWAYS_INLINE Lookup(const JS::Latin1Char* chars, size_t length) - : latin1Chars(chars), - type(Latin1), - length(length), - atom(nullptr), - hash(mozilla::HashString(chars, length)) {} - - MOZ_ALWAYS_INLINE Lookup(HashNumber hash, const char16_t* chars, - size_t length) - : twoByteChars(chars), - type(TwoByteChar), - length(length), - atom(nullptr), - hash(hash) { - MOZ_ASSERT(hash == mozilla::HashString(chars, length)); - } - - MOZ_ALWAYS_INLINE Lookup(HashNumber hash, const JS::Latin1Char* chars, - size_t length) - : latin1Chars(chars), - type(Latin1), - length(length), - atom(nullptr), - hash(hash) { - MOZ_ASSERT(hash == mozilla::HashString(chars, length)); - } - - inline explicit Lookup(const JSAtom* atom) - : type(atom->hasLatin1Chars() ? Latin1 : TwoByteChar), - length(atom->length()), - atom(atom), - hash(atom->hash()) { - if (type == Latin1) { - latin1Chars = atom->latin1Chars(nogc); - MOZ_ASSERT(mozilla::HashString(latin1Chars, length) == hash); - } else { - MOZ_ASSERT(type == TwoByteChar); - twoByteChars = atom->twoByteChars(nogc); - MOZ_ASSERT(mozilla::HashString(twoByteChars, length) == hash); - } - } -}; - -inline HashNumber js::AtomHasher::hash(const Lookup& l) { return l.hash; } - -MOZ_ALWAYS_INLINE bool js::AtomHasher::match(const WeakHeapPtr<JSAtom*>& entry, - const Lookup& lookup) { - JSAtom* key = entry.unbarrieredGet(); - if (lookup.atom) { - return lookup.atom == key; - } - if (key->length() != lookup.length || key->hash() != lookup.hash) { - return false; - } - - if (key->hasLatin1Chars()) { - const Latin1Char* keyChars = key->latin1Chars(lookup.nogc); - switch (lookup.type) { +MOZ_ALWAYS_INLINE bool js::AtomHasher::Lookup::StringsMatch( + const JSAtom& atom) const { + if (atom.hasLatin1Chars()) { + const Latin1Char* keyChars = atom.latin1Chars(nogc); + switch (type) { case Lookup::Latin1: - return EqualChars(keyChars, lookup.latin1Chars, lookup.length); + return EqualChars(keyChars, latin1Chars, length); case Lookup::TwoByteChar: - return EqualChars(keyChars, lookup.twoByteChars, lookup.length); + return EqualChars(keyChars, twoByteChars, length); case Lookup::UTF8: { - JS::UTF8Chars utf8(lookup.utf8Bytes, lookup.byteLength); + JS::UTF8Chars utf8(utf8Bytes, byteLength); return UTF8EqualsChars(utf8, keyChars); } } } - const char16_t* keyChars = key->twoByteChars(lookup.nogc); - switch (lookup.type) { + const char16_t* keyChars = atom.twoByteChars(nogc); + switch (type) { case Lookup::Latin1: - return EqualChars(lookup.latin1Chars, keyChars, lookup.length); + return EqualChars(latin1Chars, keyChars, length); case Lookup::TwoByteChar: - return EqualChars(keyChars, lookup.twoByteChars, lookup.length); + return EqualChars(keyChars, twoByteChars, length); case Lookup::UTF8: { - JS::UTF8Chars utf8(lookup.utf8Bytes, lookup.byteLength); + JS::UTF8Chars utf8(utf8Bytes, byteLength); return UTF8EqualsChars(utf8, keyChars); } } @@ -177,6 +94,21 @@ MOZ_ALWAYS_INLINE bool js::AtomHasher::match(const WeakHeapPtr<JSAtom*>& entry, return false; } +inline HashNumber js::AtomHasher::hash(const Lookup& l) { return l.hash; } + +MOZ_ALWAYS_INLINE bool js::AtomHasher::match(const WeakHeapPtr<JSAtom*>& entry, + const Lookup& lookup) { + JSAtom* key = entry.unbarrieredGet(); + if (lookup.atom) { + return lookup.atom == key; + } + if (key->length() != lookup.length || key->hash() != lookup.hash) { + return false; + } + + return lookup.StringsMatch(*key); +} + UniqueChars js::AtomToPrintableString(JSContext* cx, JSAtom* atom) { return QuoteString(cx, atom); } @@ -450,18 +382,21 @@ static MOZ_ALWAYS_INLINE JSAtom* AtomizeAndCopyCharsNonStaticValidLengthFromLookup( JSContext* cx, const CharT* chars, size_t length, const AtomHasher::Lookup& lookup, const Maybe<uint32_t>& indexValue) { - // Try the per-Zone cache first. If we find the atom there we can avoid the - // markAtom call, and the multiple HashSet lookups below. Zone* zone = cx->zone(); MOZ_ASSERT(zone); - AtomSet::AddPtr zonePtr = zone->atomCache().lookupForAdd(lookup); - if (zonePtr) { - // The cache is purged on GC so if we're in the middle of an - // incremental GC we should have barriered the atom when we put - // it in the cache. - JSAtom* atom = zonePtr->unbarrieredGet(); - MOZ_ASSERT(AtomIsMarked(zone, atom)); - return atom; + + AtomCacheHashTable* atomCache = zone->atomCache(); + + // Try the per-Zone cache first. If we find the atom there we can avoid the + // markAtom call, and the multiple HashSet lookups below. + if (MOZ_LIKELY(atomCache)) { + JSAtom* const cachedAtom = atomCache->lookupForAdd(lookup); + if (cachedAtom) { + // The cache is purged on GC so if we're in the middle of an incremental + // GC we should have barriered the atom when we put it in the cache. + MOZ_ASSERT(AtomIsMarked(zone, cachedAtom)); + return cachedAtom; + } } MOZ_ASSERT(cx->permanentAtomsPopulated()); @@ -469,11 +404,9 @@ AtomizeAndCopyCharsNonStaticValidLengthFromLookup( AtomSet::Ptr pp = cx->permanentAtoms().readonlyThreadsafeLookup(lookup); if (pp) { JSAtom* atom = pp->get(); - if (MOZ_UNLIKELY(!zone->atomCache().add(zonePtr, atom))) { - ReportOutOfMemory(cx); - return nullptr; + if (MOZ_LIKELY(atomCache)) { + atomCache->add(lookup.hash, atom); } - return atom; } @@ -488,11 +421,9 @@ AtomizeAndCopyCharsNonStaticValidLengthFromLookup( return nullptr; } - if (MOZ_UNLIKELY(!zone->atomCache().add(zonePtr, atom))) { - ReportOutOfMemory(cx); - return nullptr; + if (MOZ_LIKELY(atomCache)) { + atomCache->add(lookup.hash, atom); } - return atom; } |