author | Ms2ger <ms2ger@gmail.com> |
Thu, 10 Jul 2014 21:04:26 +0200 | |
changeset 193415 | d6553613d42dcd358c266c21f67fdbb63d1cde29 |
parent 193414 | c95a18275e1d8e2496af6d47e3bcc65b20a9c109 |
child 193416 | 6684d05944b6558a083e4eca4dc6afdb8980a4f0 |
push id | 27117 |
push user | ryanvm@gmail.com |
push date | Thu, 10 Jul 2014 22:23:14 +0000 |
treeherder | mozilla-central@e1a037c085d1 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 33.0a1 |
backs out | 69c0707a144a585b6ea169c28c1b5a07e7fdd984 |
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
|
--- 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, ¤t) || \ !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, - ¶m_iid, nullptr)) + !param.IsDipper(), ¶m_iid, nullptr)) break; } else #endif { if (!XPCConvert::JSData2Native(&pv->val, val, type, - ¶m_iid, nullptr)) + !param.IsDipper(), ¶m_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, - ¶m_iid, + true, ¶m_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, ¶mInfo, ¶m_iid))) { ThrowBadParam(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO, i, mCallContext); return false; } nsresult err; - if (!XPCConvert::JSData2Native(&dp->val, src, type, ¶m_iid, &err)) { + if (!XPCConvert::JSData2Native(&dp->val, src, type, true, ¶m_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, ¶m_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)