Bug 861912 - GC: Remove use of AUTO_MARK_JSVAL in XPConnect r=bholley
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 09 Apr 2013 16:42:32 +0100
changeset 129733 233f42abf005885675622decfd19712ff71f957c
parent 129732 dff116662296a26dfdd9ac2ef49f7476ad85d899
child 129734 5e96a99f7c5dacc73d017d61e08e877ff9082fbd
push id26973
push userjcoppeard@mozilla.com
push dateWed, 24 Apr 2013 09:46:52 +0000
treeherdermozilla-inbound@da6a56be2e05 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs861912
milestone23.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 861912 - GC: Remove use of AUTO_MARK_JSVAL in XPConnect r=bholley
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -1408,39 +1408,33 @@ XPCConvert::NativeArray2JS(XPCLazyCallCo
     JSContext* cx = ccx.GetJSContext();
     NS_ABORT_IF_FALSE(js::IsObjectInContextCompartment(lccx.GetScopeForNewJSObjects(), cx),
                       "bad scope for new JSObjects");
 
     // XXX add support for putting chars in a string rather than an array
 
     // XXX add support to indicate *which* array element was not convertable
 
-    JSObject *array = JS_NewArrayObject(cx, count, nullptr);
-
+    RootedObject array(cx, JS_NewArrayObject(cx, count, nullptr));
     if (!array)
         return false;
 
-    // root this early
-    *d = OBJECT_TO_JSVAL(array);
-    AUTO_MARK_JSVAL(ccx, d);
-
     if (pErr)
         *pErr = NS_ERROR_XPC_BAD_CONVERT_NATIVE;
 
     uint32_t i;
-    jsval current = JSVAL_NULL;
-    AUTO_MARK_JSVAL(ccx, &current);
+    RootedValue current(cx, JSVAL_NULL);
 
-#define POPULATE(_t)                                                          \
-    PR_BEGIN_MACRO                                                            \
-        for (i = 0; i < count; i++) {                                         \
-            if (!NativeData2JS(ccx, &current, ((_t*)*s)+i, type, iid, pErr) ||\
-                !JS_SetElement(cx, array, i, &current))                       \
-                goto failure;                                                 \
-        }                                                                     \
+#define POPULATE(_t)                                                                    \
+    PR_BEGIN_MACRO                                                                      \
+        for (i = 0; i < count; i++) {                                                   \
+            if (!NativeData2JS(ccx, current.address(), ((_t*)*s)+i, type, iid, pErr) || \
+                !JS_SetElement(cx, array, i, current.address()))                        \
+                goto failure;                                                           \
+        }                                                                               \
     PR_END_MACRO
 
     // XXX check IsPtr - esp. to handle array of nsID (as opposed to nsID*)
 
     switch (type.TagPart()) {
     case nsXPTType::T_I8            : POPULATE(int8_t);         break;
     case nsXPTType::T_I16           : POPULATE(int16_t);        break;
     case nsXPTType::T_I32           : POPULATE(int32_t);        break;
@@ -1464,16 +1458,17 @@ XPCConvert::NativeArray2JS(XPCLazyCallCo
     case nsXPTType::T_UTF8STRING    : NS_ERROR("bad type"); goto failure;
     case nsXPTType::T_CSTRING       : NS_ERROR("bad type"); goto failure;
     case nsXPTType::T_ASTRING       : NS_ERROR("bad type"); goto failure;
     default                         : NS_ERROR("bad type"); goto failure;
     }
 
     if (pErr)
         *pErr = NS_OK;
+    *d = OBJECT_TO_JSVAL(array);
     return true;
 
 failure:
     return false;
 
 #undef POPULATE
 }
 
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -227,19 +227,16 @@ nsXPCWrappedJSClass::CallQueryInterfaceO
     if (!scriptEval.StartEvaluating(jsobj))
         return nullptr;
 
     // check upfront for the existence of the function property
     funid = mRuntime->GetStringID(XPCJSRuntime::IDX_QUERY_INTERFACE);
     if (!JS_GetPropertyById(cx, jsobj, funid, fun.address()) || JSVAL_IS_PRIMITIVE(fun))
         return nullptr;
 
-    // protect fun so that we're sure it's alive when we call it
-    AUTO_MARK_JSVAL(cx, fun);
-
     // Ensure that we are asking for a scriptable interface.
     // NB:  It's important for security that this check is here rather
     // than later, since it prevents untrusted objects from implementing
     // some interfaces in JS and aggregating a trusted object to
     // implement intentionally (for security) unscriptable interfaces.
     // We so often ask for nsISupports that we can short-circuit the test...
     if (!aIID.Equals(NS_GET_IID(nsISupports))) {
         nsCOMPtr<nsIInterfaceInfo> info;
@@ -266,17 +263,16 @@ nsXPCWrappedJSClass::CallQueryInterfaceO
 
         JS_SetOptions(cx, oldOpts);
 
         if (!success) {
             NS_ASSERTION(JS_IsExceptionPending(cx),
                          "JS failed without setting an exception!");
 
             RootedValue jsexception(cx, NullValue());
-            AUTO_MARK_JSVAL(cx, jsexception.address());
 
             if (JS_GetPendingException(cx, jsexception.address())) {
                 nsresult rv;
                 if (jsexception.isObject()) {
                     // XPConnect may have constructed an object to represent a
                     // C++ QI failure. See if that is the case.
                     nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
 
@@ -713,22 +709,19 @@ nsXPCWrappedJSClass::DelegatedQueryInter
             if (!checked)
                 return NS_ERROR_OUT_OF_MEMORY;
             *aInstancePtr = checked.forget().get();
             return NS_OK;
         }
     }
 
     // check if the JSObject claims to implement this interface
-    JSObject* jsobj = CallQueryInterfaceOnJSObject(ccx, self->GetJSObject(),
-                                                   aIID);
+    RootedObject jsobj(ccx, CallQueryInterfaceOnJSObject(ccx, self->GetJSObject(),
+                                                         aIID));
     if (jsobj) {
-        // protect jsobj until it is actually attached
-        AUTO_MARK_JSVAL(ccx, OBJECT_TO_JSVAL(jsobj));
-
         // We can't use XPConvert::JSObject2NativeInterface() here
         // since that can find a XPCWrappedNative directly on the
         // proto chain, and we don't want that here. We need to find
         // the actual JS object that claimed it supports the interface
         // we're looking for or we'll potentially bypass security
         // checks etc by calling directly through to a native found on
         // the prototype chain.
         //
@@ -1290,18 +1283,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
     // we're trusting the JS engine to come up with a good global to use for
     // our object (whatever it was).
     for (i = 0; i < argc; i++) {
         const nsXPTParamInfo& param = info->params[i];
         const nsXPTType& type = param.GetType();
         nsXPTType datum_type;
         uint32_t array_count;
         bool isArray = type.IsArray();
-        RootedValue val(cx, JSVAL_NULL);
-        AUTO_MARK_JSVAL(ccx, val.address());
+        RootedValue val(cx, NullValue());
         bool isSizedString = isArray ?
                 false :
                 type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS ||
                 type.TagPart() == nsXPTType::T_PWSTRING_SIZE_IS;
 
 
         // verify that null was not passed for 'out' param
         if (param.IsOut() && !nativeParams[i].val.p) {
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -491,19 +491,17 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
     // described by the nsIClassInfo, not for the class info object
     // itself.
     const XPCNativeScriptableCreateInfo& sciWrapper =
         isClassInfo ? sci :
         GatherScriptableCreateInfo(identity, info, sciProto, sci);
 
     RootedObject parent(ccx, Scope->GetGlobalJSObject());
 
-    jsval newParentVal = JSVAL_NULL;
-    XPCMarkableJSVal newParentVal_markable(&newParentVal);
-    AutoMarkingJSVal newParentVal_automarker(ccx, &newParentVal_markable);
+    RootedValue newParentVal(ccx, NullValue());
     JSBool needsSOW = false;
     JSBool needsCOW = false;
 
     mozilla::Maybe<JSAutoCompartment> ac;
 
     if (sciWrapper.GetFlags().WantPreCreate()) {
         // PreCreate may touch dead compartments.
         js::AutoMaybeTouchDeadZones agc(parent);
@@ -2429,17 +2427,16 @@ CallMethodHelper::GatherAndConvertResult
     for (uint8_t i = 0; i < paramCount; i++) {
         const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(i);
         if (!paramInfo.IsOut() && !paramInfo.IsDipper())
             continue;
 
         const nsXPTType& type = paramInfo.GetType();
         nsXPTCVariant* dp = GetDispatchParam(i);
         RootedValue v(mCallContext, NullValue());
-        AUTO_MARK_JSVAL(mCallContext, v.address());
         uint32_t array_count = 0;
         nsXPTType datum_type;
         bool isArray = type.IsArray();
         bool isSizedString = isArray ?
                 false :
                 type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS ||
                 type.TagPart() == nsXPTType::T_PWSTRING_SIZE_IS;
 
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -419,19 +419,16 @@ DefinePropertyIfFound(XPCCallContext& cc
          scriptableInfo->GetFlags().DontEnumQueryInterface() &&
          id == rt->GetStringID(XPCJSRuntime::IDX_QUERY_INTERFACE)))
         propFlags &= ~JSPROP_ENUMERATE;
 
     RootedValue funval(ccx);
     if (!member->NewFunctionObject(ccx, iface, obj, funval.address()))
         return false;
 
-    // protect funobj until it is actually attached
-    AUTO_MARK_JSVAL(ccx, funval);
-
 #ifdef off_DEBUG_jband
     {
         static int cloneCount = 0;
         if (!(++cloneCount%10))
             printf("<><><> %d cloned functions created\n", cloneCount);
     }
 #endif
 
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -1588,17 +1588,16 @@ nsXPConnect::CreateSandbox(JSContext *cx
 {
     XPCCallContext ccx(NATIVE_CALLER, cx);
     if (!ccx.IsValid())
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
     *_retval = nullptr;
 
     RootedValue rval(cx, JSVAL_VOID);
-    AUTO_MARK_JSVAL(ccx, rval.address());
 
     SandboxOptions options(cx);
     nsresult rv = xpc_CreateSandboxObject(cx, rval.address(), principal, options);
     NS_ASSERTION(NS_FAILED(rv) || !JSVAL_IS_PRIMITIVE(rval),
                  "Bad return value from xpc_CreateSandboxObject()!");
 
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(rval)) {
         *_retval = XPCJSObjectHolder::newHolder(ccx, JSVAL_TO_OBJECT(rval));
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3858,35 +3858,16 @@ private:
     JS::RootedId mOld;
 #ifdef DEBUG
     JS::RootedId mCheck;
 #endif
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 /***************************************************************************/
-class XPCMarkableJSVal
-{
-public:
-    XPCMarkableJSVal(jsval val) : mVal(val), mValPtr(&mVal) {}
-    XPCMarkableJSVal(jsval *pval) : mVal(JSVAL_VOID), mValPtr(pval) {}
-    ~XPCMarkableJSVal() {}
-    void Mark() {}
-    void TraceJS(JSTracer* trc)
-    {
-        JS_CallValueTracer(trc, *mValPtr, "XPCMarkableJSVal");
-    }
-    void AutoTrace(JSTracer* trc) {}
-private:
-    XPCMarkableJSVal(); // not implemented
-    jsval  mVal;
-    jsval* mValPtr;
-};
-
-/***************************************************************************/
 // AutoMarkingPtr is the base class for the various AutoMarking pointer types
 // below. This system allows us to temporarily protect instances of our garbage
 // collected types after they are constructed but before they are safely
 // attached to other rooted objects.
 // This base class has pure virtual support for marking.
 
 class AutoMarkingPtr
 {
@@ -3955,17 +3936,16 @@ class TypedAutoMarkingPtr : public AutoM
     T* mPtr;
 };
 
 typedef TypedAutoMarkingPtr<XPCNativeInterface> AutoMarkingNativeInterfacePtr;
 typedef TypedAutoMarkingPtr<XPCNativeSet> AutoMarkingNativeSetPtr;
 typedef TypedAutoMarkingPtr<XPCWrappedNative> AutoMarkingWrappedNativePtr;
 typedef TypedAutoMarkingPtr<XPCWrappedNativeTearOff> AutoMarkingWrappedNativeTearOffPtr;
 typedef TypedAutoMarkingPtr<XPCWrappedNativeProto> AutoMarkingWrappedNativeProtoPtr;
-typedef TypedAutoMarkingPtr<XPCMarkableJSVal> AutoMarkingJSVal;
 typedef TypedAutoMarkingPtr<XPCNativeScriptableInfo> AutoMarkingNativeScriptableInfoPtr;
 
 template<class T>
 class ArrayAutoMarkingPtr : public AutoMarkingPtr
 {
   public:
     ArrayAutoMarkingPtr(JSContext* cx)
       : AutoMarkingPtr(cx), mPtr(nullptr), mCount(0) {}
@@ -4008,24 +3988,16 @@ class ArrayAutoMarkingPtr : public AutoM
 
   private:
     T** mPtr;
     uint32_t mCount;
 };
 
 typedef ArrayAutoMarkingPtr<XPCNativeInterface> AutoMarkingNativeInterfacePtrArrayPtr;
 
-#define AUTO_MARK_JSVAL_HELPER2(tok, line) tok##line
-#define AUTO_MARK_JSVAL_HELPER(tok, line) AUTO_MARK_JSVAL_HELPER2(tok, line)
-
-#define AUTO_MARK_JSVAL(cx, val)                                              \
-    XPCMarkableJSVal AUTO_MARK_JSVAL_HELPER(_val_,__LINE__)(val);             \
-    AutoMarkingJSVal AUTO_MARK_JSVAL_HELPER(_automarker_,__LINE__)            \
-    (cx, &AUTO_MARK_JSVAL_HELPER(_val_,__LINE__))
-
 /***************************************************************************/
 // Allocates a string that grants all access ("AllAccess")
 
 extern char* xpc_CloneAllAccess();
 /***************************************************************************/
 // Returns access if wideName is in list
 
 extern char * xpc_CheckAccessList(const PRUnichar* wideName, const char* list[]);