1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 * Implementation details of the atoms table.
11 #ifndef vm_AtomsTable_h
12 #define vm_AtomsTable_h
14 #include "gc/Barrier.h"
15 #include "js/GCHashTable.h"
16 #include "js/TypeDecls.h"
17 #include "js/Vector.h"
18 #include "vm/StringType.h"
21 * The atoms table is a mapping from strings to JSAtoms that supports
22 * incremental sweeping.
29 static inline HashNumber
hash(const Lookup
& l
);
30 static MOZ_ALWAYS_INLINE
bool match(const WeakHeapPtr
<JSAtom
*>& entry
,
31 const Lookup
& lookup
);
32 static void rekey(WeakHeapPtr
<JSAtom
*>& k
,
33 const WeakHeapPtr
<JSAtom
*>& newKey
) {
38 // Note: Use a 'class' here to make forward declarations easier to use.
39 class AtomSet
: public JS::GCHashSet
<WeakHeapPtr
<JSAtom
*>, AtomHasher
,
42 JS::GCHashSet
<WeakHeapPtr
<JSAtom
*>, AtomHasher
, SystemAllocPolicy
>;
46 explicit AtomSet(size_t length
) : Base(length
){};
49 // This class is a wrapper for AtomSet that is used to ensure the AtomSet is
50 // not modified. It should only expose read-only methods from AtomSet.
51 // Note however that the atoms within the table can be marked during GC.
56 // This constructor takes ownership of the passed-in AtomSet.
57 explicit FrozenAtomSet(AtomSet
* set
) { mSet
= set
; }
59 ~FrozenAtomSet() { js_delete(mSet
); }
61 MOZ_ALWAYS_INLINE
AtomSet::Ptr
readonlyThreadsafeLookup(
62 const AtomSet::Lookup
& l
) const;
64 size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf
) const {
65 return mSet
->shallowSizeOfIncludingThis(mallocSizeOf
);
68 using Range
= AtomSet::Range
;
70 AtomSet::Range
all() const { return mSet
->all(); }
74 // Use a low initial capacity for atom hash tables to avoid penalizing
75 // runtimes which create a small number of atoms.
76 static const size_t InitialTableSize
= 16;
78 // The main atoms set.
81 // Set of atoms added while the |atoms| set is being swept.
82 AtomSet
* atomsAddedWhileSweeping
;
84 // List of pinned atoms that are traced in every GC.
85 Vector
<JSAtom
*, 0, SystemAllocPolicy
> pinnedAtoms
;
88 // An iterator used for sweeping atoms incrementally.
89 using SweepIterator
= AtomSet::Enum
;
95 template <typename CharT
>
96 MOZ_ALWAYS_INLINE JSAtom
* atomizeAndCopyCharsNonStaticValidLength(
97 JSContext
* cx
, const CharT
* chars
, size_t length
,
98 const mozilla::Maybe
<uint32_t>& indexValue
,
99 const AtomHasher::Lookup
& lookup
);
101 bool maybePinExistingAtom(JSContext
* cx
, JSAtom
* atom
);
103 void tracePinnedAtoms(JSTracer
* trc
);
105 // Sweep all atoms non-incrementally.
106 void traceWeak(JSTracer
* trc
);
108 bool startIncrementalSweep(mozilla::Maybe
<SweepIterator
>& atomsToSweepOut
);
110 // Sweep some atoms incrementally and return whether we finished.
111 bool sweepIncrementally(SweepIterator
& atomsToSweep
, SliceBudget
& budget
);
113 size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf
) const;
116 void mergeAtomsAddedWhileSweeping();
119 bool AtomIsPinned(JSContext
* cx
, JSAtom
* atom
);
123 #endif /* vm_AtomsTable_h */