Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
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/. */
6 :
7 : #include "gc/AtomMarking.h"
8 :
9 : #include "jscompartment.h"
10 :
11 : #include "gc/Heap-inl.h"
12 :
13 : namespace js {
14 : namespace gc {
15 :
16 : inline size_t
17 570741 : GetAtomBit(TenuredCell* thing)
18 : {
19 570741 : MOZ_ASSERT(thing->zoneFromAnyThread()->isAtomsZone());
20 570738 : Arena* arena = thing->arena();
21 570746 : size_t arenaBit = (reinterpret_cast<uintptr_t>(thing) - arena->address()) / CellBytesPerMarkBit;
22 570745 : return arena->atomBitmapStart() * JS_BITS_PER_WORD + arenaBit;
23 : }
24 :
25 : inline bool
26 907205 : ThingIsPermanent(JSAtom* atom)
27 : {
28 907205 : return atom->isPermanentAtom();
29 : }
30 :
31 : inline bool
32 5918 : ThingIsPermanent(JS::Symbol* symbol)
33 : {
34 5918 : return symbol->isWellKnownSymbol();
35 : }
36 :
37 : template <typename T>
38 : MOZ_ALWAYS_INLINE void
39 248138 : AtomMarkingRuntime::inlinedMarkAtom(JSContext* cx, T* thing)
40 : {
41 : static_assert(mozilla::IsSame<T, JSAtom>::value ||
42 : mozilla::IsSame<T, JS::Symbol>::value,
43 : "Should only be called with JSAtom* or JS::Symbol* argument");
44 :
45 248138 : MOZ_ASSERT(thing);
46 248138 : MOZ_ASSERT(thing->zoneFromAnyThread()->isAtomsZone());
47 :
48 : // The context's zone will be null during initialization of the runtime.
49 248139 : if (!cx->zone())
50 1461 : return;
51 246677 : MOZ_ASSERT(!cx->zone()->isAtomsZone());
52 :
53 246675 : if (ThingIsPermanent(thing))
54 44378 : return;
55 :
56 202300 : size_t bit = GetAtomBit(thing);
57 202300 : MOZ_ASSERT(bit / JS_BITS_PER_WORD < allocatedWords);
58 :
59 202300 : cx->zone()->markedAtoms().setBit(bit);
60 :
61 202299 : if (!cx->helperThread()) {
62 : // Trigger a read barrier on the atom, in case there is an incremental
63 : // GC in progress. This is necessary if the atom is being marked
64 : // because a reference to it was obtained from another zone which is
65 : // not being collected by the incremental GC.
66 180194 : T::readBarrier(thing);
67 : }
68 :
69 : // Children of the thing also need to be marked in the context's zone.
70 : // We don't have a JSTracer for this so manually handle the cases in which
71 : // an atom can reference other atoms.
72 202298 : markChildren(cx, thing);
73 : }
74 :
75 : } // namespace gc
76 : } // namespace js
|