Bug 861912 - GC: Remove use of AUTO_MARK_JSVAL in XPConnect r=bholley
☠☠ backed out by 712e8ba8219b ☠ ☠
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 09 Apr 2013 16:42:32 +0100
changeset 128916 76f7d796369277f90462af18ba530cfe4ee236a6
parent 128915 3fa225a54135f955614f0b7bb781f3f2b401548e
child 128917 a3fe83ef26e321b6e51a7afd0ddfd3123edb87da
push id26569
push userjcoppeard@mozilla.com
push dateTue, 16 Apr 2013 13:27:26 +0000
treeherdermozilla-inbound@76f7d7963692 [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
@@ -24,16 +24,17 @@
 #include "jsfriendapi.h"
 
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/PrimitiveConversions.h"
 
 using namespace xpc;
 using namespace mozilla;
 using namespace mozilla::dom;
+using namespace JS;
 
 //#define STRICT_CHECK_OF_UNICODE
 #ifdef STRICT_CHECK_OF_UNICODE
 #define ILLEGAL_RANGE(c) (0!=((c) & 0xFF80))
 #else // STRICT_CHECK_OF_UNICODE
 #define ILLEGAL_RANGE(c) (0!=((c) & 0xFF00))
 #endif // STRICT_CHECK_OF_UNICODE
 
@@ -164,17 +165,17 @@ XPCConvert::NativeData2JS(XPCLazyCallCon
             XPC_LOG_ERROR(("XPCConvert::NativeData2JS : void* params not supported"));
             return false;
 
         case nsXPTType::T_IID:
             {
                 nsID* iid2 = *((nsID**)s);
                 if (!iid2)
                     break;
-                JS::RootedObject scope(cx, lccx.GetScopeForNewJSObjects());
+                RootedObject scope(cx, lccx.GetScopeForNewJSObjects());
                 JSObject* obj;
                 if (!(obj = xpc_NewIDObject(cx, scope, *iid2)))
                     return false;
                 *d = OBJECT_TO_JSVAL(obj);
                 break;
             }
 
         case nsXPTType::T_ASTRING:
@@ -825,17 +826,17 @@ XPCConvert::NativeInterface2JSObject(XPC
     // Note: If |cache->IsProxy()| is true, then it means that the object
     // implementing it doesn't want a wrapped native as its JS Object, but
     // instead it provides its own proxy object. In that case, the object
     // to use is found as cache->GetWrapper(). If that is null, then the
     // object will create (and fill the cache) from its WrapObject call.
     nsWrapperCache *cache = aHelper.GetWrapperCache();
 
     bool tryConstructSlimWrapper = false;
-    JS::RootedObject flat(cx);
+    RootedObject flat(cx);
     if (cache) {
         flat = cache->GetWrapper();
         if (cache->IsDOMBinding()) {
             XPCCallContext &ccx = lccx.GetXPCCallContext();
             if (!ccx.IsValid())
                 return false;
 
             if (!flat) {
@@ -1148,17 +1149,17 @@ public:
 
     ~AutoExceptionRestorer()
     {
         JS_SetPendingException(mContext, tvr.jsval_value());
     }
 
 private:
     JSContext * const mContext;
-    JS::AutoValueRooter tvr;
+    AutoValueRooter tvr;
 };
 
 // static
 nsresult
 XPCConvert::JSValToXPCException(XPCCallContext& ccx,
                                 jsval s,
                                 const char* ifaceName,
                                 const char* methodName,
@@ -1406,39 +1407,36 @@ 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;
--- 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;
 
@@ -711,22 +707,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.
         //
@@ -1286,18 +1279,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
@@ -498,19 +498,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, JSVAL_NULL);
     JSBool needsSOW = false;
     JSBool needsCOW = false;
 
     mozilla::Maybe<JSAutoCompartment> ac;
 
     if (sciWrapper.GetFlags().WantPreCreate()) {
         // PreCreate may touch dead compartments.
         js::AutoMaybeTouchDeadZones agc(parent);
@@ -2436,17 +2434,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
@@ -3852,35 +3852,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
 {
@@ -3949,17 +3930,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) {}
@@ -4002,24 +3982,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[]);