/src/mozilla-central/js/src/gc/AtomMarking-inl.h
Line | Count | Source (jump to first uncovered line) |
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 "vm/Realm.h" |
10 | | |
11 | | #include "gc/Heap-inl.h" |
12 | | |
13 | | namespace js { |
14 | | namespace gc { |
15 | | |
16 | | inline size_t |
17 | | GetAtomBit(TenuredCell* thing) |
18 | 885 | { |
19 | 885 | MOZ_ASSERT(thing->zoneFromAnyThread()->isAtomsZone()); |
20 | 885 | Arena* arena = thing->arena(); |
21 | 885 | size_t arenaBit = (reinterpret_cast<uintptr_t>(thing) - arena->address()) / CellBytesPerMarkBit; |
22 | 885 | return arena->atomBitmapStart() * JS_BITS_PER_WORD + arenaBit; |
23 | 885 | } |
24 | | |
25 | | inline bool |
26 | | ThingIsPermanent(JSAtom* atom) |
27 | 1.63M | { |
28 | 1.63M | return atom->isPinned(); |
29 | 1.63M | } |
30 | | |
31 | | inline bool |
32 | | ThingIsPermanent(JS::Symbol* symbol) |
33 | 0 | { |
34 | 0 | return symbol->isWellKnownSymbol(); |
35 | 0 | } |
36 | | |
37 | | template <typename T> |
38 | | MOZ_ALWAYS_INLINE void |
39 | | AtomMarkingRuntime::inlinedMarkAtom(JSContext* cx, T* thing) |
40 | 1.63M | { |
41 | 1.63M | static_assert(mozilla::IsSame<T, JSAtom>::value || |
42 | 1.63M | mozilla::IsSame<T, JS::Symbol>::value, |
43 | 1.63M | "Should only be called with JSAtom* or JS::Symbol* argument"); |
44 | 1.63M | |
45 | 1.63M | MOZ_ASSERT(thing); |
46 | 1.63M | js::gc::TenuredCell* cell = &thing->asTenured(); |
47 | 1.63M | MOZ_ASSERT(cell->zoneFromAnyThread()->isAtomsZone()); |
48 | 1.63M | |
49 | 1.63M | // The context's zone will be null during initialization of the runtime. |
50 | 1.63M | if (!cx->zone()) { |
51 | 261 | return; |
52 | 261 | } |
53 | 1.63M | MOZ_ASSERT(!cx->zone()->isAtomsZone()); |
54 | 1.63M | |
55 | 1.63M | if (ThingIsPermanent(thing)) { |
56 | 1.63M | return; |
57 | 1.63M | } |
58 | 885 | |
59 | 885 | size_t bit = GetAtomBit(cell); |
60 | 885 | MOZ_ASSERT(bit / JS_BITS_PER_WORD < allocatedWords); |
61 | 885 | |
62 | 885 | cx->zone()->markedAtoms().setBit(bit); |
63 | 885 | |
64 | 885 | if (!cx->helperThread()) { |
65 | 885 | // Trigger a read barrier on the atom, in case there is an incremental |
66 | 885 | // GC in progress. This is necessary if the atom is being marked |
67 | 885 | // because a reference to it was obtained from another zone which is |
68 | 885 | // not being collected by the incremental GC. |
69 | 885 | T::readBarrier(thing); |
70 | 885 | } |
71 | 885 | |
72 | 885 | // Children of the thing also need to be marked in the context's zone. |
73 | 885 | // We don't have a JSTracer for this so manually handle the cases in which |
74 | 885 | // an atom can reference other atoms. |
75 | 885 | markChildren(cx, thing); |
76 | 885 | } void js::gc::AtomMarkingRuntime::inlinedMarkAtom<JSAtom>(JSContext*, JSAtom*) Line | Count | Source | 40 | 1.63M | { | 41 | 1.63M | static_assert(mozilla::IsSame<T, JSAtom>::value || | 42 | 1.63M | mozilla::IsSame<T, JS::Symbol>::value, | 43 | 1.63M | "Should only be called with JSAtom* or JS::Symbol* argument"); | 44 | 1.63M | | 45 | 1.63M | MOZ_ASSERT(thing); | 46 | 1.63M | js::gc::TenuredCell* cell = &thing->asTenured(); | 47 | 1.63M | MOZ_ASSERT(cell->zoneFromAnyThread()->isAtomsZone()); | 48 | 1.63M | | 49 | 1.63M | // The context's zone will be null during initialization of the runtime. | 50 | 1.63M | if (!cx->zone()) { | 51 | 225 | return; | 52 | 225 | } | 53 | 1.63M | MOZ_ASSERT(!cx->zone()->isAtomsZone()); | 54 | 1.63M | | 55 | 1.63M | if (ThingIsPermanent(thing)) { | 56 | 1.63M | return; | 57 | 1.63M | } | 58 | 885 | | 59 | 885 | size_t bit = GetAtomBit(cell); | 60 | 885 | MOZ_ASSERT(bit / JS_BITS_PER_WORD < allocatedWords); | 61 | 885 | | 62 | 885 | cx->zone()->markedAtoms().setBit(bit); | 63 | 885 | | 64 | 885 | if (!cx->helperThread()) { | 65 | 885 | // Trigger a read barrier on the atom, in case there is an incremental | 66 | 885 | // GC in progress. This is necessary if the atom is being marked | 67 | 885 | // because a reference to it was obtained from another zone which is | 68 | 885 | // not being collected by the incremental GC. | 69 | 885 | T::readBarrier(thing); | 70 | 885 | } | 71 | 885 | | 72 | 885 | // Children of the thing also need to be marked in the context's zone. | 73 | 885 | // We don't have a JSTracer for this so manually handle the cases in which | 74 | 885 | // an atom can reference other atoms. | 75 | 885 | markChildren(cx, thing); | 76 | 885 | } |
void js::gc::AtomMarkingRuntime::inlinedMarkAtom<JS::Symbol>(JSContext*, JS::Symbol*) Line | Count | Source | 40 | 36 | { | 41 | 36 | static_assert(mozilla::IsSame<T, JSAtom>::value || | 42 | 36 | mozilla::IsSame<T, JS::Symbol>::value, | 43 | 36 | "Should only be called with JSAtom* or JS::Symbol* argument"); | 44 | 36 | | 45 | 36 | MOZ_ASSERT(thing); | 46 | 36 | js::gc::TenuredCell* cell = &thing->asTenured(); | 47 | 36 | MOZ_ASSERT(cell->zoneFromAnyThread()->isAtomsZone()); | 48 | 36 | | 49 | 36 | // The context's zone will be null during initialization of the runtime. | 50 | 36 | if (!cx->zone()) { | 51 | 36 | return; | 52 | 36 | } | 53 | 0 | MOZ_ASSERT(!cx->zone()->isAtomsZone()); | 54 | 0 |
| 55 | 0 | if (ThingIsPermanent(thing)) { | 56 | 0 | return; | 57 | 0 | } | 58 | 0 | | 59 | 0 | size_t bit = GetAtomBit(cell); | 60 | 0 | MOZ_ASSERT(bit / JS_BITS_PER_WORD < allocatedWords); | 61 | 0 |
| 62 | 0 | cx->zone()->markedAtoms().setBit(bit); | 63 | 0 |
| 64 | 0 | if (!cx->helperThread()) { | 65 | 0 | // Trigger a read barrier on the atom, in case there is an incremental | 66 | 0 | // GC in progress. This is necessary if the atom is being marked | 67 | 0 | // because a reference to it was obtained from another zone which is | 68 | 0 | // not being collected by the incremental GC. | 69 | 0 | T::readBarrier(thing); | 70 | 0 | } | 71 | 0 |
| 72 | 0 | // Children of the thing also need to be marked in the context's zone. | 73 | 0 | // We don't have a JSTracer for this so manually handle the cases in which | 74 | 0 | // an atom can reference other atoms. | 75 | 0 | markChildren(cx, thing); | 76 | 0 | } |
|
77 | | |
78 | | } // namespace gc |
79 | | } // namespace js |