Coverage Report

Created: 2018-09-25 14:53

/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