mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1226687
- Part 1: Export a GCPolicy usable by JS::Heap; r=fitzgen
--HG-- extra : rebase_source : 7ac38143297ef92265faefe6ce800b6c55dcaa64
This commit is contained in:
parent
64b9c0ed0b
commit
2f587b2fc3
@ -586,7 +586,7 @@ struct JS_PUBLIC_API(MovableCellHasher)
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct MovableCellHasher<JS::Heap<T>>
|
||||
struct JS_PUBLIC_API(MovableCellHasher<JS::Heap<T>>)
|
||||
{
|
||||
using Key = JS::Heap<T>;
|
||||
using Lookup = T;
|
||||
|
@ -311,6 +311,12 @@ JS_CallScriptTracer(JSTracer* trc, JS::Heap<JSScript*>* scriptp, const char* nam
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_CallFunctionTracer(JSTracer* trc, JS::Heap<JSFunction*>* funp, const char* name);
|
||||
|
||||
namespace JS {
|
||||
template <typename T>
|
||||
extern JS_PUBLIC_API(void)
|
||||
TraceEdge(JSTracer* trc, JS::Heap<T>* edgep, const char* name);
|
||||
} // namespace JS
|
||||
|
||||
// The following JS_CallUnbarriered*Tracer functions should only be called where
|
||||
// you know for sure that a heap post barrier is not required. Use with extreme
|
||||
// caution!
|
||||
@ -358,6 +364,11 @@ JS_GetTraceThingInfo(char* buf, size_t bufsize, JSTracer* trc,
|
||||
void* thing, JS::TraceKind kind, bool includeDetails);
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
template <typename T>
|
||||
extern JS_PUBLIC_API(bool)
|
||||
EdgeNeedsSweep(JS::Heap<T>* edgep);
|
||||
} // namespace gc
|
||||
|
||||
// Automates static dispatch for GC interaction with TraceableContainers.
|
||||
template <typename>
|
||||
@ -403,6 +414,17 @@ struct DefaultGCPolicy<jsid>
|
||||
|
||||
template <> struct DefaultGCPolicy<uint32_t> : public IgnoreGCPolicy<uint32_t> {};
|
||||
|
||||
template <typename T>
|
||||
struct DefaultGCPolicy<JS::Heap<T>>
|
||||
{
|
||||
static void trace(JSTracer* trc, JS::Heap<T>* thingp, const char* name) {
|
||||
JS::TraceEdge(trc, thingp, name);
|
||||
}
|
||||
static bool needsSweep(JS::Heap<T>* thingp) {
|
||||
return gc::EdgeNeedsSweep(thingp);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif /* js_TracingAPI_h */
|
||||
|
@ -398,6 +398,13 @@ js::TraceEdge(JSTracer* trc, WriteBarrieredBase<T>* thingp, const char* name)
|
||||
DispatchToTracer(trc, ConvertToBase(thingp->unsafeUnbarrieredForTracing()), name);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
JS_PUBLIC_API(void)
|
||||
JS::TraceEdge(JSTracer* trc, JS::Heap<T>* thingp, const char* name)
|
||||
{
|
||||
DispatchToTracer(trc, ConvertToBase(thingp->unsafeGet()), name);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
js::TraceManuallyBarrieredEdge(JSTracer* trc, T* thingp, const char* name)
|
||||
@ -462,6 +469,7 @@ js::TraceRootRange(JSTracer* trc, size_t len, T* vec, const char* name)
|
||||
// Instantiate a copy of the Tracing templates for each derived type.
|
||||
#define INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS(type) \
|
||||
template void js::TraceEdge<type>(JSTracer*, WriteBarrieredBase<type>*, const char*); \
|
||||
template JS_PUBLIC_API(void) JS::TraceEdge<type>(JSTracer*, JS::Heap<type>*, const char*); \
|
||||
template void js::TraceManuallyBarrieredEdge<type>(JSTracer*, type*, const char*); \
|
||||
template void js::TraceWeakEdge<type>(JSTracer*, WeakRef<type>*, const char*); \
|
||||
template void js::TraceRoot<type>(JSTracer*, type*, const char*); \
|
||||
@ -2436,13 +2444,21 @@ IsAboutToBeFinalized(ReadBarrieredBase<T>* thingp)
|
||||
return IsAboutToBeFinalizedInternal(ConvertToBase(thingp->unsafeUnbarrieredForTracing()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
JS_PUBLIC_API(bool)
|
||||
EdgeNeedsSweep(JS::Heap<T>* thingp)
|
||||
{
|
||||
return IsAboutToBeFinalizedInternal(ConvertToBase(thingp->unsafeGet()));
|
||||
}
|
||||
|
||||
// Instantiate a copy of the Tracing templates for each derived type.
|
||||
#define INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS(type) \
|
||||
template bool IsMarkedUnbarriered<type>(type*); \
|
||||
template bool IsMarked<type>(WriteBarrieredBase<type>*); \
|
||||
template bool IsAboutToBeFinalizedUnbarriered<type>(type*); \
|
||||
template bool IsAboutToBeFinalized<type>(WriteBarrieredBase<type>*); \
|
||||
template bool IsAboutToBeFinalized<type>(ReadBarrieredBase<type>*);
|
||||
template bool IsAboutToBeFinalized<type>(ReadBarrieredBase<type>*); \
|
||||
template JS_PUBLIC_API(bool) EdgeNeedsSweep<type>(JS::Heap<type>*);
|
||||
FOR_EACH_GC_POINTER_TYPE(INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS)
|
||||
#undef INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS
|
||||
|
||||
|
@ -463,30 +463,33 @@ void
|
||||
CheckTracedThing(JSTracer* trc, T thing);
|
||||
|
||||
// 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.
|
||||
// policy gets used on a non-GC typed pointer by accident. There is a separate
|
||||
// default policy for Value and jsid.
|
||||
template <typename T>
|
||||
struct DefaultGCPolicy<T*>
|
||||
{
|
||||
static void trace(JSTracer* trc, T** t, const char* name) {
|
||||
static void trace(JSTracer* trc, T** thingp, 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);
|
||||
TraceManuallyBarrieredEdge(trc, thingp, name);
|
||||
}
|
||||
|
||||
static bool needsSweep(T** t) {
|
||||
return gc::IsAboutToBeFinalizedUnbarriered(t);
|
||||
static bool needsSweep(T** thingp) {
|
||||
// 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.
|
||||
return gc::IsAboutToBeFinalizedUnbarriered(thingp);
|
||||
}
|
||||
};
|
||||
|
||||
// RelocatablePtr is only defined for GC pointer types, so this default policy
|
||||
// should work in all cases.
|
||||
template <typename T>
|
||||
struct DefaultGCPolicy<RelocatablePtr<T*>>
|
||||
struct DefaultGCPolicy<RelocatablePtr<T>>
|
||||
{
|
||||
static void trace(JSTracer* trc, RelocatablePtr<T*> t, const char* name) {
|
||||
TraceEdge(trc, t, name);
|
||||
static void trace(JSTracer* trc, RelocatablePtr<T>* thingp, const char* name) {
|
||||
TraceEdge(trc, thingp, name);
|
||||
}
|
||||
static bool needsSweep(RelocatablePtr<T*>* thingp) {
|
||||
static bool needsSweep(RelocatablePtr<T>* thingp) {
|
||||
return gc::IsAboutToBeFinalizedUnbarriered(thingp);
|
||||
}
|
||||
};
|
||||
@ -494,8 +497,8 @@ struct DefaultGCPolicy<RelocatablePtr<T*>>
|
||||
template <typename T>
|
||||
struct DefaultGCPolicy<ReadBarriered<T>>
|
||||
{
|
||||
static void trace(JSTracer* trc, ReadBarriered<T> t, const char* name) {
|
||||
TraceEdge(trc, t, name);
|
||||
static void trace(JSTracer* trc, ReadBarriered<T>* thingp, const char* name) {
|
||||
TraceEdge(trc, thingp, name);
|
||||
}
|
||||
static bool needsSweep(ReadBarriered<T>* thingp) {
|
||||
return gc::IsAboutToBeFinalized(thingp);
|
||||
|
Loading…
Reference in New Issue
Block a user