diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 2f1929aee50..db3ed821f45 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -478,10 +478,13 @@ template inline bool WrapNewBindingObject(JSContext* cx, JSObject* scope, T* value, JS::Value* vp) { - JSObject* obj = value->GetWrapper(); - if (obj && js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)) { - *vp = JS::ObjectValue(*obj); - return true; + JSObject* obj = value->GetWrapperPreserveColor(); + if (obj) { + xpc_UnmarkNonNullGrayObject(obj); + if (js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)) { + *vp = JS::ObjectValue(*obj); + return true; + } } if (!obj) { diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index e9639fbc0eb..d8eca979c9c 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -140,16 +140,23 @@ xpc_GCThingIsGrayCCThing(void *thing); extern void xpc_UnmarkGrayGCThingRecursive(void *thing, JSGCTraceKind kind); +// Unmark gray for known-nonnull cases +MOZ_ALWAYS_INLINE void +xpc_UnmarkNonNullGrayObject(JSObject *obj) +{ + if (xpc_IsGrayGCThing(obj)) + xpc_UnmarkGrayGCThingRecursive(obj, JSTRACE_OBJECT); + else if (JS::IsIncrementalBarrierNeededOnGCThing(obj)) + js::IncrementalReferenceBarrier(obj); +} + // Remove the gray color from the given JSObject and any other objects that can // be reached through it. -inline JSObject * +MOZ_ALWAYS_INLINE JSObject * xpc_UnmarkGrayObject(JSObject *obj) { if (obj) { - if (xpc_IsGrayGCThing(obj)) - xpc_UnmarkGrayGCThingRecursive(obj, JSTRACE_OBJECT); - else if (JS::IsIncrementalBarrierNeededOnGCThing(obj)) - js::IncrementalReferenceBarrier(obj); + xpc_UnmarkNonNullGrayObject(obj); } return obj; }