Bug 1119753 - Fix CPOW GC crash. r=jonco, a=sledru
authorBill McCloskey <wmccloskey@mozilla.com>
Fri, 16 Jan 2015 09:56:30 -0800
changeset 249373 c0f368aff73869659019b19a48cdf2fdd28b92d8
parent 249372 62321380a4c3c14fa507814cb397e18520764efa
child 249374 0fe217418754b6aeef7d4d3fd733ee4088ae60ea
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco, sledru
bugs1119753
milestone37.0a2
Bug 1119753 - Fix CPOW GC crash. r=jonco, a=sledru
js/ipc/JavaScriptParent.cpp
js/ipc/JavaScriptShared.cpp
js/ipc/JavaScriptShared.h
js/ipc/WrapperOwner.cpp
--- a/js/ipc/JavaScriptParent.cpp
+++ b/js/ipc/JavaScriptParent.cpp
@@ -46,21 +46,19 @@ JavaScriptParent::init()
 
     JS_AddExtraGCRootsTracer(rt_, TraceParent, this);
     return true;
 }
 
 void
 JavaScriptParent::trace(JSTracer *trc)
 {
-    if (active()) {
-        objects_.trace(trc);
-        unwaivedObjectIds_.trace(trc);
-        waivedObjectIds_.trace(trc);
-    }
+    objects_.trace(trc);
+    unwaivedObjectIds_.trace(trc);
+    waivedObjectIds_.trace(trc);
 }
 
 JSObject *
 JavaScriptParent::scopeForTargetObjects()
 {
     // CPWOWs from the child need to point into the parent's unprivileged junk
     // scope so that a compromised child cannot compromise the parent. In
     // practice, this means that a child process can only (a) hold parent
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -68,16 +68,28 @@ IdToObjectMap::add(ObjectId id, JSObject
 }
 
 void
 IdToObjectMap::remove(ObjectId id)
 {
     table_.remove(id);
 }
 
+void
+IdToObjectMap::clear()
+{
+    table_.clear();
+}
+
+bool
+IdToObjectMap::empty() const
+{
+    return table_.empty();
+}
+
 ObjectToIdMap::ObjectToIdMap()
   : table_(nullptr)
 {
 }
 
 ObjectToIdMap::~ObjectToIdMap()
 {
     if (table_) {
@@ -152,16 +164,22 @@ ObjectToIdMap::keyMarkCallback(JSTracer 
 }
 
 void
 ObjectToIdMap::remove(JSObject *obj)
 {
     table_->remove(obj);
 }
 
+void
+ObjectToIdMap::clear()
+{
+    table_->clear();
+}
+
 bool JavaScriptShared::sLoggingInitialized;
 bool JavaScriptShared::sLoggingEnabled;
 bool JavaScriptShared::sStackLoggingEnabled;
 
 JavaScriptShared::JavaScriptShared(JSRuntime *rt)
   : rt_(rt),
     refcount_(1),
     nextSerialNumber_(1)
@@ -176,16 +194,21 @@ JavaScriptShared::JavaScriptShared(JSRun
             Preferences::AddBoolVarCache(&sLoggingEnabled,
                                          "dom.ipc.cpows.log.enabled", false);
             Preferences::AddBoolVarCache(&sStackLoggingEnabled,
                                          "dom.ipc.cpows.log.stack", false);
         }
     }
 }
 
+JavaScriptShared::~JavaScriptShared()
+{
+    MOZ_RELEASE_ASSERT(cpows_.empty());
+}
+
 bool
 JavaScriptShared::init()
 {
     if (!objects_.init())
         return false;
     if (!cpows_.init())
         return false;
     if (!unwaivedObjectIds_.init())
--- a/js/ipc/JavaScriptShared.h
+++ b/js/ipc/JavaScriptShared.h
@@ -105,16 +105,19 @@ class IdToObjectMap
     bool init();
     void trace(JSTracer *trc);
     void sweep();
 
     bool add(ObjectId id, JSObject *obj);
     JSObject *find(ObjectId id);
     void remove(ObjectId id);
 
+    void clear();
+    bool empty() const;
+
   private:
     Table table_;
 };
 
 // Map JSObjects -> ids
 class ObjectToIdMap
 {
     typedef js::PointerHasher<JSObject *, 3> Hasher;
@@ -126,30 +129,31 @@ class ObjectToIdMap
 
     bool init();
     void trace(JSTracer *trc);
     void sweep();
 
     bool add(JSContext *cx, JSObject *obj, ObjectId id);
     ObjectId find(JSObject *obj);
     void remove(JSObject *obj);
+    void clear();
 
   private:
     static void keyMarkCallback(JSTracer *trc, JSObject *key, void *data);
 
     Table *table_;
 };
 
 class Logging;
 
 class JavaScriptShared
 {
   public:
     explicit JavaScriptShared(JSRuntime *rt);
-    virtual ~JavaScriptShared() {}
+    virtual ~JavaScriptShared();
 
     bool init();
 
     void decref();
     void incref();
 
     bool Unwrap(JSContext *cx, const InfallibleTArray<CpowEntry> &aCpows, JS::MutableHandleObject objp);
     bool Wrap(JSContext *cx, JS::HandleObject aObj, InfallibleTArray<CpowEntry> *outCpows);
--- a/js/ipc/WrapperOwner.cpp
+++ b/js/ipc/WrapperOwner.cpp
@@ -872,16 +872,20 @@ WrapperOwner::domInstanceOf(JSContext *c
 
     return ok(cx, status);
 }
 
 void
 WrapperOwner::ActorDestroy(ActorDestroyReason why)
 {
     inactive_ = true;
+
+    objects_.clear();
+    unwaivedObjectIds_.clear();
+    waivedObjectIds_.clear();
 }
 
 bool
 WrapperOwner::ipcfail(JSContext *cx)
 {
     JS_ReportError(cx, "child process crashed or timedout");
     return false;
 }