Backout changeset 69c0707a144a for crashes on a CLOSED TREE.
authorMs2ger <ms2ger@gmail.com>
Thu, 10 Jul 2014 21:04:26 +0200
changeset 193415 d6553613d42dcd358c266c21f67fdbb63d1cde29
parent 193414 c95a18275e1d8e2496af6d47e3bcc65b20a9c109
child 193416 6684d05944b6558a083e4eca4dc6afdb8980a4f0
push id27117
push userryanvm@gmail.com
push dateThu, 10 Jul 2014 22:23:14 +0000
treeherdermozilla-central@e1a037c085d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone33.0a1
backs out69c0707a144a585b6ea169c28c1b5a07e7fdd984
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
Backout changeset 69c0707a144a for crashes on a CLOSED TREE.
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -371,17 +371,17 @@ bool ConvertToPrimitive(JSContext *cx, H
 {
     return ValueToPrimitive<T, eDefault>(cx, v, retval);
 }
 
 // static
 bool
 XPCConvert::JSData2Native(void* d, HandleValue s,
                           const nsXPTType& type,
-                          const nsID* iid,
+                          bool useAllocator, const nsID* iid,
                           nsresult* pErr)
 {
     NS_PRECONDITION(d, "bad param");
 
     AutoJSContext cx;
     if (pErr)
         *pErr = NS_ERROR_XPC_BAD_CONVERT_JS;
 
@@ -469,57 +469,77 @@ XPCConvert::JSData2Native(void* d, Handl
         }
         *((const nsID**)d) = pid;
         return true;
     }
 
     case nsXPTType::T_ASTRING:
     {
         if (s.isUndefined()) {
-            (**((nsAString**)d)).SetIsVoid(true);
+            if (useAllocator)
+                *((const nsAString**)d) = &NullString();
+            else
+                (**((nsAString**)d)).SetIsVoid(true);
             return true;
         }
         // Fall through to T_DOMSTRING case.
     }
     case nsXPTType::T_DOMSTRING:
     {
         if (s.isNull()) {
-            (**((nsAString**)d)).SetIsVoid(true);
+            if (useAllocator)
+                *((const nsAString**)d) = &NullString();
+            else
+                (**((nsAString**)d)).SetIsVoid(true);
             return true;
         }
         size_t length = 0;
         const char16_t* chars = nullptr;
         JSString* str = nullptr;
         if (!s.isUndefined()) {
             str = ToString(cx, s);
             if (!str)
                 return false;
 
-            chars = JS_GetStringCharsAndLength(cx, str, &length);
+            chars = useAllocator ? JS_GetStringCharsZAndLength(cx, str, &length)
+                                 : JS_GetStringCharsAndLength(cx, str, &length);
             if (!chars)
                 return false;
 
             if (!length) {
-                (**((nsAString**)d)).Truncate();
+                if (useAllocator)
+                    *((const nsAString**)d) = &EmptyString();
+                else
+                    (**((nsAString**)d)).Truncate();
                 return true;
             }
         }
 
-        nsString* ws = *((nsString**)d);
+        nsString* ws;
+        if (useAllocator) {
+            ws = nsXPConnect::GetRuntimeInstance()->NewShortLivedString();
+            *((const nsString**)d) = ws;
+        } else {
+            ws = *((nsString**)d);
+        }
 
         if (!str) {
             ws->AssignLiteral(MOZ_UTF16("undefined"));
         } else if (XPCStringConvert::IsDOMString(str)) {
             // The characters represent an existing nsStringBuffer that
             // was shared by XPCStringConvert::ReadableToJSVal.
             nsStringBuffer::FromData((void *)chars)->ToString(length, *ws);
         } else if (XPCStringConvert::IsLiteral(str)) {
             // The characters represent a literal char16_t string constant
             // compiled into libxul, such as the string "undefined" above.
             ws->AssignLiteral(chars, length);
+        } else if (useAllocator && STRING_TO_JSVAL(str) == s) {
+            // The JS string will exist over the function call.
+            // We don't need to copy the characters in this case.
+            ws->Rebind(chars, length);
         } else {
             ws->Assign(chars, length);
         }
         return true;
     }
 
     case nsXPTType::T_CHAR_STR:
     {
@@ -590,66 +610,106 @@ XPCConvert::JSData2Native(void* d, Handl
 
     case nsXPTType::T_UTF8STRING:
     {
         const jschar* chars;
         size_t length;
         JSString* str;
 
         if (s.isNull() || s.isUndefined()) {
-            nsCString* rs = *((nsCString**)d);
-            rs->SetIsVoid(true);
+            if (useAllocator) {
+                *((const nsACString**)d) = &NullCString();
+            } else {
+                nsCString* rs = *((nsCString**)d);
+                rs->SetIsVoid(true);
+            }
             return true;
         }
 
         // The JS val is neither null nor void...
 
         if (!(str = ToString(cx, s))||
             !(chars = JS_GetStringCharsAndLength(cx, str, &length))) {
             return false;
         }
 
         if (!length) {
-            nsCString* rs = *((nsCString**)d);
-            rs->Truncate();
+            if (useAllocator) {
+                *((const nsACString**)d) = &EmptyCString();
+            } else {
+                nsCString* rs = *((nsCString**)d);
+                rs->Truncate();
+            }
             return true;
         }
 
-        nsCString *rs = *((nsCString**)d);
+        nsCString *rs;
+        if (useAllocator) {
+            // Use nsCString to enable sharing
+            rs = new nsCString();
+            if (!rs)
+                return false;
+
+            *((const nsCString**)d) = rs;
+        } else {
+            rs = *((nsCString**)d);
+        }
         CopyUTF16toUTF8(Substring(chars, length), *rs);
         return true;
     }
 
     case nsXPTType::T_CSTRING:
     {
         if (s.isNull() || s.isUndefined()) {
-            nsACString* rs = *((nsACString**)d);
-            rs->Truncate();
-            rs->SetIsVoid(true);
+            if (useAllocator) {
+                nsACString *rs = new nsCString();
+                if (!rs)
+                    return false;
+
+                rs->SetIsVoid(true);
+                *((nsACString**)d) = rs;
+            } else {
+                nsACString* rs = *((nsACString**)d);
+                rs->Truncate();
+                rs->SetIsVoid(true);
+            }
             return true;
         }
 
         // The JS val is neither null nor void...
         JSString* str = ToString(cx, s);
         if (!str) {
             return false;
         }
 
         size_t length = JS_GetStringEncodingLength(cx, str);
         if (length == size_t(-1)) {
             return false;
         }
 
         if (!length) {
-            nsCString* rs = *((nsCString**)d);
-            rs->Truncate();
+            if (useAllocator) {
+                *((const nsACString**)d) = &EmptyCString();
+            } else {
+                nsCString* rs = *((nsCString**)d);
+                rs->Truncate();
+            }
             return true;
         }
 
-        nsACString *rs = *((nsACString**)d);
+        nsACString *rs;
+        if (useAllocator) {
+            rs = new nsCString();
+            if (!rs)
+                return false;
+            *((const nsACString**)d) = rs;
+        } else {
+            rs = *((nsACString**)d);
+        }
+
         rs->SetLength(uint32_t(length));
         if (rs->Length() != uint32_t(length)) {
             return false;
         }
         JS_EncodeStringToBuffer(cx, str, rs->BeginWriting(), length);
 
         return true;
     }
@@ -1543,17 +1603,17 @@ XPCConvert::JSArray2Native(void** d, Han
             nullptr == (array = nsMemory::Alloc(count * sizeof(_t)))) {        \
             if (pErr)                                                          \
                 *pErr = NS_ERROR_OUT_OF_MEMORY;                                \
             goto failure;                                                      \
         }                                                                      \
         for (initedCount = 0; initedCount < count; initedCount++) {            \
             if (!JS_GetElement(cx, jsarray, initedCount, &current) ||          \
                 !JSData2Native(((_t*)array)+initedCount, current, type,        \
-                               iid, pErr))                                     \
+                               true, iid, pErr))                               \
                 goto failure;                                                  \
         }                                                                      \
     PR_END_MACRO
 
     // No Action, FRee memory, RElease object
     enum CleanupMode {na, fr, re};
 
     CleanupMode cleanupMode;
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -278,17 +278,20 @@ GetNamedPropertyAsVariantRaw(XPCCallCont
                              HandleId aName,
                              nsIVariant** aResult,
                              nsresult* pErr)
 {
     nsXPTType type = nsXPTType((uint8_t)TD_INTERFACE_TYPE);
     RootedValue val(ccx);
 
     return JS_GetPropertyById(ccx, aJSObj, aName, &val) &&
-           XPCConvert::JSData2Native(aResult, val, type,
+           // Note that this always takes the T_INTERFACE path through
+           // JSData2Native, so the value passed for useAllocator
+           // doesn't really matter. We pass true for consistency.
+           XPCConvert::JSData2Native(aResult, val, type, true,
                                      &NS_GET_IID(nsIVariant), pErr);
 }
 
 // static
 nsresult
 nsXPCWrappedJSClass::GetNamedPropertyAsVariant(XPCCallContext& ccx,
                                                JSObject* aJSObjArg,
                                                const nsAString& aName,
@@ -1342,23 +1345,23 @@ pre_call_clean_up:
         }
 
 // see bug #961488
 #if (defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(_AIX)) && \
     ((defined(__sparc) && !defined(__sparcv9) && !defined(__sparcv9__)) || \
     (defined(__powerpc__) && !defined (__powerpc64__)))
         if (type_tag == nsXPTType::T_JSVAL) {
             if (!XPCConvert::JSData2Native(*(void**)(&pv->val), val, type,
-                                           &param_iid, nullptr))
+                                           !param.IsDipper(), &param_iid, nullptr))
                 break;
         } else
 #endif
         {
             if (!XPCConvert::JSData2Native(&pv->val, val, type,
-                                           &param_iid, nullptr))
+                                           !param.IsDipper(), &param_iid, nullptr))
                 break;
         }
     }
 
     // if any params were dependent, then we must iterate again to convert them.
     if (foundDependentParam && i == paramCount) {
         for (i = 0; i < paramCount; i++) {
             const nsXPTParamInfo& param = info->params[i];
@@ -1421,17 +1424,17 @@ pre_call_clean_up:
                     break;
             } else if (isSizedString) {
                 if (!XPCConvert::JSStringWithSize2Native((void*)&pv->val, val,
                                                          array_count, datum_type,
                                                          nullptr))
                     break;
             } else {
                 if (!XPCConvert::JSData2Native(&pv->val, val, type,
-                                               &param_iid,
+                                               true, &param_iid,
                                                nullptr))
                     break;
             }
         }
     }
 
     if (i != paramCount) {
         // We didn't manage all the result conversions!
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -2151,17 +2151,17 @@ CallMethodHelper::ConvertIndependentPara
     if (type_tag == nsXPTType::T_INTERFACE &&
         NS_FAILED(mIFaceInfo->GetIIDForParamNoAlloc(mVTableIndex, &paramInfo,
                                                     &param_iid))) {
         ThrowBadParam(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO, i, mCallContext);
         return false;
     }
 
     nsresult err;
-    if (!XPCConvert::JSData2Native(&dp->val, src, type, &param_iid, &err)) {
+    if (!XPCConvert::JSData2Native(&dp->val, src, type, true, &param_iid, &err)) {
         ThrowBadParam(err, i, mCallContext);
         return false;
     }
 
     return true;
 }
 
 bool
@@ -2271,17 +2271,17 @@ CallMethodHelper::ConvertDependentParam(
             if (!XPCConvert::JSStringWithSize2Native((void*)&dp->val,
                                                      src, array_count,
                                                      datum_type, &err)) {
                 ThrowBadParam(err, i, mCallContext);
                 return false;
             }
         }
     } else {
-        if (!XPCConvert::JSData2Native(&dp->val, src, type,
+        if (!XPCConvert::JSData2Native(&dp->val, src, type, true,
                                        &param_iid, &err)) {
             ThrowBadParam(err, i, mCallContext);
             return false;
         }
     }
 
     return true;
 }
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2496,17 +2496,17 @@ public:
      */
 
     static bool NativeData2JS(JS::MutableHandleValue d,
                               const void* s, const nsXPTType& type,
                               const nsID* iid, nsresult* pErr);
 
     static bool JSData2Native(void* d, JS::HandleValue s,
                               const nsXPTType& type,
-                              const nsID* iid,
+                              bool useAllocator, const nsID* iid,
                               nsresult* pErr);
 
     /**
      * Convert a native nsISupports into a JSObject.
      *
      * @param dest [out] the resulting JSObject
      * @param src the native object we're working with
      * @param iid the interface of src that we want (may be null)