www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit 53a4d987b60fafcb253de16a0cf5073a4406a719
parent 5bfee27ab96123c6278474724bf4fd7aa6615363
Author: Simon Kornblith <simon@simonster.com>
Date:   Wed,  5 Jun 2013 18:12:52 -0400

Remove use of Components.utils.methodjit

It appears that this flag can no longer be set in new-ish Nightlies.
This patch switches code that used nsITimers with the
Components.utils.methodjit hack to use setTimeout on the hidden DOM
window instead, so that we still get the JIT. (See
https://bugzilla.mozilla.org/show_bug.cgi?id=776798)

This might also mean that callbacks from doGet etc. no longer get JITed.
At some point, we should test this with the JIT profiler.

Diffstat:
Mchrome/content/zotero/xpcom/http.js | 18------------------
Mchrome/content/zotero/xpcom/zotero.js | 65+++++++++++++++++------------------------------------------------
Mresource/q.js | 44+++-----------------------------------------
3 files changed, 20 insertions(+), 107 deletions(-)

diff --git a/chrome/content/zotero/xpcom/http.js b/chrome/content/zotero/xpcom/http.js @@ -246,10 +246,8 @@ Zotero.HTTP = new function() { // Don't cache GET requests xmlhttp.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE; - var useMethodjit = Components.utils.methodjit; /** @ignore */ xmlhttp.onreadystatechange = function() { - Components.utils.methodjit = useMethodjit; _stateChange(xmlhttp, onDone, responseCharset); }; @@ -334,10 +332,8 @@ Zotero.HTTP = new function() { xmlhttp.setRequestHeader(header, headers[header]); } - var useMethodjit = Components.utils.methodjit; /** @ignore */ xmlhttp.onreadystatechange = function() { - Components.utils.methodjit = useMethodjit; _stateChange(xmlhttp, onDone, responseCharset); }; @@ -398,10 +394,8 @@ Zotero.HTTP = new function() { // Don't cache HEAD requests xmlhttp.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE; - var useMethodjit = Components.utils.methodjit; /** @ignore */ xmlhttp.onreadystatechange = function() { - Components.utils.methodjit = useMethodjit; _stateChange(xmlhttp, onDone); }; @@ -437,10 +431,8 @@ Zotero.HTTP = new function() { xmlhttp.mozBackgroundRequest = true; xmlhttp.open('OPTIONS', uri.spec, true); - var useMethodjit = Components.utils.methodjit; /** @ignore */ xmlhttp.onreadystatechange = function() { - Components.utils.methodjit = useMethodjit; _stateChange(xmlhttp, callback); }; xmlhttp.send(null); @@ -479,10 +471,8 @@ Zotero.HTTP = new function() { xmlhttp.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE; - var useMethodjit = Components.utils.methodjit; /** @ignore */ xmlhttp.onreadystatechange = function() { - Components.utils.methodjit = useMethodjit; _stateChange(xmlhttp, function (xmlhttp) { Zotero.debug("Proxy auth request completed with status " + xmlhttp.status + ": " + xmlhttp.responseText); @@ -558,10 +548,8 @@ Zotero.HTTP = new function() { xmlhttp.setRequestHeader("Content-Type", 'text/xml; charset="utf-8"'); - var useMethodjit = Components.utils.methodjit; /** @ignore */ xmlhttp.onreadystatechange = function() { - Components.utils.methodjit = useMethodjit; _stateChange(xmlhttp, callback); }; @@ -594,10 +582,8 @@ Zotero.HTTP = new function() { // Prevent certificate/authentication dialogs from popping up xmlhttp.mozBackgroundRequest = true; xmlhttp.open('MKCOL', uri.spec, true); - var useMethodjit = Components.utils.methodjit; /** @ignore */ xmlhttp.onreadystatechange = function() { - Components.utils.methodjit = useMethodjit; _stateChange(xmlhttp, callback); }; xmlhttp.send(null); @@ -639,10 +625,8 @@ Zotero.HTTP = new function() { // with Content-Length: 0, which triggers a "no element found" error // in Firefox, so we override to text xmlhttp.overrideMimeType("text/plain"); - var useMethodjit = Components.utils.methodjit; /** @ignore */ xmlhttp.onreadystatechange = function() { - Components.utils.methodjit = useMethodjit; _stateChange(xmlhttp, callback); }; xmlhttp.send(body); @@ -678,10 +662,8 @@ Zotero.HTTP = new function() { // Firefox 3 throws a "no element found" error even with a // 204 ("No Content") response, so we override to text xmlhttp.overrideMimeType("text/plain"); - var useMethodjit = Components.utils.methodjit; /** @ignore */ xmlhttp.onreadystatechange = function() { - Components.utils.methodjit = useMethodjit; _stateChange(xmlhttp, callback); }; xmlhttp.send(null); diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js @@ -187,27 +187,19 @@ Components.utils.import("resource://gre/modules/Services.jsm"); var _waitingForDBLock = false; /** - * Maintains nsITimers to be used when Zotero.wait() completes (to reduce performance penalty - * of initializing new objects) - */ - var _waitTimers = []; - - /** * Maintains nsITimerCallbacks to be used when Zotero.wait() completes */ var _waitTimerCallbacks = []; - /** - * Maintains running nsITimers in global scope, so that they don't disappear randomly - */ - var _runningTimers = []; - // Errors that were in the console at startup var _startupErrors = []; // Number of errors to maintain in the recent errors buffer const ERROR_BUFFER_SIZE = 25; // A rolling buffer of the last ERROR_BUFFER_SIZE errors var _recentErrors = []; + + // The hidden DOM window + var _hiddenDOMWindow; /** * Initialize the extension @@ -247,14 +239,12 @@ Components.utils.import("resource://gre/modules/Services.jsm"); } // OS platform - var win = Components.classes["@mozilla.org/appshell/appShellService;1"] - .getService(Components.interfaces.nsIAppShellService) - .hiddenDOMWindow; - this.platform = win.navigator.platform; + _hiddenDOMWindow = Services.appShell.hiddenDOMWindow; + this.platform = _hiddenDOMWindow.navigator.platform; this.isMac = (this.platform.substr(0, 3) == "Mac"); this.isWin = (this.platform.substr(0, 3) == "Win"); this.isLinux = (this.platform.substr(0, 5) == "Linux"); - this.oscpu = win.navigator.oscpu; + this.oscpu = _hiddenDOMWindow.navigator.oscpu; // Browser Zotero.browser = "g"; @@ -1521,10 +1511,9 @@ Components.utils.import("resource://gre/modules/Services.jsm"); _waiting--; // requeue nsITimerCallbacks that came up during Zotero.wait() but couldn't execute - for(var i in _waitTimers) { - _waitTimers[i].initWithCallback(_waitTimerCallbacks[i], 0, Components.interfaces.nsITimer.TYPE_ONE_SHOT); + for(var i=0; i<_waitTimerCallbacks.length; i++) { + Zotero.setTimeout(_waitTimerCallbacks[i], 0); } - _waitTimers = []; _waitTimerCallbacks = []; //Zotero.debug("Waited " + cycles + " cycles"); @@ -1540,13 +1529,8 @@ Components.utils.import("resource://gre/modules/Services.jsm"); this.pumpGenerator = function(generator, ms, errorHandler, doneHandler) { _waiting++; - var timer = Components.classes["@mozilla.org/timer;1"]. - createInstance(Components.interfaces.nsITimer), - yielded, - useJIT = Components.utils.methodjit; - var timerCallback = {"notify":function() { - Components.utils.methodjit = useJIT; - + var yielded; + var interval = _hiddenDOMWindow.setInterval(function() { var err = false; _waiting--; try { @@ -1560,14 +1544,12 @@ Components.utils.import("resource://gre/modules/Services.jsm"); err = e; } - timer.cancel(); - _runningTimers.splice(_runningTimers.indexOf(timer), 1); + _hiddenDOMWindow.clearInterval(interval); // requeue nsITimerCallbacks that came up during generator pumping but couldn't execute - for(var i in _waitTimers) { - _waitTimers[i].initWithCallback(_waitTimerCallbacks[i], 0, Components.interfaces.nsITimer.TYPE_ONE_SHOT); + for(var i=0; i<_waitTimerCallbacks.length; i++) { + Zotero.setTimeout(_waitTimerCallbacks[i], 0); } - _waitTimers = []; _waitTimerCallbacks = []; if(err) { @@ -1579,10 +1561,7 @@ Components.utils.import("resource://gre/modules/Services.jsm"); } else if(doneHandler) { doneHandler(yielded); } - }} - timer.initWithCallback(timerCallback, ms ? ms : 0, Components.interfaces.nsITimer.TYPE_REPEATING_SLACK); - // add timer to global scope so that it doesn't get garbage collected before it completes - _runningTimers.push(timer); + }, 0); }; /** @@ -1606,27 +1585,17 @@ Components.utils.import("resource://gre/modules/Services.jsm"); * is executing */ this.setTimeout = function(func, ms, runWhenWaiting) { - var timer = Components.classes["@mozilla.org/timer;1"]. - createInstance(Components.interfaces.nsITimer), - useJIT = Components.utils.methodjit; - var timerCallback = {"notify":function() { - Components.utils.methodjit = useJIT; - + var timerCallback = function() { if(_waiting && !runWhenWaiting) { // if our callback gets called during Zotero.wait(), queue it to be set again // when Zotero.wait() completes - _waitTimers.push(timer); _waitTimerCallbacks.push(timerCallback); } else { // execute callback function func(); - // remove timer from global scope, so it can be garbage collected - _runningTimers.splice(_runningTimers.indexOf(timer), 1); } - }} - timer.initWithCallback(timerCallback, ms, Components.interfaces.nsITimer.TYPE_ONE_SHOT); - // add timer to global scope so that it doesn't get garbage collected before it completes - _runningTimers.push(timer); + }; + _hiddenDOMWindow.setTimeout(timerCallback, ms); } /** diff --git a/resource/q.js b/resource/q.js @@ -58,49 +58,11 @@ // Mozilla JSM } else if (~String(this).indexOf('BackstagePass')) { EXPORTED_SYMBOLS = ["Q"]; + Components.utils.import("resource://gre/modules/Services.jsm"); + var hiddenDOMWindow = Services.appShell.hiddenDOMWindow; // Q expects an implementation of setTimeout - setTimeout = new function() { - // We need to maintain references to running nsITimers. Otherwise, they can - // get garbage collected before they fire. - var _runningTimers = []; - - return function setTimeout(func, ms) { - var useMethodjit = Components.utils.methodjit, - timer = Components.classes["@mozilla.org/timer;1"]. - createInstance(Components.interfaces.nsITimer); - timer.initWithCallback({"notify":function() { - Components.utils.methodjit = useMethodjit; - - // Remove timer from array so it can be garbage collected - _runningTimers.splice(_runningTimers.indexOf(timer), 1); - - // Execute callback function - try { - func(); - } catch(err) { - // Rethrow errors that occur so that they appear in the error - // console with the appropriate name and line numbers. While the - // the errors appear without this, the line numbers get eaten. - var scriptError = Components.classes["@mozilla.org/scripterror;1"] - .createInstance(Components.interfaces.nsIScriptError); - scriptError.init( - err.message || err.toString(), - err.fileName || err.filename || null, - null, - err.lineNumber || null, - null, - scriptError.errorFlag, - 'component javascript' - ); - Components.classes["@mozilla.org/consoleservice;1"] - .getService(Components.interfaces.nsIConsoleService) - .logMessage(scriptError); - } - }}, ms, Components.interfaces.nsITimer.TYPE_ONE_SHOT); - _runningTimers.push(timer); - } - }; + setTimeout = hiddenDOMWindow.setTimeout; Q = definition(); // <script>