Bug 1288944 - Baldr: change how wasm::Instance is traced (r=terrence)
authorLuke Wagner <luke@mozilla.com>
Fri, 05 Aug 2016 15:39:56 -0500
changeset 397526 d97a1da36f40b8126fd8c4ef622bcbee38383b5c
parent 397525 214d6ce2943a0b4e5067a9e37986b47a8104859b
child 397527 5f028ac66f96fe761149751a32304e72f28880cf
push id25332
push usermaglione.k@gmail.com
push dateSat, 06 Aug 2016 21:21:51 +0000
reviewersterrence
bugs1288944
milestone51.0a1
Bug 1288944 - Baldr: change how wasm::Instance is traced (r=terrence) MozReview-Commit-ID: 2re3vhJ7MIG
js/src/asmjs/WasmInstance.cpp
js/src/asmjs/WasmInstance.h
js/src/asmjs/WasmJS.cpp
--- a/js/src/asmjs/WasmInstance.cpp
+++ b/js/src/asmjs/WasmInstance.cpp
@@ -390,31 +390,42 @@ Instance::~Instance()
         for (const SigWithId& sig : metadata().sigIds) {
             if (const void* sigId = *addressOfSigId(sig.id))
                 lockedSigIdSet->deallocateSigId(sig, sigId);
         }
     }
 }
 
 void
-Instance::trace(JSTracer* trc)
+Instance::tracePrivate(JSTracer* trc)
 {
-    // Ordinarily, an Instance is only marked via WasmInstanceObject's trace
-    // hook and so this TraceEdge() call is only useful to update the pointer on
-    // moving GC. However, if wasm is active in a wasm::Compartment during GC,
-    // all Instances are marked directly via Instance::trace() making this a
-    // necessary strong edge.
-    TraceEdge(trc, &object_, "wasm object");
+    // This method is only called from WasmInstanceObject so the only reason why
+    // TraceEdge is called is so that the pointer can be updated during a moving
+    // GC. TraceWeakEdge may sound better, but it is less efficient given that
+    // we know object_ is already marked.
+    MOZ_ASSERT(!IsAboutToBeFinalized(&object_));
+    TraceEdge(trc, &object_, "wasm instance object");
 
     for (const FuncImport& fi : metadata().funcImports)
         TraceNullableEdge(trc, &funcImportTls(fi).obj, "wasm import");
 
     TraceNullableEdge(trc, &memory_, "wasm buffer");
 }
 
+void
+Instance::trace(JSTracer* trc)
+{
+    // Technically, instead of having this method, the caller could use
+    // Instance::object() to get the owning WasmInstanceObject to mark,
+    // but this method is simpler and more efficient. The trace hook of
+    // WasmInstanceObject will call Instance::tracePrivate at which point we
+    // can mark the rest of the children.
+    TraceEdge(trc, &object_, "wasm instance object");
+}
+
 SharedMem<uint8_t*>
 Instance::memoryBase() const
 {
     MOZ_ASSERT(metadata().usesMemory());
     MOZ_ASSERT(tlsData_.memoryBase == memory_->buffer().dataPointerEither());
     return memory_->buffer().dataPointerEither();
 }
 
--- a/js/src/asmjs/WasmInstance.h
+++ b/js/src/asmjs/WasmInstance.h
@@ -59,16 +59,20 @@ class Instance
     static int32_t callImport_void(Instance*, int32_t, int32_t, uint64_t*);
     static int32_t callImport_i32(Instance*, int32_t, int32_t, uint64_t*);
     static int32_t callImport_i64(Instance*, int32_t, int32_t, uint64_t*);
     static int32_t callImport_f64(Instance*, int32_t, int32_t, uint64_t*);
 
     bool callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, const uint64_t* argv,
                     MutableHandleValue rval);
 
+    // Only WasmInstanceObject can call the private trace function.
+    friend class js::WasmInstanceObject;
+    void tracePrivate(JSTracer* trc);
+
   public:
     Instance(JSContext* cx,
              HandleWasmInstanceObject object,
              UniqueCode code,
              HandleWasmMemoryObject memory,
              SharedTableVector&& tables,
              Handle<FunctionVector> funcImports,
              const ValVector& globalImports);
--- a/js/src/asmjs/WasmJS.cpp
+++ b/js/src/asmjs/WasmJS.cpp
@@ -510,17 +510,17 @@ WasmInstanceObject::finalize(FreeOp* fop
     if (!obj->as<WasmInstanceObject>().isNewborn())
         fop->delete_(&obj->as<WasmInstanceObject>().instance());
 }
 
 /* static */ void
 WasmInstanceObject::trace(JSTracer* trc, JSObject* obj)
 {
     if (!obj->as<WasmInstanceObject>().isNewborn())
-        obj->as<WasmInstanceObject>().instance().trace(trc);
+        obj->as<WasmInstanceObject>().instance().tracePrivate(trc);
 }
 
 /* static */ WasmInstanceObject*
 WasmInstanceObject::create(JSContext* cx,
                            UniqueCode code,
                            HandleWasmMemoryObject memory,
                            SharedTableVector&& tables,
                            Handle<FunctionVector> funcImports,