diff --git a/js/src/proxy/CrossCompartmentWrapper.cpp b/js/src/proxy/CrossCompartmentWrapper.cpp index d679a08b3..10470a40f 100644 --- a/js/src/proxy/CrossCompartmentWrapper.cpp +++ b/js/src/proxy/CrossCompartmentWrapper.cpp @@ -433,7 +433,7 @@ js::NukeCrossCompartmentWrapper(JSContext* cx, JSObject* wrapper) NotifyGCNukeWrapper(wrapper); - wrapper->as().nuke(&DeadObjectProxy::singleton); + wrapper->as().nuke(); MOZ_ASSERT(IsDeadProxyObject(wrapper)); } diff --git a/js/src/vm/ProxyObject.cpp b/js/src/vm/ProxyObject.cpp index 132de707b..bde6b41fb 100644 --- a/js/src/vm/ProxyObject.cpp +++ b/js/src/vm/ProxyObject.cpp @@ -7,6 +7,9 @@ #include "vm/ProxyObject.h" #include "jscompartment.h" + +#include "proxy/DeadObjectProxy.h" + #include "jsobjinlines.h" using namespace js; @@ -86,14 +89,20 @@ ProxyObject::setSameCompartmentPrivate(const Value& priv) } void -ProxyObject::nuke(const BaseProxyHandler* handler) +ProxyObject::nuke() { + // Clear the target reference. setSameCompartmentPrivate(NullValue()); - for (size_t i = 0; i < PROXY_EXTRA_SLOTS; i++) - SetProxyExtra(this, i, NullValue()); - /* Restore the handler as requested after nuking. */ - setHandler(handler); + // Update the handler to make this a DeadObjectProxy. + setHandler(&DeadObjectProxy::singleton); + + // The proxy's extra slots are not cleared and will continue to be + // traced. This avoids the possibility of triggering write barriers while + // nuking proxies in dead compartments which could otherwise cause those + // compartments to be kept alive. Note that these are slots cannot hold + // cross compartment pointers, so this cannot cause the target compartment + // to leak. } JS_FRIEND_API(void) diff --git a/js/src/vm/ProxyObject.h b/js/src/vm/ProxyObject.h index e22d39288..64a0fe1ec 100644 --- a/js/src/vm/ProxyObject.h +++ b/js/src/vm/ProxyObject.h @@ -102,7 +102,7 @@ class ProxyObject : public JSObject static void trace(JSTracer* trc, JSObject* obj); - void nuke(const BaseProxyHandler* handler); + void nuke(); // There is no class_ member to force specialization of JSObject::is(). // The implementation in JSObject is incorrect for proxies since it doesn't