Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit d8fe7c9

Browse files
committed
Bug 1735296 - Part 5: Add a result value for TraceWeakEdge that encapsulates all relevant information r=sfink
This is intended to be a simple as possible so that compilers can optimise away the bits that aren't used after inlining. The result value includes the edge state before and after update and there are runtime checks that you only use the right one, depending on whether the edge was removed or not. The signature of TraceWeakEdge changes to allow any barriered type because in practice we have weak edges that are no WeakHeapPtr in cases where we don't want the read barrier (e.g. WeakMap keys). Differential Revision: https://phabricator.services.mozilla.com/D128261
1 parent bb75502 commit d8fe7c9

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

js/src/gc/Tracer.h

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -224,15 +224,43 @@ inline bool TraceManuallyBarrieredWeakEdge(JSTracer* trc, T* thingp,
224224
return gc::TraceEdgeInternal(trc, gc::ConvertToBase(thingp), name);
225225
}
226226

227+
// The result of tracing a weak edge, which can be either:
228+
//
229+
// - the target is dead (and the edge has been cleared), or
230+
// - the target is alive (and the edge may have been updated)
231+
//
232+
// This includes the initial and final values of the edge to allow cleanup if
233+
// the target is dead or access to the referent if it is alive.
227234
template <typename T>
228-
inline bool TraceWeakEdge(JSTracer* trc, WeakHeapPtr<T>* thingp,
229-
const char* name) {
230-
if (!InternalBarrierMethods<T>::isMarkable(thingp->unbarrieredGet())) {
231-
return true;
235+
struct TraceWeakResult {
236+
const bool live_;
237+
const T initial_;
238+
const T final_;
239+
240+
bool isLive() const { return live_; }
241+
bool isDead() const { return !live_; }
242+
243+
MOZ_IMPLICIT operator bool() const { return isLive(); }
244+
245+
T initialTarget() const {
246+
MOZ_ASSERT(isDead());
247+
return initial_;
232248
}
233249

234-
return gc::TraceEdgeInternal(
235-
trc, gc::ConvertToBase(thingp->unbarrieredAddress()), name);
250+
T finalTarget() const {
251+
MOZ_ASSERT(isLive());
252+
return final_;
253+
}
254+
};
255+
256+
template <typename T>
257+
inline TraceWeakResult<T> TraceWeakEdge(JSTracer* trc, BarrieredBase<T>* thingp,
258+
const char* name) {
259+
T* addr = thingp->unbarrieredAddress();
260+
T initial = *addr;
261+
bool live = !InternalBarrierMethods<T>::isMarkable(initial) ||
262+
gc::TraceEdgeInternal(trc, gc::ConvertToBase(addr), name);
263+
return TraceWeakResult<T>{live, initial, *addr};
236264
}
237265

238266
// Trace all edges contained in the given array.

0 commit comments

Comments
 (0)