From fe9a03e77b0aa17cc9b5c863c9cdac8ba643b66c Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Thu, 22 Aug 2013 22:17:09 -0700 Subject: [PATCH] Bug 903772: Part 4 - Harmonize main thread and worker dictionary implementations. r=peterv --- content/base/src/nsDOMBlobBuilder.cpp | 19 +-- dom/bindings/AtomList.h | 23 ++++ dom/bindings/Codegen.py | 180 +++++++++++++++----------- dom/bindings/Configuration.py | 2 - dom/bindings/GlobalGen.py | 3 + dom/bindings/Makefile.in | 1 + dom/bindings/moz.build | 2 + dom/workers/RuntimeService.cpp | 22 +++- dom/workers/TextEncoder.h | 2 +- dom/workers/URL.cpp | 6 +- dom/workers/URL.h | 4 +- dom/workers/WorkerPrivate.cpp | 7 - dom/workers/XMLHttpRequest.cpp | 2 +- dom/workers/XMLHttpRequest.h | 4 +- js/xpconnect/src/XPCJSRuntime.cpp | 10 ++ 15 files changed, 179 insertions(+), 108 deletions(-) create mode 100644 dom/bindings/AtomList.h diff --git a/content/base/src/nsDOMBlobBuilder.cpp b/content/base/src/nsDOMBlobBuilder.cpp index 3d64bfaab0d..4637dc732c3 100644 --- a/content/base/src/nsDOMBlobBuilder.cpp +++ b/content/base/src/nsDOMBlobBuilder.cpp @@ -186,21 +186,12 @@ nsDOMMultipartFile::InitBlob(JSContext* aCx, { bool nativeEOL = false; if (aArgc > 1) { - if (NS_IsMainThread()) { - BlobPropertyBag d; - if (!d.Init(aCx, JS::Handle::fromMarkedLocation(&aArgv[1]))) { - return NS_ERROR_TYPE_ERR; - } - mContentType = d.mType; - nativeEOL = d.mEndings == EndingTypes::Native; - } else { - BlobPropertyBagWorkers d; - if (!d.Init(aCx, JS::Handle::fromMarkedLocation(&aArgv[1]))) { - return NS_ERROR_TYPE_ERR; - } - mContentType = d.mType; - nativeEOL = d.mEndings == EndingTypes::Native; + BlobPropertyBag d; + if (!d.Init(aCx, JS::Handle::fromMarkedLocation(&aArgv[1]))) { + return NS_ERROR_TYPE_ERR; } + mContentType = d.mType; + nativeEOL = d.mEndings == EndingTypes::Native; } if (aArgc > 0) { diff --git a/dom/bindings/AtomList.h b/dom/bindings/AtomList.h new file mode 100644 index 00000000000..7b948c744b9 --- /dev/null +++ b/dom/bindings/AtomList.h @@ -0,0 +1,23 @@ +#ifndef mozilla_dom_AtomList_h__ +#define mozilla_dom_AtomList_h__ + +#include "jsapi.h" +#include "mozilla/dom/GeneratedAtomList.h" + +namespace mozilla { +namespace dom { + +template +T* GetAtomCache(JSContext* aCx) +{ + JSRuntime* rt = JS_GetRuntime(aCx); + + auto atomCache = static_cast(JS_GetRuntimePrivate(rt)); + + return static_cast(atomCache); +} + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_AtomList_h__ diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index c04d11ac07a..39c0c1de70a 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -3481,8 +3481,7 @@ for (uint32_t i = 0; i < length; ++i) { # should be able to assume not isOptional here. assert not isOptional - typeName = CGDictionary.makeDictionaryName(type.inner, - descriptorProvider.workers) + typeName = CGDictionary.makeDictionaryName(type.inner) actualTypeName = typeName declType = CGGeneric(actualTypeName) @@ -4380,8 +4379,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider, return result, True, rooter, None if returnType.isDictionary(): nullable = returnType.nullable() - dictName = (CGDictionary.makeDictionaryName(returnType.unroll().inner, - descriptorProvider.workers) + + dictName = (CGDictionary.makeDictionaryName(returnType.unroll().inner) + "Initializer") result = CGGeneric(dictName) if not isMember and typeNeedsRooting(returnType, descriptorProvider): @@ -7966,9 +7964,7 @@ class CGDictionary(CGThing): def __init__(self, dictionary, descriptorProvider): self.dictionary = dictionary self.descriptorProvider = descriptorProvider - self.workers = descriptorProvider.workers - # NOTE: jsids are per-runtime, so don't use them in workers - self.needToInitIds = not self.workers and len(dictionary.members) > 0 + self.needToInitIds = len(dictionary.members) > 0 self.memberInfo = [ (member, getJSToNativeConversionInfo( @@ -7992,9 +7988,7 @@ class CGDictionary(CGThing): def base(self): if self.dictionary.parent: return self.makeClassName(self.dictionary.parent) - if not self.workers: - return "MainThreadDictionaryBase" - return "DictionaryBase" + return "MainThreadDictionaryBase" def initMethod(self): body = ( @@ -8003,10 +7997,17 @@ class CGDictionary(CGThing): "MOZ_ASSERT_IF(!cx, val.isNull());\n") if self.needToInitIds: - body += ( - "if (cx && !initedIds && !InitIds(cx)) {\n" - " return false;\n" - "}\n") + initIdText = """${dictName}Atoms* atomsCache = nullptr; +if (cx) { + atomsCache = GetAtomCache<${dictName}Atoms>(cx); + if (!*reinterpret_cast(atomsCache) && !InitIds(cx, atomsCache)) { + return false; + } +} + +""" + body += string.Template(initIdText).substitute( + { "dictName": self.makeClassName(self.dictionary)}) if self.dictionary.parent: body += ( @@ -8044,10 +8045,10 @@ class CGDictionary(CGThing): ], body=body) def initFromJSONMethod(self): - assert not self.workers return ClassMethod("Init", "bool", [ Argument('const nsAString&', 'aJSON'), ], body=( + "MOZ_ASSERT(NS_IsMainThread());\n" "AutoSafeJSContext cx;\n" "JS::Rooted json(cx);\n" "bool ok = ParseJSON(cx, aJSON, &json);\n" @@ -8058,10 +8059,14 @@ class CGDictionary(CGThing): def toObjectMethod(self): body = "" if self.needToInitIds: - body += ( - "if (!initedIds && !InitIds(cx)) {\n" - " return false;\n" - "}\n") + initIdText = """${dictName}Atoms* atomsCache = GetAtomCache<${dictName}Atoms>(cx); +if (!*reinterpret_cast(atomsCache) && !InitIds(cx, atomsCache)) { + return false; +} + +""" + body += string.Template(initIdText).substitute( + { "dictName": self.makeClassName(self.dictionary)}) if self.dictionary.parent: body += ( @@ -8092,23 +8097,28 @@ class CGDictionary(CGThing): def initIdsMethod(self): assert self.needToInitIds - idinit = [CGGeneric('!InternJSString(cx, %s, "%s")' % + idinit = [CGGeneric('!InternJSString(cx, atomsCache->%s, "%s")' % (m.identifier.name + "_id", m.identifier.name)) for m in self.dictionary.members] + idinit.reverse(); idinit = CGList(idinit, " ||\n") - idinit = CGWrapper(idinit, pre="if (", + idinit = CGWrapper(idinit, pre=""" +// Initialize these in reverse order so that any failure leaves the first one +// uninitialized. +if (""", post=(") {\n" " return false;\n" "}"), reindent=True) body = ( - "MOZ_ASSERT(!initedIds);\n" + "MOZ_ASSERT(!*reinterpret_cast(atomsCache));\n" "%s\n" - "initedIds = true;\n" "return true;") % idinit.define() return ClassMethod("InitIds", "bool", [ Argument("JSContext*", "cx"), + Argument("%sAtoms*" % self.makeClassName(self.dictionary), + "atomsCache"), ], static=True, body=body, visibility="private") def traceDictionaryMethod(self): @@ -8140,16 +8150,9 @@ class CGDictionary(CGThing): if self.needToInitIds: methods.append(self.initIdsMethod()) - members.append(ClassMember("initedIds", "bool", static=True, body="false")) - members.extend( - ClassMember(self.makeIdName(m.identifier.name), "jsid", static=True, body="JSID_VOID") - for m in d.members) methods.append(self.initMethod()) - - if not self.workers: - methods.append(self.initFromJSONMethod()) - + methods.append(self.initFromJSONMethod()) methods.append(self.toObjectMethod()) methods.append(self.traceDictionaryMethod()) @@ -8179,12 +8182,11 @@ class CGDictionary(CGThing): return self.dictionary.getDeps() @staticmethod - def makeDictionaryName(dictionary, workers): - suffix = "Workers" if workers else "" - return dictionary.identifier.name + suffix + def makeDictionaryName(dictionary): + return dictionary.identifier.name def makeClassName(self, dictionary): - return self.makeDictionaryName(dictionary, self.workers) + return self.makeDictionaryName(dictionary) @staticmethod def makeMemberName(name): @@ -8215,15 +8217,9 @@ class CGDictionary(CGThing): if member.defaultValue: replacements["haveValue"] = "!isNull && !temp.ref().isUndefined()" - # NOTE: jsids are per-runtime, so don't use them in workers - if self.workers: - propName = member.identifier.name - propGet = ('JS_GetProperty(cx, &val.toObject(), "%s", &temp.ref())' % - propName) - else: - propId = self.makeIdName(member.identifier.name); - propGet = ("JS_GetPropertyById(cx, &val.toObject(), %s, &temp.ref())" % - propId) + propId = self.makeIdName(member.identifier.name); + propGet = ("JS_GetPropertyById(cx, &val.toObject(), atomsCache->%s, &temp.ref())" % + propId) conversionReplacements = { "prop": self.makeMemberName(member.identifier.name), @@ -8259,14 +8255,9 @@ class CGDictionary(CGThing): # The data is inside the Optional<> memberData = "%s.InternalValue()" % memberLoc - if self.workers: - propDef = ( - 'JS_DefineProperty(cx, obj, "%s", temp, nullptr, nullptr, JSPROP_ENUMERATE)' % - member.identifier.name) - else: - propDef = ( - 'JS_DefinePropertyById(cx, obj, %s, temp, nullptr, nullptr, JSPROP_ENUMERATE)' % - self.makeIdName(member.identifier.name)) + propDef = ( + 'JS_DefinePropertyById(cx, obj, atomsCache->%s, temp, nullptr, nullptr, JSPROP_ENUMERATE)' % + self.makeIdName(member.identifier.name)) innerTemplate = wrapForType( member.type, self.descriptorProvider, @@ -8529,7 +8520,7 @@ class CGForwardDeclarations(CGWrapper): Code generate the forward declarations for a header file. """ def __init__(self, config, descriptors, mainCallbacks, workerCallbacks, - mainDictionaries, workerDictionaries, callbackInterfaces): + dictionaries, callbackInterfaces): builder = ForwardDeclarationBuilder() def forwardDeclareForType(t, workerness='both'): @@ -8580,13 +8571,11 @@ class CGForwardDeclarations(CGWrapper): for t in getTypesFromDescriptor(d): forwardDeclareForType(t) - for d in mainDictionaries: + for d in dictionaries: + if len(d.members) > 0: + builder.addInMozillaDom(d.identifier.name + "Atoms", isStruct=True) for t in getTypesFromDictionary(d): - forwardDeclareForType(t, workerness='mainthreadonly') - - for d in workerDictionaries: - for t in getTypesFromDictionary(d): - forwardDeclareForType(t, workerness='workeronly') + forwardDeclareForType(t) CGWrapper.__init__(self, builder.build()) @@ -8618,10 +8607,8 @@ class CGBindingRoot(CGThing): isEventTarget = webIDLFile.endswith("EventTarget.webidl") hasWorkerStuff = len(config.getDescriptors(webIDLFile=webIDLFile, workers=True)) != 0 - mainDictionaries = config.getDictionaries(webIDLFile=webIDLFile, - workers=False) - workerDictionaries = config.getDictionaries(webIDLFile=webIDLFile, - workers=True) + dictionaries = config.getDictionaries(webIDLFile=webIDLFile) + requiresAtoms = any([len(dict.members) > 0 for dict in dictionaries]) mainCallbacks = config.getCallbacks(webIDLFile=webIDLFile, workers=False) workerCallbacks = config.getCallbacks(webIDLFile=webIDLFile, @@ -8657,14 +8644,9 @@ class CGBindingRoot(CGThing): # here, because we have to generate these in order from least derived # to most derived so that class inheritance works out. We also have to # generate members before the dictionary that contains them. - cgthings.extend([CGDictionary(d, config.getDescriptorProvider(True)) - for d in - dependencySortObjects(workerDictionaries, - CGDictionary.getDictionaryDependencies, - lambda d: d.identifier.name)]) cgthings.extend([CGDictionary(d, config.getDescriptorProvider(False)) for d in - dependencySortObjects(mainDictionaries, + dependencySortObjects(dictionaries, CGDictionary.getDictionaryDependencies, lambda d: d.identifier.name)]) @@ -8701,7 +8683,7 @@ class CGBindingRoot(CGThing): curr = CGList([CGForwardDeclarations(config, descriptors, mainCallbacks, workerCallbacks, - mainDictionaries, workerDictionaries, + dictionaries, callbackDescriptors + jsImplemented), CGWrapper(CGGeneric("using namespace mozilla::dom;"), defineOnly=True), @@ -8710,7 +8692,7 @@ class CGBindingRoot(CGThing): # Add header includes. curr = CGHeaders(descriptors, - mainDictionaries + workerDictionaries, + dictionaries, mainCallbacks + workerCallbacks, callbackDescriptors, ['mozilla/dom/BindingDeclarations.h', @@ -8729,9 +8711,10 @@ class CGBindingRoot(CGThing): + (['mozilla/Preferences.h'] if requiresPreferences else []) + (['mozilla/dom/NonRefcountedDOMObject.h'] if hasOwnedDescriptors else []) + (['nsContentUtils.h'] if requiresContentUtils else []) - + (['nsCxPusher.h'] if mainDictionaries else []) + + (['nsCxPusher.h'] if dictionaries else []) + (['AccessCheck.h'] if hasChromeOnly else []) - + (['xpcprivate.h'] if isEventTarget else []), + + (['xpcprivate.h'] if isEventTarget else []) + + (['AtomList.h'] if requiresAtoms else []), prefix, curr, config, @@ -9045,8 +9028,7 @@ class CGNativeMember(ClassMethod): return declType, False, False if type.isDictionary(): - typeName = CGDictionary.makeDictionaryName( - type.inner, self.descriptorProvider.workers) + typeName = CGDictionary.makeDictionaryName(type.inner) return typeName, True, True if type.isDate(): @@ -10173,6 +10155,54 @@ class GlobalGenRoots(): call the appropriate define/declare method. """ + @staticmethod + def GeneratedAtomList(config): + # Atom enum + dictionaries = config.dictionaries + + structs = [] + + for dict in dictionaries: + dictMembers = dict.members + if len(dictMembers) == 0: + continue + + classMembers = [ClassMember(m.identifier.name + "_id", + "jsid", + visibility="public", + body="JSID_VOID") for m in dictMembers] + + structName = dict.identifier.name + "Atoms" + structs.append((structName, + CGWrapper(CGClass(structName, + bases=None, + isStruct=True, + members=classMembers), post='\n'))) + + structs.sort() + generatedStructs = [struct for (structName, struct) in structs] + structNames = [structName for (structName, struct) in structs] + + mainStruct = CGWrapper(CGClass("PerThreadAtomCache", + bases=[ClassBase(structName) for structName in structNames], + isStruct=True), post='\n') + + structs = CGList(generatedStructs + [mainStruct]) + + # Wrap all of that in our namespaces. + curr = CGNamespace.build(['mozilla', 'dom'], + CGWrapper(structs, pre='\n')) + curr = CGWrapper(curr, post='\n') + + # Add include guards. + curr = CGIncludeGuard('GeneratedAtomList', curr) + + # Add the auto-generated comment. + curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT) + + # Done. + return curr + @staticmethod def PrototypeList(config): diff --git a/dom/bindings/Configuration.py b/dom/bindings/Configuration.py index 7359b8364f8..45679cab282 100644 --- a/dom/bindings/Configuration.py +++ b/dom/bindings/Configuration.py @@ -99,8 +99,6 @@ class Configuration: item.setUserData("mainThread", True) if item in worker: item.setUserData("workers", True) - flagWorkerOrMainThread(self.dictionaries, mainDictionaries, - workerDictionaries); flagWorkerOrMainThread(self.callbacks, mainCallbacks, workerCallbacks) def getInterface(self, ifname): diff --git a/dom/bindings/GlobalGen.py b/dom/bindings/GlobalGen.py index f13d4250dcc..f3f02a4d1e4 100644 --- a/dom/bindings/GlobalGen.py +++ b/dom/bindings/GlobalGen.py @@ -63,6 +63,9 @@ def main(): cPickle.dump(config, resultsFile, -1) resultsFile.close() + # Generate the atom list. + generate_file(config, 'GeneratedAtomList', 'declare') + # Generate the prototype list. generate_file(config, 'PrototypeList', 'declare') diff --git a/dom/bindings/Makefile.in b/dom/bindings/Makefile.in index f48d7353894..0632c84c116 100644 --- a/dom/bindings/Makefile.in +++ b/dom/bindings/Makefile.in @@ -39,6 +39,7 @@ binding_cpp_files := $(subst .webidl,Binding.cpp,$(all_webidl_files)) binding_dependency_trackers := $(subst .webidl,Binding,$(all_webidl_files)) globalgen_targets := \ + GeneratedAtomList.h \ PrototypeList.h \ RegisterBindings.h \ RegisterBindings.cpp \ diff --git a/dom/bindings/moz.build b/dom/bindings/moz.build index d33971094ea..26ea86a0c41 100644 --- a/dom/bindings/moz.build +++ b/dom/bindings/moz.build @@ -11,6 +11,7 @@ EXPORTS.mozilla += [ ] EXPORTS.mozilla.dom += [ + 'AtomList.h', 'BindingDeclarations.h', 'BindingUtils.h', 'CallbackFunction.h', @@ -20,6 +21,7 @@ EXPORTS.mozilla.dom += [ 'DOMJSProxyHandler.h', 'Date.h', 'Errors.msg', + 'GeneratedAtomList.h', 'NonRefcountedDOMObject.h', 'Nullable.h', 'PrimitiveConversions.h', diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 3f6835969fd..c607d78721d 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -22,6 +22,7 @@ #include "jsdbgapi.h" #include "jsfriendapi.h" #include "mozilla/CycleCollectedJSRuntime.h" +#include "mozilla/dom/AtomList.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/EventTargetBinding.h" #include "mozilla/DebugOnly.h" @@ -746,6 +747,11 @@ CTypesActivityCallback(JSContext* aCx, } } +struct WorkerThreadRuntimePrivate : public PerThreadAtomCache +{ + WorkerPrivate* mWorkerPrivate; +}; + JSContext* CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime) { @@ -794,7 +800,10 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime) return nullptr; } - JS_SetRuntimePrivate(aRuntime, aWorkerPrivate); + auto rtPrivate = new WorkerThreadRuntimePrivate(); + memset(rtPrivate, 0, sizeof(WorkerThreadRuntimePrivate)); + rtPrivate->mWorkerPrivate = aWorkerPrivate; + JS_SetRuntimePrivate(aRuntime, rtPrivate); JS_SetErrorReporter(workerCx, ErrorReporter); @@ -837,6 +846,10 @@ public: ~WorkerJSRuntime() { + auto rtPrivate = static_cast(JS_GetRuntimePrivate(Runtime())); + delete rtPrivate; + JS_SetRuntimePrivate(Runtime(), nullptr); + // All JSContexts except mLastJSContext should be destroyed now. The // worker global will be unrooted and the shutdown cycle collection // should break all remaining cycles. Destroying mLastJSContext will run @@ -1100,6 +1113,13 @@ WorkerCrossThreadDispatcher::PostTask(WorkerTask* aTask) return true; } +WorkerPrivate* +GetWorkerPrivateFromContext(JSContext* aCx) +{ + NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!"); + return static_cast(JS_GetRuntimePrivate(JS_GetRuntime(aCx)))->mWorkerPrivate; +} + END_WORKERS_NAMESPACE // This is only touched on the main thread. Initialized in Init() below. diff --git a/dom/workers/TextEncoder.h b/dom/workers/TextEncoder.h index 7be9f933393..9ffb2dc5c44 100644 --- a/dom/workers/TextEncoder.h +++ b/dom/workers/TextEncoder.h @@ -40,7 +40,7 @@ public: Encode(JSContext* aCx, JS::Handle aObj, const nsAString& aString, - const TextEncodeOptionsWorkers& aOptions, + const TextEncodeOptions& aOptions, ErrorResult& aRv) { return TextEncoderBase::Encode(aCx, aObj, aString, aOptions.mStream, aRv); } diff --git a/dom/workers/URL.cpp b/dom/workers/URL.cpp index 935e7936116..6ff34f45139 100644 --- a/dom/workers/URL.cpp +++ b/dom/workers/URL.cpp @@ -117,7 +117,7 @@ private: public: CreateURLRunnable(WorkerPrivate* aWorkerPrivate, nsIDOMBlob* aBlob, - const mozilla::dom::objectURLOptionsWorkers& aOptions, + const mozilla::dom::objectURLOptions& aOptions, nsString& aURL) : URLRunnable(aWorkerPrivate), mBlob(aBlob), @@ -228,7 +228,7 @@ public: // static void URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject* aBlob, - const mozilla::dom::objectURLOptionsWorkers& aOptions, + const mozilla::dom::objectURLOptions& aOptions, nsString& aResult, mozilla::ErrorResult& aRv) { JSContext* cx = aGlobal.GetContext(); @@ -255,7 +255,7 @@ URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject* aBlob, // static void URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject& aBlob, - const mozilla::dom::objectURLOptionsWorkers& aOptions, + const mozilla::dom::objectURLOptions& aOptions, nsString& aResult, mozilla::ErrorResult& aRv) { return CreateObjectURL(aGlobal, &aBlob, aOptions, aResult, aRv); diff --git a/dom/workers/URL.h b/dom/workers/URL.h index 197d473eb25..64c54d30838 100644 --- a/dom/workers/URL.h +++ b/dom/workers/URL.h @@ -18,12 +18,12 @@ class URL : public EventTarget public: // Methods for WebIDL static void CreateObjectURL(const GlobalObject& aGlobal, - JSObject* aArg, const objectURLOptionsWorkers& aOptions, + JSObject* aArg, const objectURLOptions& aOptions, nsString& aResult, ErrorResult& aRv); static void CreateObjectURL(const GlobalObject& aGlobal, - JSObject& aArg, const objectURLOptionsWorkers& aOptions, + JSObject& aArg, const objectURLOptions& aOptions, nsString& aResult, ErrorResult& aRv); static void diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 0e15a723b5f..afd3733b66d 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -4400,13 +4400,6 @@ BEGIN_WORKERS_NAMESPACE // Force instantiation. template class WorkerPrivateParent; -WorkerPrivate* -GetWorkerPrivateFromContext(JSContext* aCx) -{ - NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!"); - return static_cast(JS_GetRuntimePrivate(JS_GetRuntime(aCx))); -} - JSStructuredCloneCallbacks* WorkerStructuredCloneCallbacks(bool aMainRuntime) { diff --git a/dom/workers/XMLHttpRequest.cpp b/dom/workers/XMLHttpRequest.cpp index 0f544793712..2a253eb5a3d 100644 --- a/dom/workers/XMLHttpRequest.cpp +++ b/dom/workers/XMLHttpRequest.cpp @@ -1460,7 +1460,7 @@ XMLHttpRequest::_finalize(JSFreeOp* aFop) // static XMLHttpRequest* XMLHttpRequest::Constructor(const GlobalObject& aGlobal, - const MozXMLHttpRequestParametersWorkers& aParams, + const MozXMLHttpRequestParameters& aParams, ErrorResult& aRv) { JSContext* cx = aGlobal.GetContext(); diff --git a/dom/workers/XMLHttpRequest.h b/dom/workers/XMLHttpRequest.h index ae9d5af0219..f8062a54785 100644 --- a/dom/workers/XMLHttpRequest.h +++ b/dom/workers/XMLHttpRequest.h @@ -76,7 +76,7 @@ public: static XMLHttpRequest* Constructor(const GlobalObject& aGlobal, - const MozXMLHttpRequestParametersWorkers& aParams, + const MozXMLHttpRequestParameters& aParams, ErrorResult& aRv); static XMLHttpRequest* @@ -84,7 +84,7 @@ public: ErrorResult& aRv) { // Pretend like someone passed null, so we can pick up the default values - MozXMLHttpRequestParametersWorkers params; + MozXMLHttpRequestParameters params; if (!params.Init(aGlobal.GetContext(), JS::NullHandleValue)) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 748d5a4da54..878ee370656 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -35,6 +35,7 @@ #include "jsfriendapi.h" #include "jsprf.h" #include "js/MemoryMetrics.h" +#include "mozilla/dom/AtomList.h" #include "mozilla/dom/DOMJSClass.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/Element.h" @@ -53,6 +54,7 @@ using namespace mozilla; using namespace xpc; using namespace JS; +using mozilla::dom::PerThreadAtomCache; /***************************************************************************/ @@ -1517,6 +1519,10 @@ XPCJSRuntime::~XPCJSRuntime() MOZ_ASSERT(!mScratchStrings[i].mInUse, "Uh, string wrapper still in use!"); } #endif + + auto rtPrivate = static_cast(JS_GetRuntimePrivate(Runtime())); + delete rtPrivate; + JS_SetRuntimePrivate(Runtime(), nullptr); } static void @@ -2898,6 +2904,10 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect) MOZ_ASSERT(Runtime()); JSRuntime* runtime = Runtime(); + auto rtPrivate = new PerThreadAtomCache(); + memset(rtPrivate, 0, sizeof(PerThreadAtomCache)); + JS_SetRuntimePrivate(runtime, rtPrivate); + // Unconstrain the runtime's threshold on nominal heap size, to avoid // triggering GC too often if operating continuously near an arbitrary // finite threshold (0xffffffff is infinity for uint32_t parameters).