Bug 1592155: Make TraceCrossCompartmentEdge handle JSObject subclasses. r=jonco
authorJim Blandy <jimb@mozilla.com>
Thu, 21 Nov 2019 18:37:08 +0000
changeset 503194 59c3668969ef41ce4a6f1de58b6071207e104b0e
parent 503193 a8082b9b4ed10796852c719d9a965445f19b53ee
child 503195 9f5acf34610fefe7f9d1065ae263dcff3b7595b6
push id36829
push userccoroiu@mozilla.com
push dateFri, 22 Nov 2019 04:19:28 +0000
treeherdermozilla-central@adf7d49a44f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1592155
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1592155: Make TraceCrossCompartmentEdge handle JSObject subclasses. r=jonco Give TraceCrossCompartmentEdge an inline definition in Tracer.h that uses gc::ConvertToBase and unsafeUnbarrieredForTracing (already in use by other definitions in that file) to bring things to the point that TraceManuallyBarrieredCrossCompartmentEdge can finish the job. This gives us a definition that handles WriteBarriered<T> for pointers to subclasses of JSObject, so we can use tighter types in data structures. Remove the non-inline definition and explicit template instantiations in Marking.cpp. Differential Revision: https://phabricator.services.mozilla.com/D54075
js/src/gc/Marking.cpp
js/src/gc/Tracer.h
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -490,40 +490,26 @@ FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(I
 template <typename T>
 void js::TraceManuallyBarrieredCrossCompartmentEdge(JSTracer* trc,
                                                     JSObject* src, T* dst,
                                                     const char* name) {
   if (ShouldTraceCrossCompartment(trc, src, *dst)) {
     TraceEdgeInternal(trc, dst, name);
   }
 }
+template void js::TraceManuallyBarrieredCrossCompartmentEdge<Value>(
+    JSTracer*, JSObject*, Value*, const char*);
 template void js::TraceManuallyBarrieredCrossCompartmentEdge<JSObject*>(
     JSTracer*, JSObject*, JSObject**, const char*);
 template void js::TraceManuallyBarrieredCrossCompartmentEdge<JSScript*>(
     JSTracer*, JSObject*, JSScript**, const char*);
 template void js::TraceManuallyBarrieredCrossCompartmentEdge<LazyScript*>(
     JSTracer*, JSObject*, LazyScript**, const char*);
 
 template <typename T>
-void js::TraceCrossCompartmentEdge(JSTracer* trc, JSObject* src,
-                                   const WriteBarriered<T>* dst,
-                                   const char* name) {
-  if (ShouldTraceCrossCompartment(trc, src, dst->get())) {
-    TraceEdgeInternal(trc, dst->unsafeUnbarrieredForTracing(), name);
-  }
-}
-
-template void js::TraceCrossCompartmentEdge<Value>(
-    JSTracer* trc, JSObject* src, const WriteBarriered<Value>* dst,
-    const char* name);
-template void js::TraceCrossCompartmentEdge<JSScript*>(
-    JSTracer* trc, JSObject* src, const WriteBarriered<JSScript*>* dst,
-    const char* name);
-
-template <typename T>
 void js::TraceProcessGlobalRoot(JSTracer* trc, T* thing, const char* name) {
   AssertRootMarkingPhase(trc);
   MOZ_ASSERT(ThingIsPermanentAtomOrWellKnownSymbol(thing));
 
   // We have to mark permanent atoms and well-known symbols through a special
   // method because the default DoMarking implementation automatically skips
   // them. Fortunately, atoms (permanent and non) cannot refer to other GC
   // things so they do not need to go through the mark stack and may simply
--- a/js/src/gc/Tracer.h
+++ b/js/src/gc/Tracer.h
@@ -219,26 +219,29 @@ void TraceRange(JSTracer* trc, size_t le
 // Trace all root edges in the given array.
 
 template <typename T>
 void TraceRootRange(JSTracer* trc, size_t len, T* vec, const char* name) {
   gc::AssertRootMarkingPhase(trc);
   gc::TraceRangeInternal(trc, len, gc::ConvertToBase(vec), name);
 }
 
+// As below but with manual barriers.
+template <typename T>
+void TraceManuallyBarrieredCrossCompartmentEdge(JSTracer* trc, JSObject* src,
+                                                T* dst, const char* name);
+
 // Trace an edge that crosses compartment boundaries. If the compartment of the
 // destination thing is not being GC'd, then the edge will not be traced.
 template <typename T>
 void TraceCrossCompartmentEdge(JSTracer* trc, JSObject* src,
-                               const WriteBarriered<T>* dst, const char* name);
-
-// As above but with manual barriers.
-template <typename T>
-void TraceManuallyBarrieredCrossCompartmentEdge(JSTracer* trc, JSObject* src,
-                                                T* dst, const char* name);
+                               const WriteBarriered<T>* dst, const char* name) {
+  TraceManuallyBarrieredCrossCompartmentEdge(
+      trc, src, gc::ConvertToBase(dst->unsafeUnbarrieredForTracing()), name);
+}
 
 // Permanent atoms and well-known symbols are shared between runtimes and must
 // use a separate marking path so that we can filter them out of normal heap
 // tracing.
 template <typename T>
 void TraceProcessGlobalRoot(JSTracer* trc, T* thing, const char* name);
 
 // Trace a root edge that uses the base GC thing type, instead of a more