Bug 1736604 - Part 2: Remove GCPolicy and container needsSweep and sweep methods r=sfink

This functionality has been replaced by the traceWeak methods.

Differential Revision: https://phabricator.services.mozilla.com/D128902
This commit is contained in:
Jon Coppeard 2021-11-09 09:17:34 +00:00
parent 2a5497d4ff
commit 4514fe83d3
6 changed files with 16 additions and 113 deletions

View File

@ -22,41 +22,37 @@ namespace JS {
// Define a reasonable default GC policy for GC-aware Maps.
template <typename Key, typename Value>
struct DefaultMapSweepPolicy {
static bool needsSweep(Key* key, Value* value) {
return GCPolicy<Key>::needsSweep(key) || GCPolicy<Value>::needsSweep(value);
}
static bool traceWeak(JSTracer* trc, Key* key, Value* value) {
return GCPolicy<Key>::traceWeak(trc, key) &&
GCPolicy<Value>::traceWeak(trc, value);
}
};
// A GCHashMap is a GC-aware HashMap, meaning that it has additional trace and
// sweep methods that know how to visit all keys and values in the table.
// HashMaps that contain GC pointers will generally want to use this GCHashMap
// A GCHashMap is a GC-aware HashMap, meaning that it has additional trace
// methods that know how to visit all keys and values in the table. HashMaps
// that contain GC pointers will generally want to use this GCHashMap
// specialization instead of HashMap, because this conveniently supports tracing
// keys and values, and cleaning up weak entries.
//
// GCHashMap::trace applies GCPolicy<T>::trace to each entry's key and value.
// Most types of GC pointers already have appropriate specializations of
// GCPolicy, so they should just work as keys and values. Any struct type with a
// default constructor and trace and sweep functions should work as well. If you
// need to define your own GCPolicy specialization, generic helpers can be found
// in js/public/TracingAPI.h.
// default constructor and trace function should work as well. If you need to
// define your own GCPolicy specialization, generic helpers can be found in
// js/public/TracingAPI.h.
//
// The MapSweepPolicy template parameter controls how the table drops entries
// when swept. GCHashMap::sweep applies MapSweepPolicy::needsSweep to each table
// entry; if it returns true, the entry is dropped. The default MapSweepPolicy
// drops the entry if either the key or value is about to be finalized,
// according to its GCPolicy<T>::needsSweep method. (This default is almost
// always fine: it's hard to imagine keeping such an entry around anyway.)
// when edges are weakly held. GCHashMap::traceWeak applies the MapSweepPolicy's
// traceWeak method to each table entry; if it returns true, the entry is
// dropped. The default MapSweepPolicy drops the entry if either the key or
// value is about to be finalized, according to its GCPolicy<T>::traceWeak
// method. (This default is almost always fine: it's hard to imagine keeping
// such an entry around anyway.)
//
// Note that this HashMap only knows *how* to trace and sweep, but it does not
// itself cause tracing or sweeping to be invoked. For tracing, it must be used
// as Rooted<GCHashMap> or PersistentRooted<GCHashMap>, or barriered and traced
// manually. For sweeping, currently it requires an explicit call to
// <map>.sweep().
// Note that this HashMap only knows *how* to trace, but it does not itself
// cause tracing to be invoked. For tracing, it must be used as
// Rooted<GCHashMap> or PersistentRooted<GCHashMap>, or barriered and traced
// manually.
template <typename Key, typename Value,
typename HashPolicy = js::DefaultHasher<Key>,
typename AllocPolicy = js::TempAllocPolicy,
@ -78,15 +74,6 @@ class GCHashMap : public js::HashMap<Key, Value, HashPolicy, AllocPolicy> {
}
}
void sweep() {
for (typename Base::Enum e(*this); !e.empty(); e.popFront()) {
if (MapSweepPolicy::needsSweep(&e.front().mutableKey(),
&e.front().value())) {
e.removeFront();
}
}
}
bool traceWeak(JSTracer* trc) {
typename Base::Enum e(*this);
traceWeakEntries(trc, e);
@ -139,17 +126,6 @@ class GCRekeyableHashMap : public JS::GCHashMap<Key, Value, HashPolicy,
GCRekeyableHashMap(AllocPolicy a, size_t length)
: Base(std::move(a), length) {}
void sweep() {
for (typename Base::Enum e(*this); !e.empty(); e.popFront()) {
Key key(e.front().key());
if (MapSweepPolicy::needsSweep(&key, &e.front().value())) {
e.removeFront();
} else if (!HashPolicy::match(key, e.front().key())) {
e.rekeyFront(key);
}
}
}
bool traceWeak(JSTracer* trc) {
for (typename Base::Enum e(*this); !e.empty(); e.popFront()) {
Key key(e.front().key());

View File

@ -17,15 +17,6 @@
// - Trace the edge |*tp|, calling the edge |name|. Containers like
// GCHashMap and GCHashSet use this method to trace their children.
//
// static bool needsSweep(T* tp)
// - [DEPRECATED], use traceWeak instead.
// Return true if |*tp| is about to be finalized. Otherwise, update the
// edge for moving GC, and return false. Containers like GCHashMap and
// GCHashSet use this method to decide when to remove an entry: if this
// function returns true on a key/value/member/etc, its entry is dropped
// from the container. Specializing this method is the standard way to
// get custom weak behavior from a container type.
//
// static bool traceWeak(T* tp)
// - Return false if |*tp| has been set to nullptr. Otherwise, update the
// edge for moving GC, and return true. Containers like GCHashMap and
@ -74,8 +65,6 @@ struct StructGCPolicy {
static void sweep(T* tp) { return tp->sweep(); }
static bool needsSweep(T* tp) { return tp->needsSweep(); }
static bool traceWeak(JSTracer* trc, T* tp) { return tp->traceWeak(trc); }
static bool isValid(const T& tp) { return true; }
@ -92,7 +81,6 @@ struct GCPolicy : public StructGCPolicy<T> {};
template <typename T>
struct IgnoreGCPolicy {
static void trace(JSTracer* trc, T* t, const char* name) {}
static bool needsSweep(T* v) { return false; }
static bool traceWeak(JSTracer*, T* v) { return true; }
static bool isValid(const T& v) { return true; }
};
@ -129,12 +117,6 @@ struct NonGCPointerPolicy {
(*vp)->trace(trc);
}
}
static bool needsSweep(T* vp) {
if (*vp) {
return (*vp)->needsSweep();
}
return false;
}
static bool traceWeak(JSTracer* trc, T* vp) {
if (*vp) {
return (*vp)->traceWeak(trc);
@ -164,12 +146,6 @@ struct GCPolicy<mozilla::UniquePtr<T, D>> {
GCPolicy<T>::trace(trc, tp->get(), name);
}
}
static bool needsSweep(mozilla::UniquePtr<T, D>* tp) {
if (tp->get()) {
return GCPolicy<T>::needsSweep(tp->get());
}
return false;
}
static bool traceWeak(JSTracer* trc, mozilla::UniquePtr<T, D>* tp) {
if (tp->get()) {
return GCPolicy<T>::traceWeak(trc, tp->get());
@ -196,12 +172,6 @@ struct GCPolicy<mozilla::Maybe<T>> {
GCPolicy<T>::trace(trc, tp->ptr(), name);
}
}
static bool needsSweep(mozilla::Maybe<T>* tp) {
if (tp->isSome()) {
return GCPolicy<T>::needsSweep(tp->ptr());
}
return false;
}
static bool traceWeak(JSTracer* trc, mozilla::Maybe<T>* tp) {
if (tp->isSome()) {
return GCPolicy<T>::traceWeak(trc, tp->ptr());

View File

@ -181,28 +181,6 @@ class GCVector {
shrinkBy(end() - dst);
return !empty();
}
bool needsSweep() {
sweep();
return this->empty();
}
void sweep() {
T* src = begin();
T* dst = begin();
while (src != end()) {
if (!GCPolicy<T>::needsSweep(src)) {
if (src != dst) {
*dst = std::move(*src);
}
dst++;
}
src++;
}
MOZ_ASSERT(dst <= end());
shrinkBy(end() - dst);
}
};
// AllocPolicy is optional. It has a default value declared in TypeDecls.h

View File

@ -200,9 +200,6 @@ struct GCPolicy<js::detail::UnsafeBareWeakHeapPtr<T>> {
js::detail::UnsafeBareWeakHeapPtr<T>* thingp) {
return js::TraceWeakEdge(trc, thingp, "UnsafeBareWeakHeapPtr");
}
static bool needsSweep(js::detail::UnsafeBareWeakHeapPtr<T>* thingp) {
return js::gc::IsAboutToBeFinalized(thingp);
}
};
} // namespace JS

View File

@ -55,10 +55,6 @@ struct GCPolicy<js::HeapPtr<T>> {
static bool traceWeak(JSTracer* trc, js::HeapPtr<T>* thingp) {
return js::TraceWeakEdge(trc, thingp, "HeapPtr");
}
static bool needsSweep(js::HeapPtr<T>* thingp) {
return js::InternalBarrierMethods<T>::isMarkable(thingp->get()) &&
js::gc::IsAboutToBeFinalized(thingp);
}
};
template <typename T>
@ -67,9 +63,6 @@ struct GCPolicy<js::PreBarriered<T>> {
const char* name) {
js::TraceNullableEdge(trc, thingp, name);
}
static bool needsSweep(js::PreBarriered<T>* thingp) {
return js::gc::IsAboutToBeFinalized(thingp);
}
};
template <typename T>
@ -78,9 +71,6 @@ struct GCPolicy<js::WeakHeapPtr<T>> {
const char* name) {
js::TraceEdge(trc, thingp, name);
}
static bool needsSweep(js::WeakHeapPtr<T>* thingp) {
return js::gc::IsAboutToBeFinalized(thingp);
}
static bool traceWeak(JSTracer* trc, js::WeakHeapPtr<T>* thingp) {
return js::TraceWeakEdge(trc, thingp, "traceWeak");
}
@ -88,12 +78,6 @@ struct GCPolicy<js::WeakHeapPtr<T>> {
template <typename T>
struct GCPolicy<js::UnsafeBarePtr<T>> {
static bool needsSweep(js::UnsafeBarePtr<T>* vp) {
if (*vp) {
return js::gc::IsAboutToBeFinalizedUnbarriered(vp->unbarrieredAddress());
}
return false;
}
static bool traceWeak(JSTracer* trc, js::UnsafeBarePtr<T>* vp) {
if (*vp) {
return js::TraceManuallyBarrieredWeakEdge(trc, vp->unbarrieredAddress(),

View File

@ -136,7 +136,6 @@ struct ObjectEntry {
HeapPtr<JSObject*> obj;
explicit ObjectEntry(JSObject* o) : obj(o) {}
bool operator==(const ObjectEntry& other) const { return obj == other.obj; }
bool needsSweep() { return IsAboutToBeFinalized(&obj); }
bool traceWeak(JSTracer* trc) {
return TraceWeakEdge(trc, &obj, "ObjectEntry::obj");
}
@ -174,7 +173,6 @@ struct NumberAndObjectEntry {
bool operator==(const NumberAndObjectEntry& other) const {
return number == other.number && obj == other.obj;
}
bool needsSweep() { return IsAboutToBeFinalized(&obj); }
bool traceWeak(JSTracer* trc) {
return TraceWeakEdge(trc, &obj, "NumberAndObjectEntry::obj");
}