Bug 1499865 - Make loadedModules and loadedComponents into array attributes. r=kmag
authorAndrew McCreight <continuation@gmail.com>
Tue, 23 Oct 2018 23:28:44 +0000
changeset 491027 2793e042041cecfd63b3a66f9930bf49c6ac3aa0
parent 491026 75f6d479fdaf74ea269f22c7f3e6ffe91133c726
child 491028 dce16565d2a8c37e885b9e105ffcb78a0e6458db
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewerskmag
bugs1499865
milestone65.0a1
Bug 1499865 - Make loadedModules and loadedComponents into array attributes. r=kmag Differential Revision: https://phabricator.services.mozilla.com/D9561
browser/base/content/test/performance/browser_startup_content.js
browser/components/tests/startupRecorder.js
js/xpconnect/idl/xpccomponents.idl
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/loader/mozJSComponentLoader.h
js/xpconnect/src/XPCComponents.cpp
toolkit/components/extensions/test/xpcshell/test_ext_startup_perf.js
--- a/browser/base/content/test/performance/browser_startup_content.js
+++ b/browser/base/content/test/performance/browser_startup_content.js
@@ -106,24 +106,24 @@ add_task(async function() {
   // Load a custom frame script to avoid using ContentTask which loads Task.jsm
   mm.loadFrameScript("data:text/javascript,(" + function() {
     /* eslint-env mozilla/frame-script */
     const Cm = Components.manager;
     Cm.QueryInterface(Ci.nsIServiceManager);
     ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
     let collectStacks = AppConstants.NIGHTLY_BUILD || AppConstants.DEBUG;
     let components = {};
-    for (let component of Cu.loadedComponents()) {
+    for (let component of Cu.loadedComponents) {
       /* Keep only the file name for components, as the path is an absolute file
          URL rather than a resource:// URL like for modules. */
       components[component.replace(/.*\//, "")] =
         collectStacks ? Cu.getComponentLoadStack(component) : "";
     }
     let modules = {};
-    for (let module of Cu.loadedModules()) {
+    for (let module of Cu.loadedModules) {
       modules[module] = collectStacks ? Cu.getModuleImportStack(module) : "";
     }
     let services = {};
     for (let contractID of Object.keys(Cc)) {
       try {
         if (Cm.isServiceInstantiatedByContractID(contractID, Ci.nsISupports)) {
           services[contractID] = "";
         }
--- a/browser/components/tests/startupRecorder.js
+++ b/browser/components/tests/startupRecorder.js
@@ -58,18 +58,18 @@ startupRecorder.prototype = {
 
   QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
 
   record(name) {
     if (!Services.prefs.getBoolPref("browser.startup.record", false))
       return;
 
     this.data.code[name] = {
-      components: Cu.loadedComponents(),
-      modules: Cu.loadedModules(),
+      components: Cu.loadedComponents,
+      modules: Cu.loadedModules,
       services: Object.keys(Cc).filter(c => {
         try {
           return Cm.isServiceInstantiatedByContractID(c, Ci.nsISupports);
         } catch (e) {
           return false;
         }
       }),
     };
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -734,23 +734,20 @@ interface nsIXPCComponents_Utils : nsISu
     nsILoadContext createLoadContext();
 
     /* Create a private loadcontext object. */
     nsILoadContext createPrivateLoadContext();
 
     /* Create a persistent property object. */
     nsIPersistentProperties createPersistentProperties();
 
-    // These functions are for startup testing purposes. They are not expected
+    // These attributes are for startup testing purposes. They are not expected
     // to be used for production code.
-    void loadedModules([optional] out unsigned long length,
-                       [retval, array, size_is(length)] out string aModules);
-
-    void loadedComponents([optional] out unsigned long length,
-                          [retval, array, size_is(length)] out string aComponents);
+    readonly attribute Array<ACString> loadedModules;
+    readonly attribute Array<ACString> loadedComponents;
 
     // These 2 functions will only return useful values if the
     // "browser.startup.record" preference was true at the time the JS file
     // was loaded.
     ACString getModuleImportStack(in AUTF8String aLocation);
     ACString getComponentLoadStack(in AUTF8String aLocation);
 };
 
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -1058,40 +1058,30 @@ mozJSComponentLoader::IsModuleLoaded(con
     rv = info.EnsureKey();
     NS_ENSURE_SUCCESS(rv, rv);
 
     *retval = !!mImports.Get(info.Key());
     return NS_OK;
 }
 
 void
-mozJSComponentLoader::LoadedModules(uint32_t* length,
-                                    char*** aModules)
+mozJSComponentLoader::GetLoadedModules(nsTArray<nsCString>& aLoadedModules)
 {
-    char** modules = new char*[mImports.Count()];
-    *length = mImports.Count();
-    *aModules = modules;
-
+    aLoadedModules.SetCapacity(mImports.Count());
     for (auto iter = mImports.Iter(); !iter.Done(); iter.Next()) {
-        *modules = NS_xstrdup(iter.Data()->location);
-        modules++;
+        aLoadedModules.AppendElement(iter.Data()->location);
     }
 }
 
 void
-mozJSComponentLoader::LoadedComponents(uint32_t* length,
-                                       char*** aComponents)
+mozJSComponentLoader::GetLoadedComponents(nsTArray<nsCString>& aLoadedComponents)
 {
-    char** comp = new char*[mModules.Count()];
-    *length = mModules.Count();
-    *aComponents = comp;
-
+    aLoadedComponents.SetCapacity(mModules.Count());
     for (auto iter = mModules.Iter(); !iter.Done(); iter.Next()) {
-        *comp = NS_xstrdup(iter.Data()->location);
-        comp++;
+        aLoadedComponents.AppendElement(iter.Data()->location);
     }
 }
 
 nsresult
 mozJSComponentLoader::GetModuleImportStack(const nsACString& aLocation,
                                            nsACString& retval)
 {
 #ifdef STARTUP_RECORDER_ENABLED
--- a/js/xpconnect/loader/mozJSComponentLoader.h
+++ b/js/xpconnect/loader/mozJSComponentLoader.h
@@ -44,18 +44,18 @@ namespace mozilla {
 class mozJSComponentLoader final : public nsIObserver
 {
  public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
 
     mozJSComponentLoader();
 
-    void LoadedModules(uint32_t* aLength, char*** aModules);
-    void LoadedComponents(uint32_t* aLength, char*** aComponents);
+    void GetLoadedModules(nsTArray<nsCString>& aLoadedModules);
+    void GetLoadedComponents(nsTArray<nsCString>& aLoadedComponents);
     nsresult GetModuleImportStack(const nsACString& aLocation, nsACString& aRetval);
     nsresult GetComponentLoadStack(const nsACString& aLocation, nsACString& aRetval);
 
     const mozilla::Module* LoadModule(mozilla::FileLocation& aFile);
 
     void FindTargetObject(JSContext* aCx,
                           JS::MutableHandleObject aTargetObject);
 
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3266,28 +3266,26 @@ nsXPCComponents_Utils::CreatePersistentP
 {
     NS_ENSURE_ARG_POINTER(aPersistentProperties);
     nsCOMPtr<nsIPersistentProperties> props = new nsPersistentProperties();
     props.forget(aPersistentProperties);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::LoadedModules(uint32_t* aLength,
-                                     char*** aModules)
+nsXPCComponents_Utils::GetLoadedModules(nsTArray<nsCString>& aLoadedModules)
 {
-    mozJSComponentLoader::Get()->LoadedModules(aLength, aModules);
+    mozJSComponentLoader::Get()->GetLoadedModules(aLoadedModules);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::LoadedComponents(uint32_t* aLength,
-                                        char*** aComponents)
+nsXPCComponents_Utils::GetLoadedComponents(nsTArray<nsCString>& aLoadedComponents)
 {
-    mozJSComponentLoader::Get()->LoadedComponents(aLength, aComponents);
+    mozJSComponentLoader::Get()->GetLoadedComponents(aLoadedComponents);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::GetModuleImportStack(const nsACString& aLocation,
                                             nsACString& aRetval)
 {
     return mozJSComponentLoader::Get()->GetModuleImportStack(aLocation, aRetval);
--- a/toolkit/components/extensions/test/xpcshell/test_ext_startup_perf.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_startup_perf.js
@@ -42,16 +42,16 @@ add_task(async function test_loaded_scri
   const loadedAPIs = Array.from(apiManager.modules.values())
                           .filter(m => m.loaded || m.asyncLoaded)
                           .map(m => m.namespaceName);
 
   deepEqual(loadedAPIs.sort(), STARTUP_APIS,
             "No extra APIs should be loaded at startup for a simple extension");
 
 
-  let loadedModules = Cu.loadedModules()
+  let loadedModules = Cu.loadedModules
                         .filter(url => url.startsWith("resource://gre/modules/Extension"));
 
   deepEqual(loadedModules.sort(), STARTUP_MODULES.sort(),
             "No extra extension modules should be loaded at startup for a simple extension");
 
   await extension.unload();
 });