diff options
Diffstat (limited to 'js/src/vm/StringType.h')
-rw-r--r-- | js/src/vm/StringType.h | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/js/src/vm/StringType.h b/js/src/vm/StringType.h index f2850c33a4..38dea85c60 100644 --- a/js/src/vm/StringType.h +++ b/js/src/vm/StringType.h @@ -407,8 +407,10 @@ class JSString : public js::gc::CellWithLengthAndFlags { static const uint32_t INDEX_VALUE_BIT = js::Bit(11); static const uint32_t INDEX_VALUE_SHIFT = 16; - // NON_DEDUP_BIT is used in string deduplication during tenuring. - static const uint32_t NON_DEDUP_BIT = js::Bit(12); + // NON_DEDUP_BIT is used in string deduplication during tenuring. This bit is + // shared with both FLATTEN_FINISH_NODE and ATOM_IS_PERMANENT_BIT, since it + // only applies to linear non-atoms. + static const uint32_t NON_DEDUP_BIT = js::Bit(15); // If IN_STRING_TO_ATOM_CACHE is set, this string had an entry in the // StringToAtomCache at some point. Note that GC can purge the cache without @@ -627,13 +629,27 @@ class JSString : public js::gc::CellWithLengthAndFlags { } MOZ_ALWAYS_INLINE - void setNonDeduplicatable() { setFlagBit(NON_DEDUP_BIT); } + void setNonDeduplicatable() { + MOZ_ASSERT(isLinear()); + MOZ_ASSERT(!isAtom()); + setFlagBit(NON_DEDUP_BIT); + } + // After copying a string from the nursery to the tenured heap, adjust bits + // that no longer apply. MOZ_ALWAYS_INLINE - void clearNonDeduplicatable() { clearFlagBit(NON_DEDUP_BIT); } + void clearBitsOnTenure() { + MOZ_ASSERT(!isAtom()); + clearFlagBit(NON_DEDUP_BIT | IN_STRING_TO_ATOM_CACHE); + } + // NON_DEDUP_BIT is only valid for linear non-atoms. MOZ_ALWAYS_INLINE - bool isDeduplicatable() { return !(flags() & NON_DEDUP_BIT); } + bool isDeduplicatable() { + MOZ_ASSERT(isLinear()); + MOZ_ASSERT(!isAtom()); + return !(flags() & NON_DEDUP_BIT); + } void setInStringToAtomCache() { MOZ_ASSERT(!isAtom()); @@ -659,6 +675,7 @@ class JSString : public js::gc::CellWithLengthAndFlags { inline bool canOwnDependentChars() const; + // Only called by the GC during nursery collection. inline void setBase(JSLinearString* newBase); void traceBase(JSTracer* trc); @@ -781,6 +798,8 @@ class JSString : public js::gc::CellWithLengthAndFlags { void traceChildren(JSTracer* trc); + inline void traceBaseFromStoreBuffer(JSTracer* trc); + // Override base class implementation to tell GC about permanent atoms. bool isPermanentAndMayBeShared() const { return isPermanentAtom(); } @@ -930,6 +949,7 @@ class JSLinearString : public JSString { friend class JS::AutoStableStringChars; friend class js::gc::TenuringTracer; friend class js::gc::CellAllocator; + friend class JSDependentString; // To allow access when used as base. /* Vacuous and therefore unimplemented. */ JSLinearString* ensureLinear(JSContext* cx) = delete; @@ -1138,6 +1158,13 @@ class JSDependentString : public JSLinearString { setNonInlineChars(chars + offset); } + inline JSLinearString* rootBaseDuringMinorGC(); + + template <typename CharT> + inline void sweepTypedAfterMinorGC(); + + inline void sweepAfterMinorGC(); + #if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW) void dumpOwnRepresentationFields(js::JSONPrinter& json) const; #endif @@ -2260,14 +2287,17 @@ class StringRelocationOverlay : public RelocationOverlay { MOZ_ALWAYS_INLINE const CharT* savedNurseryChars() const; const MOZ_ALWAYS_INLINE JS::Latin1Char* savedNurseryCharsLatin1() const { + MOZ_ASSERT(!forwardingAddress()->as<JSString>()->hasBase()); return nurseryCharsLatin1; } const MOZ_ALWAYS_INLINE char16_t* savedNurseryCharsTwoByte() const { + MOZ_ASSERT(!forwardingAddress()->as<JSString>()->hasBase()); return nurseryCharsTwoByte; } JSLinearString* savedNurseryBaseOrRelocOverlay() const { + MOZ_ASSERT(forwardingAddress()->as<JSString>()->hasBase()); return nurseryBaseOrRelocOverlay; } |