зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1220310 - Generalize GC container trace function dispatch as GCPolicy; r=sfink
--HG-- extra : rebase_source : bf48dcfef48b74c1596a47decad9f52ea8a4bc2f
This commit is contained in:
Родитель
7aba170c6a
Коммит
80c5df8a70
|
@ -13,15 +13,23 @@
|
|||
|
||||
namespace js {
|
||||
|
||||
// Define a reasonable default GC policy for GC-aware Maps.
|
||||
template <typename Key, typename Value>
|
||||
struct DefaultMapGCPolicy {
|
||||
using KeyPolicy = DefaultGCPolicy<Key>;
|
||||
using ValuePolicy = DefaultGCPolicy<Value>;
|
||||
};
|
||||
|
||||
// A TraceableHashMap is a HashMap with an additional trace method that knows
|
||||
// how to visit all keys and values in the table. HashMaps that contain GC
|
||||
// pointers that must be traced to be kept alive will generally want to use
|
||||
// this TraceableHashMap specializeation in lieu of HashMap.
|
||||
//
|
||||
// Most types of GC pointers as keys and values can be traced with no extra
|
||||
// infrastructure. For structs and non-gc-pointer members, ensure that there
|
||||
// is a specialization of DefaultTracer<T> with an appropriate trace method
|
||||
// available to handle the custom type.
|
||||
// infrastructure. For structs and non-gc-pointer members, ensure that there
|
||||
// is a specialization of DefaultGCPolicy<T> with an appropriate trace method
|
||||
// available to handle the custom type. Generic helpers can be found in
|
||||
// js/public/TracingAPI.h.
|
||||
//
|
||||
// Note that although this HashMap's trace will deal correctly with moved keys,
|
||||
// it does not itself know when to barrier or trace keys. To function properly
|
||||
|
@ -30,8 +38,7 @@ template <typename Key,
|
|||
typename Value,
|
||||
typename HashPolicy = DefaultHasher<Key>,
|
||||
typename AllocPolicy = TempAllocPolicy,
|
||||
typename KeyTraceFunc = DefaultTracer<Key>,
|
||||
typename ValueTraceFunc = DefaultTracer<Value>>
|
||||
typename GCPolicy = DefaultMapGCPolicy<Key, Value>>
|
||||
class TraceableHashMap : public HashMap<Key, Value, HashPolicy, AllocPolicy>,
|
||||
public JS::Traceable
|
||||
{
|
||||
|
@ -45,9 +52,9 @@ class TraceableHashMap : public HashMap<Key, Value, HashPolicy, AllocPolicy>,
|
|||
if (!this->initialized())
|
||||
return;
|
||||
for (typename Base::Enum e(*this); !e.empty(); e.popFront()) {
|
||||
ValueTraceFunc::trace(trc, &e.front().value(), "hashmap value");
|
||||
GCPolicy::ValuePolicy::trace(trc, &e.front().value(), "hashmap value");
|
||||
Key key = e.front().key();
|
||||
KeyTraceFunc::trace(trc, &key, "hashmap key");
|
||||
GCPolicy::KeyPolicy::trace(trc, &key, "hashmap key");
|
||||
if (key != e.front().key())
|
||||
e.rekeyFront(key);
|
||||
}
|
||||
|
@ -137,40 +144,40 @@ class MutableTraceableHashMapOperations
|
|||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B, typename C, typename D, typename E, typename F>
|
||||
class RootedBase<TraceableHashMap<A,B,C,D,E,F>>
|
||||
: public MutableTraceableHashMapOperations<JS::Rooted<TraceableHashMap<A,B,C,D,E,F>>, A,B,C,D,E,F>
|
||||
template <typename A, typename B, typename C, typename D, typename E>
|
||||
class RootedBase<TraceableHashMap<A,B,C,D,E>>
|
||||
: public MutableTraceableHashMapOperations<JS::Rooted<TraceableHashMap<A,B,C,D,E>>, A,B,C,D,E>
|
||||
{};
|
||||
|
||||
template <typename A, typename B, typename C, typename D, typename E, typename F>
|
||||
class MutableHandleBase<TraceableHashMap<A,B,C,D,E,F>>
|
||||
: public MutableTraceableHashMapOperations<JS::MutableHandle<TraceableHashMap<A,B,C,D,E,F>>,
|
||||
A,B,C,D,E,F>
|
||||
template <typename A, typename B, typename C, typename D, typename E>
|
||||
class MutableHandleBase<TraceableHashMap<A,B,C,D,E>>
|
||||
: public MutableTraceableHashMapOperations<JS::MutableHandle<TraceableHashMap<A,B,C,D,E>>,
|
||||
A,B,C,D,E>
|
||||
{};
|
||||
|
||||
template <typename A, typename B, typename C, typename D, typename E, typename F>
|
||||
class HandleBase<TraceableHashMap<A,B,C,D,E,F>>
|
||||
: public TraceableHashMapOperations<JS::Handle<TraceableHashMap<A,B,C,D,E,F>>, A,B,C,D,E,F>
|
||||
template <typename A, typename B, typename C, typename D, typename E>
|
||||
class HandleBase<TraceableHashMap<A,B,C,D,E>>
|
||||
: public TraceableHashMapOperations<JS::Handle<TraceableHashMap<A,B,C,D,E>>, A,B,C,D,E>
|
||||
{};
|
||||
|
||||
// A TraceableHashSet is a HashSet with an additional trace method that knows
|
||||
// how to visit all set element. HashSets that contain GC pointers that must
|
||||
// how to visit all set elements. HashSets that contain GC pointers that must
|
||||
// be traced to be kept alive will generally want to use this TraceableHashSet
|
||||
// specializeation in lieu of HashSet.
|
||||
//
|
||||
// Most types of GC pointers can be traced with no extra infrastructure. For
|
||||
// Most types of GC pointers can be traced with no extra infrastructure. For
|
||||
// structs and non-gc-pointer members, ensure that there is a specialization of
|
||||
// DefaultTracer<T> with an appropriate trace method available to handle the
|
||||
// custom type.
|
||||
// DefaultGCPolicy<T> with an appropriate trace method available to handle the
|
||||
// custom type. Generic helpers can be found in js/public/TracingAPI.h.
|
||||
//
|
||||
// Note that although this HashSet's trace will deal correctly with moved
|
||||
// elements, it does not itself know when to barrier or trace elements. To
|
||||
// elements, it does not itself know when to barrier or trace elements. To
|
||||
// function properly it must either be used with Rooted or barriered and traced
|
||||
// manually.
|
||||
template <typename T,
|
||||
typename HashPolicy = DefaultHasher<T>,
|
||||
typename AllocPolicy = TempAllocPolicy,
|
||||
typename ElemTraceFunc = DefaultTracer<T>>
|
||||
typename GCPolicy = DefaultGCPolicy<T>>
|
||||
class TraceableHashSet : public HashSet<T, HashPolicy, AllocPolicy>,
|
||||
public JS::Traceable
|
||||
{
|
||||
|
@ -185,7 +192,7 @@ class TraceableHashSet : public HashSet<T, HashPolicy, AllocPolicy>,
|
|||
return;
|
||||
for (typename Base::Enum e(*this); !e.empty(); e.popFront()) {
|
||||
T elem = e.front();
|
||||
ElemTraceFunc::trace(trc, &elem, "hashset element");
|
||||
GCPolicy::trace(trc, &elem, "hashset element");
|
||||
if (elem != e.front())
|
||||
e.rekeyFront(elem);
|
||||
}
|
||||
|
@ -273,41 +280,42 @@ class MutableTraceableHashSetOperations
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename HP, typename AP, typename TF>
|
||||
class RootedBase<TraceableHashSet<T, HP, AP, TF>>
|
||||
: public MutableTraceableHashSetOperations<JS::Rooted<TraceableHashSet<T, HP, AP, TF>>, T, HP, AP, TF>
|
||||
template <typename T, typename HP, typename AP, typename GP>
|
||||
class RootedBase<TraceableHashSet<T, HP, AP, GP>>
|
||||
: public MutableTraceableHashSetOperations<JS::Rooted<TraceableHashSet<T, HP, AP, GP>>,
|
||||
T, HP, AP, GP>
|
||||
{
|
||||
using Set = TraceableHashSet<T, HP, AP, TF>;
|
||||
using Set = TraceableHashSet<T, HP, AP, GP>;
|
||||
|
||||
friend class TraceableHashSetOperations<JS::Rooted<Set>, T, HP, AP, TF>;
|
||||
friend class TraceableHashSetOperations<JS::Rooted<Set>, T, HP, AP, GP>;
|
||||
const Set& extract() const { return *static_cast<const JS::Rooted<Set>*>(this)->address(); }
|
||||
|
||||
friend class MutableTraceableHashSetOperations<JS::Rooted<Set>, T, HP, AP, TF>;
|
||||
friend class MutableTraceableHashSetOperations<JS::Rooted<Set>, T, HP, AP, GP>;
|
||||
Set& extract() { return *static_cast<JS::Rooted<Set>*>(this)->address(); }
|
||||
};
|
||||
|
||||
template <typename T, typename HP, typename AP, typename TF>
|
||||
class MutableHandleBase<TraceableHashSet<T, HP, AP, TF>>
|
||||
: public MutableTraceableHashSetOperations<JS::MutableHandle<TraceableHashSet<T, HP, AP, TF>>,
|
||||
T, HP, AP, TF>
|
||||
template <typename T, typename HP, typename AP, typename GP>
|
||||
class MutableHandleBase<TraceableHashSet<T, HP, AP, GP>>
|
||||
: public MutableTraceableHashSetOperations<JS::MutableHandle<TraceableHashSet<T, HP, AP, GP>>,
|
||||
T, HP, AP, GP>
|
||||
{
|
||||
using Set = TraceableHashSet<T, HP, AP, TF>;
|
||||
using Set = TraceableHashSet<T, HP, AP, GP>;
|
||||
|
||||
friend class TraceableHashSetOperations<JS::MutableHandle<Set>, T, HP, AP, TF>;
|
||||
friend class TraceableHashSetOperations<JS::MutableHandle<Set>, T, HP, AP, GP>;
|
||||
const Set& extract() const {
|
||||
return *static_cast<const JS::MutableHandle<Set>*>(this)->address();
|
||||
}
|
||||
|
||||
friend class MutableTraceableHashSetOperations<JS::MutableHandle<Set>, T, HP, AP, TF>;
|
||||
friend class MutableTraceableHashSetOperations<JS::MutableHandle<Set>, T, HP, AP, GP>;
|
||||
Set& extract() { return *static_cast<JS::MutableHandle<Set>*>(this)->address(); }
|
||||
};
|
||||
|
||||
template <typename T, typename HP, typename AP, typename TF>
|
||||
class HandleBase<TraceableHashSet<T, HP, AP, TF>>
|
||||
: public TraceableHashSetOperations<JS::Handle<TraceableHashSet<T, HP, AP, TF>>, T, HP, AP, TF>
|
||||
template <typename T, typename HP, typename AP, typename GP>
|
||||
class HandleBase<TraceableHashSet<T, HP, AP, GP>>
|
||||
: public TraceableHashSetOperations<JS::Handle<TraceableHashSet<T, HP, AP, GP>>, T, HP, AP, GP>
|
||||
{
|
||||
using Set = TraceableHashSet<T, HP, AP, TF>;
|
||||
friend class TraceableHashSetOperations<JS::Handle<Set>, T, HP, AP, TF>;
|
||||
using Set = TraceableHashSet<T, HP, AP, GP>;
|
||||
friend class TraceableHashSetOperations<JS::Handle<Set>, T, HP, AP, GP>;
|
||||
const Set& extract() const { return *static_cast<const JS::Handle<Set>*>(this)->address(); }
|
||||
};
|
||||
|
||||
|
|
|
@ -22,8 +22,9 @@ namespace js {
|
|||
//
|
||||
// Most types of GC pointers as keys and values can be traced with no extra
|
||||
// infrastructure. For structs and non-gc-pointer members, ensure that there
|
||||
// is a specialization of DefaultTracer<T> with an appropriate trace method
|
||||
// available to handle the custom type.
|
||||
// is a specialization of DefaultGCPolicy<T> with an appropriate trace method
|
||||
// available to handle the custom type. Generic helpers can be found in
|
||||
// js/public/TracingAPI.h.
|
||||
//
|
||||
// Note that although this Vector's trace will deal correctly with moved items,
|
||||
// it does not itself know when to barrier or trace items. To function properly
|
||||
|
@ -31,12 +32,12 @@ namespace js {
|
|||
template <typename T,
|
||||
size_t MinInlineCapacity = 0,
|
||||
typename AllocPolicy = TempAllocPolicy,
|
||||
typename TraceFunc = DefaultTracer<T>>
|
||||
typename GCPolicy = DefaultGCPolicy<T>>
|
||||
class TraceableVector
|
||||
: public mozilla::VectorBase<T,
|
||||
MinInlineCapacity,
|
||||
AllocPolicy,
|
||||
TraceableVector<T, MinInlineCapacity, AllocPolicy, TraceFunc>>,
|
||||
TraceableVector<T, MinInlineCapacity, AllocPolicy, GCPolicy>>,
|
||||
public JS::Traceable
|
||||
{
|
||||
using Base = mozilla::VectorBase<T, MinInlineCapacity, AllocPolicy, TraceableVector>;
|
||||
|
@ -51,14 +52,14 @@ class TraceableVector
|
|||
static void trace(TraceableVector* vec, JSTracer* trc) { vec->trace(trc); }
|
||||
void trace(JSTracer* trc) {
|
||||
for (size_t i = 0; i < this->length(); ++i)
|
||||
TraceFunc::trace(trc, &Base::operator[](i), "vector element");
|
||||
GCPolicy::trace(trc, &Base::operator[](i), "vector element");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy, typename TraceFunc>
|
||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy, typename GCPolicy>
|
||||
class TraceableVectorOperations
|
||||
{
|
||||
using Vec = TraceableVector<T, Capacity, AllocPolicy, TraceFunc>;
|
||||
using Vec = TraceableVector<T, Capacity, AllocPolicy, GCPolicy>;
|
||||
const Vec& vec() const { return static_cast<const Outer*>(this)->get(); }
|
||||
|
||||
public:
|
||||
|
@ -76,11 +77,11 @@ class TraceableVectorOperations
|
|||
}
|
||||
};
|
||||
|
||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy, typename TraceFunc>
|
||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy, typename GCPolicy>
|
||||
class MutableTraceableVectorOperations
|
||||
: public TraceableVectorOperations<Outer, T, Capacity, AllocPolicy, TraceFunc>
|
||||
: public TraceableVectorOperations<Outer, T, Capacity, AllocPolicy, GCPolicy>
|
||||
{
|
||||
using Vec = TraceableVector<T, Capacity, AllocPolicy, TraceFunc>;
|
||||
using Vec = TraceableVector<T, Capacity, AllocPolicy, GCPolicy>;
|
||||
const Vec& vec() const { return static_cast<const Outer*>(this)->get(); }
|
||||
Vec& vec() { return static_cast<Outer*>(this)->get(); }
|
||||
|
||||
|
@ -141,26 +142,26 @@ class MutableTraceableVectorOperations
|
|||
void erase(T* aBegin, T* aEnd) { vec().erase(aBegin, aEnd); }
|
||||
};
|
||||
|
||||
template <typename T, size_t N, typename AP, typename TP>
|
||||
class RootedBase<TraceableVector<T,N,AP,TP>>
|
||||
: public MutableTraceableVectorOperations<JS::Rooted<TraceableVector<T,N,AP,TP>>, T,N,AP,TP>
|
||||
template <typename T, size_t N, typename AP, typename GP>
|
||||
class RootedBase<TraceableVector<T,N,AP,GP>>
|
||||
: public MutableTraceableVectorOperations<JS::Rooted<TraceableVector<T,N,AP,GP>>, T,N,AP,GP>
|
||||
{};
|
||||
|
||||
template <typename T, size_t N, typename AP, typename TP>
|
||||
class MutableHandleBase<TraceableVector<T,N,AP,TP>>
|
||||
: public MutableTraceableVectorOperations<JS::MutableHandle<TraceableVector<T,N,AP,TP>>,
|
||||
T,N,AP,TP>
|
||||
template <typename T, size_t N, typename AP, typename GP>
|
||||
class MutableHandleBase<TraceableVector<T,N,AP,GP>>
|
||||
: public MutableTraceableVectorOperations<JS::MutableHandle<TraceableVector<T,N,AP,GP>>,
|
||||
T,N,AP,GP>
|
||||
{};
|
||||
|
||||
template <typename T, size_t N, typename AP, typename TP>
|
||||
class HandleBase<TraceableVector<T,N,AP,TP>>
|
||||
: public TraceableVectorOperations<JS::Handle<TraceableVector<T,N,AP,TP>>, T,N,AP,TP>
|
||||
template <typename T, size_t N, typename AP, typename GP>
|
||||
class HandleBase<TraceableVector<T,N,AP,GP>>
|
||||
: public TraceableVectorOperations<JS::Handle<TraceableVector<T,N,AP,GP>>, T,N,AP,GP>
|
||||
{};
|
||||
|
||||
template <typename T, size_t N, typename AP, typename TP>
|
||||
class PersistentRootedBase<TraceableVector<T,N,AP,TP>>
|
||||
: public MutableTraceableVectorOperations<JS::PersistentRooted<TraceableVector<T,N,AP,TP>>,
|
||||
T,N,AP,TP>
|
||||
template <typename T, size_t N, typename AP, typename GP>
|
||||
class PersistentRootedBase<TraceableVector<T,N,AP,GP>>
|
||||
: public MutableTraceableVectorOperations<JS::PersistentRooted<TraceableVector<T,N,AP,GP>>,
|
||||
T,N,AP,GP>
|
||||
{};
|
||||
|
||||
} // namespace js
|
||||
|
|
|
@ -369,31 +369,44 @@ JS_GetTraceThingInfo(char* buf, size_t bufsize, JSTracer* trc,
|
|||
|
||||
namespace js {
|
||||
|
||||
// Automates static dispatch for tracing for TraceableContainers.
|
||||
template <typename> struct DefaultTracer;
|
||||
// Automates static dispatch for GC interaction with TraceableContainers.
|
||||
template <typename>
|
||||
struct DefaultGCPolicy;
|
||||
|
||||
// The default for non-pod (e.g. struct) types is to call the trace method.
|
||||
// This policy dispatches GC methods to a method on the type.
|
||||
template <typename T>
|
||||
struct DefaultTracer {
|
||||
struct StructGCPolicy {
|
||||
static void trace(JSTracer* trc, T* t, const char* name) {
|
||||
// This is the default GC policy for storing GC things in containers.
|
||||
// If your build is failing here, it means you either need an
|
||||
// implementation of DefaultTracer<T> for your type or, for container
|
||||
// and structure types that contain GC pointers, a trace method.
|
||||
// implementation of DefaultGCPolicy<T> for your type or, if this is
|
||||
// the right policy for you, your struct or container is missing a
|
||||
// trace method.
|
||||
t->trace(trc);
|
||||
}
|
||||
};
|
||||
|
||||
// This policy ignores any GC interaction, e.g. for non-GC types.
|
||||
template <typename T>
|
||||
struct IgnoreGCPolicy {
|
||||
static void trace(JSTracer* trc, uint32_t* id, const char* name) {}
|
||||
};
|
||||
|
||||
// The default policy when no other more specific policy fits (e.g. for a
|
||||
// direct GC pointer), is to assume a struct type that implements the needed
|
||||
// methods.
|
||||
template <typename T>
|
||||
struct DefaultGCPolicy : public StructGCPolicy<T> {};
|
||||
|
||||
template <>
|
||||
struct DefaultTracer<jsid>
|
||||
struct DefaultGCPolicy<jsid>
|
||||
{
|
||||
static void trace(JSTracer* trc, jsid* id, const char* name) {
|
||||
JS_CallUnbarrieredIdTracer(trc, id, name);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct DefaultTracer<uint32_t> {
|
||||
static void trace(JSTracer* trc, uint32_t* id, const char* name) {}
|
||||
};
|
||||
template <> struct DefaultGCPolicy<uint32_t> : public IgnoreGCPolicy<uint32_t> {};
|
||||
|
||||
} // namespace js
|
||||
|
||||
|
|
|
@ -9,11 +9,10 @@
|
|||
|
||||
#include "ds/Fifo.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/TracingAPI.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
template <typename> struct DefaultTracer;
|
||||
|
||||
// A TraceableFifo is a Fifo with an additional trace method that knows how to
|
||||
// visit all of the items stored in the Fifo. For Fifos that contain GC things,
|
||||
// this is usually more convenient than manually iterating and marking the
|
||||
|
@ -21,8 +20,10 @@ template <typename> struct DefaultTracer;
|
|||
//
|
||||
// Most types of GC pointers as keys and values can be traced with no extra
|
||||
// infrastructure. For structs and non-gc-pointer members, ensure that there is
|
||||
// a specialization of DefaultTracer<T> with an appropriate trace method
|
||||
// available to handle the custom type.
|
||||
// a specialization of DefaultGCPolicy<T> with an appropriate trace method
|
||||
// available to handle the custom type. Generic helpers can be found in
|
||||
// js/public/TracingAPI.h. Generic helpers can be found in
|
||||
// js/public/TracingAPI.h.
|
||||
//
|
||||
// Note that although this Fifo's trace will deal correctly with moved items, it
|
||||
// does not itself know when to barrier or trace items. To function properly it
|
||||
|
@ -30,7 +31,7 @@ template <typename> struct DefaultTracer;
|
|||
template <typename T,
|
||||
size_t MinInlineCapacity = 0,
|
||||
typename AllocPolicy = TempAllocPolicy,
|
||||
typename TraceFunc = DefaultTracer<T>>
|
||||
typename GCPolicy = DefaultGCPolicy<T>>
|
||||
class TraceableFifo
|
||||
: public js::Fifo<T, MinInlineCapacity, AllocPolicy>,
|
||||
public JS::Traceable
|
||||
|
@ -48,16 +49,16 @@ class TraceableFifo
|
|||
|
||||
static void trace(TraceableFifo* tf, JSTracer* trc) {
|
||||
for (size_t i = 0; i < tf->front_.length(); ++i)
|
||||
TraceFunc::trace(trc, &tf->front_[i], "fifo element");
|
||||
GCPolicy::trace(trc, &tf->front_[i], "fifo element");
|
||||
for (size_t i = 0; i < tf->rear_.length(); ++i)
|
||||
TraceFunc::trace(trc, &tf->rear_[i], "fifo element");
|
||||
GCPolicy::trace(trc, &tf->rear_[i], "fifo element");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy, typename TraceFunc>
|
||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy, typename GCPolicy>
|
||||
class TraceableFifoOperations
|
||||
{
|
||||
using TF = TraceableFifo<T, Capacity, AllocPolicy, TraceFunc>;
|
||||
using TF = TraceableFifo<T, Capacity, AllocPolicy, GCPolicy>;
|
||||
const TF& fifo() const { return static_cast<const Outer*>(this)->extract(); }
|
||||
|
||||
public:
|
||||
|
@ -66,11 +67,11 @@ class TraceableFifoOperations
|
|||
const T& front() const { return fifo().front(); }
|
||||
};
|
||||
|
||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy, typename TraceFunc>
|
||||
template <typename Outer, typename T, size_t Capacity, typename AllocPolicy, typename GCPolicy>
|
||||
class MutableTraceableFifoOperations
|
||||
: public TraceableFifoOperations<Outer, T, Capacity, AllocPolicy, TraceFunc>
|
||||
: public TraceableFifoOperations<Outer, T, Capacity, AllocPolicy, GCPolicy>
|
||||
{
|
||||
using TF = TraceableFifo<T, Capacity, AllocPolicy, TraceFunc>;
|
||||
using TF = TraceableFifo<T, Capacity, AllocPolicy, GCPolicy>;
|
||||
TF& fifo() { return static_cast<Outer*>(this)->extract(); }
|
||||
|
||||
public:
|
||||
|
|
|
@ -138,16 +138,22 @@ TraceCycleCollectorChildren(JS::CallbackTracer* trc, ObjectGroup* group);
|
|||
|
||||
} // namespace gc
|
||||
|
||||
// Define a default Policy for all pointer types. This may fail to link if this
|
||||
// policy gets used on a non-GC typed pointer by accident.
|
||||
template <typename T>
|
||||
struct DefaultTracer<T*>
|
||||
struct DefaultGCPolicy<T*>
|
||||
{
|
||||
static void trace(JSTracer* trc, T** t, const char* name) {
|
||||
// If linking is failing here, it likely means that you need to define
|
||||
// or use a non-default GC policy for your non-gc-pointer type.
|
||||
TraceManuallyBarrieredEdge(trc, t, name);
|
||||
}
|
||||
};
|
||||
|
||||
// RelocatablePtr is only defined for GC pointer types, so this default policy
|
||||
// should work in all cases.
|
||||
template <typename T>
|
||||
struct DefaultTracer<RelocatablePtr<T*>>
|
||||
struct DefaultGCPolicy<RelocatablePtr<T*>>
|
||||
{
|
||||
static void trace(JSTracer* trc, RelocatablePtr<T*> t, const char* name) {
|
||||
TraceEdge(trc, t, name);
|
||||
|
|
|
@ -943,14 +943,14 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
|||
};
|
||||
|
||||
template<>
|
||||
struct DefaultTracer<Debugger::TenurePromotionsLogEntry> {
|
||||
struct DefaultGCPolicy<Debugger::TenurePromotionsLogEntry> {
|
||||
static void trace(JSTracer* trc, Debugger::TenurePromotionsLogEntry* e, const char*) {
|
||||
Debugger::TenurePromotionsLogEntry::trace(e, trc);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct DefaultTracer<Debugger::AllocationsLogEntry> {
|
||||
struct DefaultGCPolicy<Debugger::AllocationsLogEntry> {
|
||||
static void trace(JSTracer* trc, Debugger::AllocationsLogEntry* e, const char*) {
|
||||
Debugger::AllocationsLogEntry::trace(e, trc);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче