[Pkg-mozext-commits] [greasemonkey] 01/55: avoid holding duplicate script source strings in memory
David Prévot
taffit at moszumanska.debian.org
Thu Oct 29 15:38:01 UTC 2015
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository greasemonkey.
commit 70a16c451cd56e827ae01956315e3fbd91280727
Author: The8472 <git at infinite-source.de>
Date: Tue Aug 18 20:57:43 2015 +0200
avoid holding duplicate script source strings in memory
old: strings sent via e10s message manager are duplicated and the
sandbox holds onto them as source code, this causes unnecessary memory
overhead.
new: load scripts from file:// URIs and use lazy getters for
scriptSource
---
modules/ipcscript.js | 19 ++---------
modules/miscapis.js | 7 ++++-
modules/sandbox.js | 84 ++++++++++++++++++++++++++++++++++++++++---------
modules/util.js | 1 +
modules/util/fileXHR.js | 15 +++++++++
5 files changed, 94 insertions(+), 32 deletions(-)
diff --git a/modules/ipcscript.js b/modules/ipcscript.js
index 896746e..99f530f 100644
--- a/modules/ipcscript.js
+++ b/modules/ipcscript.js
@@ -1,6 +1,5 @@
var EXPORTED_SYMBOLS = ['IPCScript'];
-Components.utils.import("chrome://greasemonkey-modules/content/extractMeta.js");
Components.utils.import("chrome://greasemonkey-modules/content/util.js");
function IPCScript(aScript, addonVersion) {
@@ -17,15 +16,13 @@ function IPCScript(aScript, addonVersion) {
this.namespace = aScript.namespace;
this.noframes = aScript.noframes;
this.runAt = aScript.runAt;
- this.textContent = aScript.textContent;
this.uuid = aScript.uuid;
this.version = aScript.version;
this.willUpdate = aScript.isRemoteUpdateAllowed();
this.requires = aScript.requires.map(function(req) {
return {
- 'fileURL': req.fileURL,
- 'textContent': req.textContent
+ 'fileURL': req.fileURL
};
});
@@ -33,21 +30,11 @@ function IPCScript(aScript, addonVersion) {
return {
'name': res.name,
'mimetype': res.mimetype,
- 'textContent': res.textContent,
'url': GM_util.getUriFromFile(res.file).spec
};
});
};
-IPCScript.prototype.__defineGetter__('metaStr',
-function IPCScript_getMetaStr() {
- if (!this._metaStr) {
- this._metaStr = extractMeta(this.textContent);
- }
-
- return this._metaStr;
-});
-
IPCScript.prototype.info = function() {
var resources = {};
for (var i = 0, r = null; r = this.resources[i]; i++) {
@@ -60,8 +47,6 @@ IPCScript.prototype.info = function() {
return {
'uuid': this.uuid,
'version': this.addonVersion,
- 'scriptMetaStr': this.metaStr,
- 'scriptSource': this.textContent,
'scriptWillUpdate': this.willUpdate,
'script': {
'description': this.description,
@@ -80,4 +65,4 @@ IPCScript.prototype.info = function() {
'version': this.version
}
};
-};
+};
\ No newline at end of file
diff --git a/modules/miscapis.js b/modules/miscapis.js
index a925edd..70f0e41 100644
--- a/modules/miscapis.js
+++ b/modules/miscapis.js
@@ -24,8 +24,13 @@ GM_Resources.prototype.getResourceURL = function(aScript, name) {
return ['greasemonkey-script:', aScript.uuid, '/', name].join('');
};
+
GM_Resources.prototype.getResourceText = function(name) {
- return this._getDep(name).textContent;
+ var dep = this._getDep(name)
+ if(dep.textContent !== undefined)
+ return dep.textContent;
+ // lazy resources in IPC scripts
+ return GM_util.fileXHR(dep.url, "text/plain");
};
GM_Resources.prototype._getDep = function(name) {
diff --git a/modules/sandbox.js b/modules/sandbox.js
index f2ed4e7..9a70b62 100644
--- a/modules/sandbox.js
+++ b/modules/sandbox.js
@@ -11,12 +11,15 @@ Cu.import("chrome://greasemonkey-modules/content/miscapis.js");
Cu.import("chrome://greasemonkey-modules/content/storageFront.js");
Cu.import("chrome://greasemonkey-modules/content/util.js");
Cu.import("chrome://greasemonkey-modules/content/xmlhttprequester.js");
+Cu.import("chrome://greasemonkey-modules/content/extractMeta.js");
var gStringBundle = Cc["@mozilla.org/intl/stringbundle;1"]
.getService(Ci.nsIStringBundleService)
.createBundle("chrome://greasemonkey/locale/greasemonkey.properties");
var gInvalidAccesskeyErrorStr = gStringBundle
.GetStringFromName('error.menu-invalid-accesskey');
+var subLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
+ .getService(Components.interfaces.mozIJSSubScriptLoader);
// Only a particular set of strings are allowed. See: http://goo.gl/ex2LJ
var gMaxJSVersion = "ECMAv5";
@@ -35,9 +38,8 @@ function createSandbox(aScript, aContentWin, aUrl, aFrameScope) {
'wantXrays': false,
});
// GM_info is always provided.
- // TODO: lazy getter? XPCOMUtils.defineLazyGetter
- Components.utils.evalInSandbox(
- 'const GM_info = ' + uneval(aScript.info()), contentSandbox);
+ injectGMInfo(aScript, contentSandbox);
+
// Alias unsafeWindow for compatibility.
Components.utils.evalInSandbox(
'const unsafeWindow = window;', contentSandbox);
@@ -124,19 +126,70 @@ function createSandbox(aScript, aContentWin, aUrl, aFrameScope) {
'contentStartRequest');
}
- // TODO: lazy getter?
- Components.utils.evalInSandbox(
- 'const GM_info = ' + uneval(aScript.info()), sandbox);
+ injectGMInfo(aScript, sandbox);
return sandbox;
}
+
+function injectGMInfo(aScript, sandbox) {
+ var rawInfo = aScript.info();
+ var scriptURL = aScript.fileURL;
+
+ // TODO: also delay top level clone via lazy getter? XPCOMUtils.defineLazyGetter
+ sandbox.GM_info = Cu.cloneInto(rawInfo, sandbox);
+
+ var waivedInfo = Components.utils.waiveXrays(sandbox.GM_info);
+
+ var fileCache = new Map();
+
+ // lazy getters for heavyweight strings that aren't sent down through IPC
+ Object.defineProperty(waivedInfo,
+ "scriptSource",
+ { get: Cu.exportFunction(
+ function() {
+ var content = fileCache.get("scriptSource");
+ if(content === undefined) {
+ content = GM_util.fileXHR(scriptURL, "application/javascript");
+ fileCache.set("scriptSource", content);
+ }
+ return content;
+ }, sandbox)
+ }
+ );
+
+ // meta depends on content, so we need a lazy one here too
+ Object.defineProperty(waivedInfo,
+ 'scriptMetaStr',
+ {get: Cu.exportFunction(
+ function() {
+ var meta = fileCache.get("meta");
+ if(meta === undefined) {
+ meta = extractMeta(this.scriptSource);
+ fileCache.set("meta", meta);
+ }
+ return meta;
+ }, sandbox)
+ }
+ );
+
+}
+
+function uriToString(uri) {
+ var channel = NetUtil.newChannel({ uri: NetUtil.newURI(uri, "UTF-8"), loadUsingSystemPrincipal: true});
+ var stream = channel.open();
+
+ var count = stream.available();
+ var data = NetUtil.readInputStreamToString(stream, count, { charset : "utf-8" });
+ return data;
+}
+
function runScriptInSandbox(script, sandbox) {
// Eval the code, with anonymous wrappers when/if appropriate.
- function evalWithWrapper(code, fileName) {
+ function evalWithWrapper(uri) {
try {
- Components.utils.evalInSandbox(code, sandbox, gMaxJSVersion, fileName, 1);
+ subLoader.loadSubScript(uri, sandbox, "UTF-8");
} catch (e) {
if ("return not in function" == e.message) {
// See #1592; we never anon wrap anymore, unless forced to by a return
@@ -147,8 +200,11 @@ function runScriptInSandbox(script, sandbox) {
fileName,
e.lineNumber
);
+
+ var code = GM_util.fileXHR(uri, "application/javascript");
+
Components.utils.evalInSandbox(
- '(function(){ '+code+'\n})()', sandbox, gMaxJSVersion, fileName, 1);
+ '(function(){ '+code+'\n})()', sandbox, gMaxJSVersion, uri, 1);
} else {
// Otherwise raise.
throw e;
@@ -157,12 +213,12 @@ function runScriptInSandbox(script, sandbox) {
}
// Eval the code, with a try/catch to report errors cleanly.
- function evalWithCatch(code, fileName) {
+ function evalWithCatch(uri) {
try {
- evalWithWrapper(code, fileName);
+ evalWithWrapper(uri);
} catch (e) {
// Log it properly.
- GM_util.logError(e, false, fileName, e.lineNumber);
+ GM_util.logError(e, false, e.fileName, e.lineNumber);
// Stop the script, in the case of requires, as if it was one big script.
return false;
}
@@ -170,9 +226,9 @@ function runScriptInSandbox(script, sandbox) {
}
for (var i = 0, require = null; require = script.requires[i]; i++) {
- if (!evalWithCatch(require.textContent, require.fileURL)) {
+ if (!evalWithCatch(require.fileURL)) {
return;
}
}
- evalWithCatch(script.textContent, script.fileURL);
+ evalWithCatch(script.fileURL);
}
diff --git a/modules/util.js b/modules/util.js
index 874f3ba..b53a4ff 100644
--- a/modules/util.js
+++ b/modules/util.js
@@ -27,6 +27,7 @@ XPCOMUtils.defineLazyModuleGetter(GM_util, 'alert', 'chrome://greasemonkey-modul
XPCOMUtils.defineLazyModuleGetter(GM_util, 'compareFirefoxVersion', 'chrome://greasemonkey-modules/content/util/compareFirefoxVersion.js');
XPCOMUtils.defineLazyModuleGetter(GM_util, 'emptyEl', 'chrome://greasemonkey-modules/content/util/emptyEl.js');
XPCOMUtils.defineLazyModuleGetter(GM_util, 'enqueueRemoveFile', 'chrome://greasemonkey-modules/content/util/enqueueRemoveFile.js');
+XPCOMUtils.defineLazyModuleGetter(GM_util, 'fileXHR', 'chrome://greasemonkey-modules/content/util/fileXHR.js');
XPCOMUtils.defineLazyModuleGetter(GM_util, 'findMessageManager', 'chrome://greasemonkey-modules/content/util/findMessageManager.js');
XPCOMUtils.defineLazyModuleGetter(GM_util, 'getBestLocaleMatch', 'chrome://greasemonkey-modules/content/util/getBestLocaleMatch.js');
XPCOMUtils.defineLazyModuleGetter(GM_util, 'getBinaryContents', 'chrome://greasemonkey-modules/content/util/getBinaryContents.js');
diff --git a/modules/util/fileXHR.js b/modules/util/fileXHR.js
new file mode 100644
index 0000000..ccc13d2
--- /dev/null
+++ b/modules/util/fileXHR.js
@@ -0,0 +1,15 @@
+'use strict';
+
+var EXPORTED_SYMBOLS = ['fileXHR'];
+
+Components.utils.importGlobalProperties(["XMLHttpRequest"]);
+
+// sync XHR. it's just meant to fetch file:// uris that aren't otherwise accessible in content
+// don't use it in the parent process or for web URLs
+function fileXHR(uri, mimetype) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("open", uri, false);
+ xhr.overrideMimeType(mimetype);
+ xhr.send(null);
+ return xhr.responseText;
+}
\ No newline at end of file
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/greasemonkey.git
More information about the Pkg-mozext-commits
mailing list