Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/js/GCPolicyAPI.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
// GC Policy Mechanism
8
9
// A GCPolicy controls how the GC interacts with both direct pointers to GC
10
// things (e.g. JSObject* or JSString*), tagged and/or optional pointers to GC
11
// things (e.g.  Value or jsid), and C++ container types (e.g.
12
// JSPropertyDescriptor or GCHashMap).
13
//
14
// The GCPolicy provides at a minimum:
15
//
16
//   static void trace(JSTracer, T* tp, const char* name)
17
//       - Trace the edge |*tp|, calling the edge |name|. Containers like
18
//         GCHashMap and GCHashSet use this method to trace their children.
19
//
20
//   static bool needsSweep(T* tp)
21
//       - Return true if |*tp| is about to be finalized. Otherwise, update the
22
//         edge for moving GC, and return false. Containers like GCHashMap and
23
//         GCHashSet use this method to decide when to remove an entry: if this
24
//         function returns true on a key/value/member/etc, its entry is dropped
25
//         from the container. Specializing this method is the standard way to
26
//         get custom weak behavior from a container type.
27
//
28
// The default GCPolicy<T> assumes that T has a default constructor and |trace|
29
// and |needsSweep| methods, and forwards to them. GCPolicy has appropriate
30
// specializations for pointers to GC things and pointer-like types like
31
// JS::Heap<T> and mozilla::UniquePtr<T>.
32
//
33
// There are some stock structs your specializations can inherit from.
34
// IgnoreGCPolicy<T> does nothing. StructGCPolicy<T> forwards the methods to the
35
// referent type T.
36
37
#ifndef GCPolicyAPI_h
38
#define GCPolicyAPI_h
39
40
#include "mozilla/Maybe.h"
41
#include "mozilla/UniquePtr.h"
42
43
#include "js/TraceKind.h"
44
#include "js/TracingAPI.h"
45
#include "js/TypeDecls.h"
46
47
// Expand the given macro D for each public GC pointer.
48
#define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \
49
    D(JS::Symbol*) \
50
    IF_BIGINT(D(JS::BigInt*),) \
51
    D(JSAtom*) \
52
    D(JSFunction*) \
53
    D(JSObject*) \
54
    D(JSScript*) \
55
    D(JSString*)
56
57
// Expand the given macro D for each public tagged GC pointer type.
58
#define FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(D) \
59
    D(JS::Value) \
60
    D(jsid)
61
62
#define FOR_EACH_PUBLIC_AGGREGATE_GC_POINTER_TYPE(D) \
63
    D(JSPropertyDescriptor)
64
65
namespace JS {
66
67
// Defines a policy for container types with non-GC, i.e. C storage. This
68
// policy dispatches to the underlying struct for GC interactions.
69
template <typename T>
70
struct StructGCPolicy
71
{
72
    static_assert(!mozilla::IsPointer<T>::value,
73
                  "Pointer type not allowed for StructGCPolicy");
74
75
107
    static void trace(JSTracer* trc, T* tp, const char* name) {
76
107
        tp->trace(trc);
77
107
    }
JS::StructGCPolicy<JS::GCVector<JSObject*, 0ul, js::SystemAllocPolicy> >::trace(JSTracer*, JS::GCVector<JSObject*, 0ul, js::SystemAllocPolicy>*, char const*)
Line
Count
Source
75
38
    static void trace(JSTracer* trc, T* tp, const char* name) {
76
38
        tp->trace(trc);
77
38
    }
JS::StructGCPolicy<JS::GCVector<JS::Value, 8ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JS::Value, 8ul, js::TempAllocPolicy>*, char const*)
Line
Count
Source
75
41
    static void trace(JSTracer* trc, T* tp, const char* name) {
76
41
        tp->trace(trc);
77
41
    }
Unexecuted instantiation: JS::StructGCPolicy<mozilla::jsipc::ObjectId>::trace(JSTracer*, mozilla::jsipc::ObjectId*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<jsid, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<jsid, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::PropertyDescriptor>::trace(JSTracer*, JS::PropertyDescriptor*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<jsid, 8ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<jsid, 8ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JSObject*, 8ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JSObject*, 8ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JSScript*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JSScript*, 0ul, js::TempAllocPolicy>*, char const*)
JS::StructGCPolicy<CallMethodHelper>::trace(JSTracer*, CallMethodHelper*, char const*)
Line
Count
Source
75
8
    static void trace(JSTracer* trc, T* tp, const char* name) {
76
8
        tp->trace(trc);
77
8
    }
Unexecuted instantiation: JS::StructGCPolicy<nsJSObjWrapperKey>::trace(JSTracer*, nsJSObjWrapperKey*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<mozilla::dom::XMLHttpRequestWorker::StateData>::trace(JSTracer*, mozilla::dom::XMLHttpRequestWorker::StateData*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::ctypes::FieldInfo>::trace(JSTracer*, js::ctypes::FieldInfo*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCHashMap<js::HeapPtr<JSFlatString*>, js::ctypes::FieldInfo, js::ctypes::FieldHashPolicy, js::SystemAllocPolicy, JS::DefaultMapSweepPolicy<js::HeapPtr<JSFlatString*>, js::ctypes::FieldInfo> > >::trace(JSTracer*, JS::GCHashMap<js::HeapPtr<JSFlatString*>, js::ctypes::FieldInfo, js::ctypes::FieldHashPolicy, js::SystemAllocPolicy, JS::DefaultMapSweepPolicy<js::HeapPtr<JSFlatString*>, js::ctypes::FieldInfo> >*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCHashMap<JSObject*, unsigned int, js::MovableCellHasher<JSObject*>, js::SystemAllocPolicy, JS::DefaultMapSweepPolicy<JSObject*, unsigned int> > >::trace(JSTracer*, JS::GCHashMap<JSObject*, unsigned int, js::MovableCellHasher<JSObject*>, js::SystemAllocPolicy, JS::DefaultMapSweepPolicy<JSObject*, unsigned int> >*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCHashSet<JSObject*, JSStructuredCloneWriter::TransferableObjectsHasher, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCHashSet<JSObject*, JSStructuredCloneWriter::TransferableObjectsHasher, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JS::Value, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JS::Value, 0ul, js::TempAllocPolicy>*, char const*)
JS::StructGCPolicy<js::TaggedProto>::trace(JSTracer*, js::TaggedProto*, char const*)
Line
Count
Source
75
1
    static void trace(JSTracer* trc, T* tp, const char* name) {
76
1
        tp->trace(trc);
77
1
    }
Unexecuted instantiation: JS::StructGCPolicy<JS::GCHashSet<jsid, mozilla::DefaultHasher<jsid>, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCHashSet<jsid, mozilla::DefaultHasher<jsid>, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::JSONParser<unsigned char> >::trace(JSTracer*, js::JSONParser<unsigned char>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::JSONParser<char16_t> >::trace(JSTracer*, js::JSONParser<char16_t>*, char const*)
JS::StructGCPolicy<js::LiveSavedFrameCache>::trace(JSTracer*, js::LiveSavedFrameCache*, char const*)
Line
Count
Source
75
14
    static void trace(JSTracer* trc, T* tp, const char* name) {
76
14
        tp->trace(trc);
77
14
    }
JS::StructGCPolicy<JS::PropertyResult>::trace(JSTracer*, JS::PropertyResult*, char const*)
Line
Count
Source
75
5
    static void trace(JSTracer* trc, T* tp, const char* name) {
76
5
        tp->trace(trc);
77
5
    }
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JS::PropertyDescriptor, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JS::PropertyDescriptor, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::Shape*, 8ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::Shape*, 8ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::HashableValue>::trace(JSTracer*, js::HashableValue*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::FunctionDeclaration>::trace(JSTracer*, js::FunctionDeclaration*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCHashSet<JSAtom*, mozilla::DefaultHasher<JSAtom*>, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCHashSet<JSAtom*, mozilla::DefaultHasher<JSAtom*>, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::RequestedModuleObject*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::RequestedModuleObject*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCHashMap<JSAtom*, js::ImportEntryObject*, mozilla::DefaultHasher<JSAtom*>, js::TempAllocPolicy, JS::DefaultMapSweepPolicy<JSAtom*, js::ImportEntryObject*> > >::trace(JSTracer*, JS::GCHashMap<JSAtom*, js::ImportEntryObject*, mozilla::DefaultHasher<JSAtom*>, js::TempAllocPolicy, JS::DefaultMapSweepPolicy<JSAtom*, js::ImportEntryObject*> >*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::ExportEntryObject*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::ExportEntryObject*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<PromiseCapability>::trace(JSTracer*, PromiseCapability*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JSString*, 16ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JSString*, 16ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JS::GCVector<JS::GCVector<JS::Value, 0ul, js::TempAllocPolicy>, 0ul, js::TempAllocPolicy>, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JS::GCVector<JS::GCVector<JS::Value, 0ul, js::TempAllocPolicy>, 0ul, js::TempAllocPolicy>, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JS::GCVector<JS::Value, 0ul, js::TempAllocPolicy>, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JS::GCVector<JS::Value, 0ul, js::TempAllocPolicy>, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::jit::RematerializedFrame*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::jit::RematerializedFrame*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::ScriptAndCounts, 0ul, js::SystemAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::ScriptAndCounts, 0ul, js::SystemAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::ScriptAndCounts>::trace(JSTracer*, js::ScriptAndCounts*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::LazyScript*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::LazyScript*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::WasmInstanceObject*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::WasmInstanceObject*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCHashSet<JSObject*, js::MovableCellHasher<JSObject*>, js::ZoneAllocPolicy> >::trace(JSTracer*, JS::GCHashSet<JSObject*, js::MovableCellHasher<JSObject*>, js::ZoneAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::DebuggerFrame*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::DebuggerFrame*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JSObject*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JSObject*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::Debugger::AllocationsLogEntry>::trace(JSTracer*, js::Debugger::AllocationsLogEntry*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::CrossCompartmentKey>::trace(JSTracer*, js::CrossCompartmentKey*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JSString*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JSString*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::BindingIter>::trace(JSTracer*, js::BindingIter*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::ScopeIter>::trace(JSTracer*, js::ScopeIter*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::StackShape>::trace(JSTracer*, js::StackShape*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::ParseTask>::trace(JSTracer*, js::ParseTask*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::Shape*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::Shape*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::IdValuePair>::trace(JSTracer*, js::IdValuePair*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::IdValuePair, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::IdValuePair, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::Scope*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::Scope*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::TypeSet::Type>::trace(JSTracer*, js::TypeSet::Type*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::ObjectGroupRealm::AllocationSiteKey>::trace(JSTracer*, js::ObjectGroupRealm::AllocationSiteKey*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::SavedStacks::LocationValue>::trace(JSTracer*, js::SavedStacks::LocationValue*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::SavedStacks::PCKey>::trace(JSTracer*, js::SavedStacks::PCKey*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::ubi::StackFrame>::trace(JSTracer*, JS::ubi::StackFrame*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::VarScope::Data>::trace(JSTracer*, js::VarScope::Data*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::LexicalScope::Data>::trace(JSTracer*, js::LexicalScope::Data*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::EvalScope::Data>::trace(JSTracer*, js::EvalScope::Data*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::FunctionScope::Data>::trace(JSTracer*, js::FunctionScope::Data*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::GlobalScope::Data>::trace(JSTracer*, js::GlobalScope::Data*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::ModuleScope::Data>::trace(JSTracer*, js::ModuleScope::Data*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::WasmInstanceScope::Data>::trace(JSTracer*, js::WasmInstanceScope::Data*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::WasmFunctionScope::Data>::trace(JSTracer*, js::WasmFunctionScope::Data*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::wasm::Val, 0ul, js::SystemAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::wasm::Val, 0ul, js::SystemAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<js::wasm::Val>::trace(JSTracer*, js::wasm::Val*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JSFunction*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JSFunction*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::WasmGlobalObject*, 0ul, js::SystemAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::WasmGlobalObject*, 0ul, js::SystemAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<js::HeapPtr<js::StructTypeDescr*>, 0ul, js::SystemAllocPolicy> >::trace(JSTracer*, JS::GCVector<js::HeapPtr<js::StructTypeDescr*>, 0ul, js::SystemAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JS::Value, 4ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JS::Value, 4ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JSAtom*, 0ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JSAtom*, 0ul, js::TempAllocPolicy>*, char const*)
Unexecuted instantiation: JS::StructGCPolicy<JS::GCVector<JSFunction*, 8ul, js::TempAllocPolicy> >::trace(JSTracer*, JS::GCVector<JSFunction*, 8ul, js::TempAllocPolicy>*, char const*)
78
79
0
    static void sweep(T* tp) {
80
0
        return tp->sweep();
81
0
    }
82
83
3.26M
    static bool needsSweep(T* tp) {
84
3.26M
        return tp->needsSweep();
85
3.26M
    }
Unexecuted instantiation: JS::StructGCPolicy<mozilla::jsipc::ObjectId>::needsSweep(mozilla::jsipc::ObjectId*)
Unexecuted instantiation: JS::StructGCPolicy<js::EvalCacheEntry>::needsSweep(js::EvalCacheEntry*)
Unexecuted instantiation: JS::StructGCPolicy<js::CrossCompartmentKey>::needsSweep(js::CrossCompartmentKey*)
JS::StructGCPolicy<js::InitialShapeEntry>::needsSweep(js::InitialShapeEntry*)
Line
Count
Source
83
1.63M
    static bool needsSweep(T* tp) {
84
1.63M
        return tp->needsSweep();
85
1.63M
    }
Unexecuted instantiation: JS::StructGCPolicy<js::LiveEnvironmentVal>::needsSweep(js::LiveEnvironmentVal*)
JS::StructGCPolicy<js::ObjectGroupRealm::NewEntry>::needsSweep(js::ObjectGroupRealm::NewEntry*)
Line
Count
Source
83
1.63M
    static bool needsSweep(T* tp) {
84
1.63M
        return tp->needsSweep();
85
1.63M
    }
JS::StructGCPolicy<js::ObjectGroupRealm::AllocationSiteKey>::needsSweep(js::ObjectGroupRealm::AllocationSiteKey*)
Line
Count
Source
83
177
    static bool needsSweep(T* tp) {
84
177
        return tp->needsSweep();
85
177
    }
JS::StructGCPolicy<js::ObjectGroupRealm::PlainObjectKey>::needsSweep(js::ObjectGroupRealm::PlainObjectKey*)
Line
Count
Source
83
18
    static bool needsSweep(T* tp) {
84
18
        return tp->needsSweep();
85
18
    }
Unexecuted instantiation: JS::StructGCPolicy<js::ObjectGroupRealm::ArrayObjectKey>::needsSweep(js::ObjectGroupRealm::ArrayObjectKey*)
Unexecuted instantiation: JS::StructGCPolicy<js::SavedStacks::PCKey>::needsSweep(js::SavedStacks::PCKey*)
Unexecuted instantiation: JS::StructGCPolicy<js::SavedStacks::LocationValue>::needsSweep(js::SavedStacks::LocationValue*)
86
87
    static bool isValid(const T& tp) {
88
        return true;
89
    }
90
};
91
92
// The default GC policy attempts to defer to methods on the underlying type.
93
// Most C++ structures that contain a default constructor, a trace function and
94
// a sweep function will work out of the box with Rooted, Handle, GCVector,
95
// and GCHash{Set,Map}.
96
template <typename T> struct GCPolicy : public StructGCPolicy<T> {};
97
98
// This policy ignores any GC interaction, e.g. for non-GC types.
99
template <typename T>
100
struct IgnoreGCPolicy {
101
0
    static void trace(JSTracer* trc, T* t, const char* name) {}
102
0
    static bool needsSweep(T* v) { return false; }
103
    static bool isValid(const T& v) { return true; }
104
};
105
template <> struct GCPolicy<uint32_t> : public IgnoreGCPolicy<uint32_t> {};
106
template <> struct GCPolicy<uint64_t> : public IgnoreGCPolicy<uint64_t> {};
107
108
template <typename T>
109
struct GCPointerPolicy
110
{
111
    static_assert(mozilla::IsPointer<T>::value,
112
                  "Non-pointer type not allowed for GCPointerPolicy");
113
114
0
    static void trace(JSTracer* trc, T* vp, const char* name) {
115
0
        if (*vp) {
116
0
            js::UnsafeTraceManuallyBarrieredEdge(trc, vp, name);
117
0
        }
118
0
    }
Unexecuted instantiation: JS::GCPointerPolicy<JSObject*>::trace(JSTracer*, JSObject**, char const*)
Unexecuted instantiation: JS::GCPointerPolicy<JSScript*>::trace(JSTracer*, JSScript**, char const*)
Unexecuted instantiation: JS::GCPointerPolicy<JSAtom*>::trace(JSTracer*, JSAtom**, char const*)
Unexecuted instantiation: JS::GCPointerPolicy<JSString*>::trace(JSTracer*, JSString**, char const*)
Unexecuted instantiation: JS::GCPointerPolicy<JSFunction*>::trace(JSTracer*, JSFunction**, char const*)
119
0
    static bool needsSweep(T* vp) {
120
0
        if (*vp) {
121
0
            return js::gc::IsAboutToBeFinalizedUnbarriered(vp);
122
0
        }
123
0
        return false;
124
0
    }
Unexecuted instantiation: JS::GCPointerPolicy<JSObject*>::needsSweep(JSObject**)
Unexecuted instantiation: JS::GCPointerPolicy<JSAtom*>::needsSweep(JSAtom**)
125
    static bool isValid(T v) {
126
        return js::gc::IsCellPointerValidOrNull(v);
127
    }
128
};
129
#define EXPAND_SPECIALIZE_GCPOLICY(Type) \
130
    template <> struct GCPolicy<Type> : public GCPointerPolicy<Type> {}; \
131
    template <> struct GCPolicy<Type const> : public GCPointerPolicy<Type const> {};
132
FOR_EACH_PUBLIC_GC_POINTER_TYPE(EXPAND_SPECIALIZE_GCPOLICY)
133
#undef EXPAND_SPECIALIZE_GCPOLICY
134
135
template <typename T>
136
struct NonGCPointerPolicy
137
{
138
0
    static void trace(JSTracer* trc, T* vp, const char* name) {
139
0
        if (*vp) {
140
0
            (*vp)->trace(trc);
141
0
        }
142
0
    }
Unexecuted instantiation: JS::NonGCPointerPolicy<js::GlobalScope::Data*>::trace(JSTracer*, js::GlobalScope::Data**, char const*)
Unexecuted instantiation: JS::NonGCPointerPolicy<js::jit::RematerializedFrame*>::trace(JSTracer*, js::jit::RematerializedFrame**, char const*)
Unexecuted instantiation: JS::NonGCPointerPolicy<js::LexicalScope::Data*>::trace(JSTracer*, js::LexicalScope::Data**, char const*)
Unexecuted instantiation: JS::NonGCPointerPolicy<js::FunctionScope::Data*>::trace(JSTracer*, js::FunctionScope::Data**, char const*)
Unexecuted instantiation: JS::NonGCPointerPolicy<js::VarScope::Data*>::trace(JSTracer*, js::VarScope::Data**, char const*)
Unexecuted instantiation: JS::NonGCPointerPolicy<js::EvalScope::Data*>::trace(JSTracer*, js::EvalScope::Data**, char const*)
Unexecuted instantiation: JS::NonGCPointerPolicy<js::ModuleScope::Data*>::trace(JSTracer*, js::ModuleScope::Data**, char const*)
143
    static bool needsSweep(T* vp) {
144
        if (*vp) {
145
            return (*vp)->needsSweep();
146
        }
147
        return false;
148
    }
149
    static bool isValid(T v) {
150
        return true;
151
    }
152
};
153
154
template <typename T>
155
struct GCPolicy<JS::Heap<T>>
156
{
157
0
    static void trace(JSTracer* trc, JS::Heap<T>* thingp, const char* name) {
158
0
        TraceEdge(trc, thingp, name);
159
0
    }
160
0
    static bool needsSweep(JS::Heap<T>* thingp) {
161
0
        return *thingp && js::gc::EdgeNeedsSweep(thingp);
162
0
    }
163
};
164
165
// GCPolicy<UniquePtr<T>> forwards the contained pointer to GCPolicy<T>.
166
template <typename T, typename D>
167
struct GCPolicy<mozilla::UniquePtr<T, D>>
168
{
169
0
    static void trace(JSTracer* trc, mozilla::UniquePtr<T,D>* tp, const char* name) {
170
0
        if (tp->get()) {
171
0
            GCPolicy<T>::trace(trc, tp->get(), name);
172
0
        }
173
0
    }
Unexecuted instantiation: JS::GCPolicy<mozilla::UniquePtr<mozilla::dom::XMLHttpRequestWorker::StateData, mozilla::DefaultDelete<mozilla::dom::XMLHttpRequestWorker::StateData> > >::trace(JSTracer*, mozilla::UniquePtr<mozilla::dom::XMLHttpRequestWorker::StateData, mozilla::DefaultDelete<mozilla::dom::XMLHttpRequestWorker::StateData> >*, char const*)
Unexecuted instantiation: JS::GCPolicy<mozilla::UniquePtr<js::ParseTask, JS::DeletePolicy<js::ParseTask> > >::trace(JSTracer*, mozilla::UniquePtr<js::ParseTask, JS::DeletePolicy<js::ParseTask> >*, char const*)
Unexecuted instantiation: JS::GCPolicy<mozilla::UniquePtr<js::VarScope::Data, JS::DeletePolicy<js::VarScope::Data> > >::trace(JSTracer*, mozilla::UniquePtr<js::VarScope::Data, JS::DeletePolicy<js::VarScope::Data> >*, char const*)
Unexecuted instantiation: JS::GCPolicy<mozilla::UniquePtr<js::LexicalScope::Data, JS::DeletePolicy<js::LexicalScope::Data> > >::trace(JSTracer*, mozilla::UniquePtr<js::LexicalScope::Data, JS::DeletePolicy<js::LexicalScope::Data> >*, char const*)
Unexecuted instantiation: JS::GCPolicy<mozilla::UniquePtr<js::EvalScope::Data, JS::DeletePolicy<js::EvalScope::Data> > >::trace(JSTracer*, mozilla::UniquePtr<js::EvalScope::Data, JS::DeletePolicy<js::EvalScope::Data> >*, char const*)
Unexecuted instantiation: JS::GCPolicy<mozilla::UniquePtr<js::FunctionScope::Data, JS::DeletePolicy<js::FunctionScope::Data> > >::trace(JSTracer*, mozilla::UniquePtr<js::FunctionScope::Data, JS::DeletePolicy<js::FunctionScope::Data> >*, char const*)
Unexecuted instantiation: JS::GCPolicy<mozilla::UniquePtr<js::GlobalScope::Data, JS::DeletePolicy<js::GlobalScope::Data> > >::trace(JSTracer*, mozilla::UniquePtr<js::GlobalScope::Data, JS::DeletePolicy<js::GlobalScope::Data> >*, char const*)
Unexecuted instantiation: JS::GCPolicy<mozilla::UniquePtr<js::ModuleScope::Data, JS::DeletePolicy<js::ModuleScope::Data> > >::trace(JSTracer*, mozilla::UniquePtr<js::ModuleScope::Data, JS::DeletePolicy<js::ModuleScope::Data> >*, char const*)
Unexecuted instantiation: JS::GCPolicy<mozilla::UniquePtr<js::WasmInstanceScope::Data, JS::DeletePolicy<js::WasmInstanceScope::Data> > >::trace(JSTracer*, mozilla::UniquePtr<js::WasmInstanceScope::Data, JS::DeletePolicy<js::WasmInstanceScope::Data> >*, char const*)
Unexecuted instantiation: JS::GCPolicy<mozilla::UniquePtr<js::WasmFunctionScope::Data, JS::DeletePolicy<js::WasmFunctionScope::Data> > >::trace(JSTracer*, mozilla::UniquePtr<js::WasmFunctionScope::Data, JS::DeletePolicy<js::WasmFunctionScope::Data> >*, char const*)
Unexecuted instantiation: JS::GCPolicy<mozilla::UniquePtr<JS::GCVector<js::WasmGlobalObject*, 0ul, js::SystemAllocPolicy>, JS::DeletePolicy<JS::GCVector<js::WasmGlobalObject*, 0ul, js::SystemAllocPolicy> > > >::trace(JSTracer*, mozilla::UniquePtr<JS::GCVector<js::WasmGlobalObject*, 0ul, js::SystemAllocPolicy>, JS::DeletePolicy<JS::GCVector<js::WasmGlobalObject*, 0ul, js::SystemAllocPolicy> > >*, char const*)
174
    static bool needsSweep(mozilla::UniquePtr<T,D>* tp) {
175
        if (tp->get()) {
176
            return GCPolicy<T>::needsSweep(tp->get());
177
        }
178
        return false;
179
    }
180
    static bool isValid(const mozilla::UniquePtr<T,D>& t) {
181
        if (t.get()) {
182
            return GCPolicy<T>::isValid(*t.get());
183
        }
184
        return true;
185
    }
186
};
187
188
// GCPolicy<Maybe<T>> forwards tracing/sweeping to GCPolicy<T*> if
189
// when the Maybe<T> is full.
190
template <typename T>
191
struct GCPolicy<mozilla::Maybe<T>>
192
{
193
    static void trace(JSTracer* trc, mozilla::Maybe<T>* tp, const char* name) {
194
        if (tp->isSome()) {
195
            GCPolicy<T>::trace(trc, tp->ptr(), name);
196
        }
197
    }
198
    static bool needsSweep(mozilla::Maybe<T>* tp) {
199
        if (tp->isSome()) {
200
            return GCPolicy<T>::needsSweep(tp->ptr());
201
        }
202
        return false;
203
    }
204
    static bool isValid(const mozilla::Maybe<T>& t) {
205
        if (t.isSome()) {
206
            return GCPolicy<T>::isValid(t.ref());
207
        }
208
        return true;
209
    }
210
};
211
212
template <> struct GCPolicy<JS::Realm*>;  // see Realm.h
213
214
} // namespace JS
215
216
#endif // GCPolicyAPI_h