summaryrefslogtreecommitdiffstats
path: root/js/src/vm/StringType.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm/StringType.h')
-rw-r--r--js/src/vm/StringType.h40
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;
}