Revert "Remove use of Components.utils.methodjit"

This reverts commit 53a4d987b6.
This commit is contained in:
Simon Kornblith 2013-06-06 19:31:09 -04:00
parent 53a4d987b6
commit 1cee348f51
3 changed files with 107 additions and 20 deletions

View file

@ -246,8 +246,10 @@ Zotero.HTTP = new function() {
// Don't cache GET requests // Don't cache GET requests
xmlhttp.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE; xmlhttp.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
var useMethodjit = Components.utils.methodjit;
/** @ignore */ /** @ignore */
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
Components.utils.methodjit = useMethodjit;
_stateChange(xmlhttp, onDone, responseCharset); _stateChange(xmlhttp, onDone, responseCharset);
}; };
@ -332,8 +334,10 @@ Zotero.HTTP = new function() {
xmlhttp.setRequestHeader(header, headers[header]); xmlhttp.setRequestHeader(header, headers[header]);
} }
var useMethodjit = Components.utils.methodjit;
/** @ignore */ /** @ignore */
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
Components.utils.methodjit = useMethodjit;
_stateChange(xmlhttp, onDone, responseCharset); _stateChange(xmlhttp, onDone, responseCharset);
}; };
@ -394,8 +398,10 @@ Zotero.HTTP = new function() {
// Don't cache HEAD requests // Don't cache HEAD requests
xmlhttp.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE; xmlhttp.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
var useMethodjit = Components.utils.methodjit;
/** @ignore */ /** @ignore */
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
Components.utils.methodjit = useMethodjit;
_stateChange(xmlhttp, onDone); _stateChange(xmlhttp, onDone);
}; };
@ -431,8 +437,10 @@ Zotero.HTTP = new function() {
xmlhttp.mozBackgroundRequest = true; xmlhttp.mozBackgroundRequest = true;
xmlhttp.open('OPTIONS', uri.spec, true); xmlhttp.open('OPTIONS', uri.spec, true);
var useMethodjit = Components.utils.methodjit;
/** @ignore */ /** @ignore */
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
Components.utils.methodjit = useMethodjit;
_stateChange(xmlhttp, callback); _stateChange(xmlhttp, callback);
}; };
xmlhttp.send(null); xmlhttp.send(null);
@ -471,8 +479,10 @@ Zotero.HTTP = new function() {
xmlhttp.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE; xmlhttp.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
var useMethodjit = Components.utils.methodjit;
/** @ignore */ /** @ignore */
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
Components.utils.methodjit = useMethodjit;
_stateChange(xmlhttp, function (xmlhttp) { _stateChange(xmlhttp, function (xmlhttp) {
Zotero.debug("Proxy auth request completed with status " Zotero.debug("Proxy auth request completed with status "
+ xmlhttp.status + ": " + xmlhttp.responseText); + xmlhttp.status + ": " + xmlhttp.responseText);
@ -548,8 +558,10 @@ Zotero.HTTP = new function() {
xmlhttp.setRequestHeader("Content-Type", 'text/xml; charset="utf-8"'); xmlhttp.setRequestHeader("Content-Type", 'text/xml; charset="utf-8"');
var useMethodjit = Components.utils.methodjit;
/** @ignore */ /** @ignore */
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
Components.utils.methodjit = useMethodjit;
_stateChange(xmlhttp, callback); _stateChange(xmlhttp, callback);
}; };
@ -582,8 +594,10 @@ Zotero.HTTP = new function() {
// Prevent certificate/authentication dialogs from popping up // Prevent certificate/authentication dialogs from popping up
xmlhttp.mozBackgroundRequest = true; xmlhttp.mozBackgroundRequest = true;
xmlhttp.open('MKCOL', uri.spec, true); xmlhttp.open('MKCOL', uri.spec, true);
var useMethodjit = Components.utils.methodjit;
/** @ignore */ /** @ignore */
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
Components.utils.methodjit = useMethodjit;
_stateChange(xmlhttp, callback); _stateChange(xmlhttp, callback);
}; };
xmlhttp.send(null); xmlhttp.send(null);
@ -625,8 +639,10 @@ Zotero.HTTP = new function() {
// with Content-Length: 0, which triggers a "no element found" error // with Content-Length: 0, which triggers a "no element found" error
// in Firefox, so we override to text // in Firefox, so we override to text
xmlhttp.overrideMimeType("text/plain"); xmlhttp.overrideMimeType("text/plain");
var useMethodjit = Components.utils.methodjit;
/** @ignore */ /** @ignore */
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
Components.utils.methodjit = useMethodjit;
_stateChange(xmlhttp, callback); _stateChange(xmlhttp, callback);
}; };
xmlhttp.send(body); xmlhttp.send(body);
@ -662,8 +678,10 @@ Zotero.HTTP = new function() {
// Firefox 3 throws a "no element found" error even with a // Firefox 3 throws a "no element found" error even with a
// 204 ("No Content") response, so we override to text // 204 ("No Content") response, so we override to text
xmlhttp.overrideMimeType("text/plain"); xmlhttp.overrideMimeType("text/plain");
var useMethodjit = Components.utils.methodjit;
/** @ignore */ /** @ignore */
xmlhttp.onreadystatechange = function() { xmlhttp.onreadystatechange = function() {
Components.utils.methodjit = useMethodjit;
_stateChange(xmlhttp, callback); _stateChange(xmlhttp, callback);
}; };
xmlhttp.send(null); xmlhttp.send(null);

View file

@ -186,11 +186,22 @@ Components.utils.import("resource://gre/modules/Services.jsm");
// whether we are waiting for another Zotero process to release its DB lock // whether we are waiting for another Zotero process to release its DB lock
var _waitingForDBLock = false; 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 * Maintains nsITimerCallbacks to be used when Zotero.wait() completes
*/ */
var _waitTimerCallbacks = []; 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 // Errors that were in the console at startup
var _startupErrors = []; var _startupErrors = [];
// Number of errors to maintain in the recent errors buffer // Number of errors to maintain in the recent errors buffer
@ -198,9 +209,6 @@ Components.utils.import("resource://gre/modules/Services.jsm");
// A rolling buffer of the last ERROR_BUFFER_SIZE errors // A rolling buffer of the last ERROR_BUFFER_SIZE errors
var _recentErrors = []; var _recentErrors = [];
// The hidden DOM window
var _hiddenDOMWindow;
/** /**
* Initialize the extension * Initialize the extension
*/ */
@ -239,12 +247,14 @@ Components.utils.import("resource://gre/modules/Services.jsm");
} }
// OS platform // OS platform
_hiddenDOMWindow = Services.appShell.hiddenDOMWindow; var win = Components.classes["@mozilla.org/appshell/appShellService;1"]
this.platform = _hiddenDOMWindow.navigator.platform; .getService(Components.interfaces.nsIAppShellService)
.hiddenDOMWindow;
this.platform = win.navigator.platform;
this.isMac = (this.platform.substr(0, 3) == "Mac"); this.isMac = (this.platform.substr(0, 3) == "Mac");
this.isWin = (this.platform.substr(0, 3) == "Win"); this.isWin = (this.platform.substr(0, 3) == "Win");
this.isLinux = (this.platform.substr(0, 5) == "Linux"); this.isLinux = (this.platform.substr(0, 5) == "Linux");
this.oscpu = _hiddenDOMWindow.navigator.oscpu; this.oscpu = win.navigator.oscpu;
// Browser // Browser
Zotero.browser = "g"; Zotero.browser = "g";
@ -1511,9 +1521,10 @@ Components.utils.import("resource://gre/modules/Services.jsm");
_waiting--; _waiting--;
// requeue nsITimerCallbacks that came up during Zotero.wait() but couldn't execute // requeue nsITimerCallbacks that came up during Zotero.wait() but couldn't execute
for(var i=0; i<_waitTimerCallbacks.length; i++) { for(var i in _waitTimers) {
Zotero.setTimeout(_waitTimerCallbacks[i], 0); _waitTimers[i].initWithCallback(_waitTimerCallbacks[i], 0, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
} }
_waitTimers = [];
_waitTimerCallbacks = []; _waitTimerCallbacks = [];
//Zotero.debug("Waited " + cycles + " cycles"); //Zotero.debug("Waited " + cycles + " cycles");
@ -1529,8 +1540,13 @@ Components.utils.import("resource://gre/modules/Services.jsm");
this.pumpGenerator = function(generator, ms, errorHandler, doneHandler) { this.pumpGenerator = function(generator, ms, errorHandler, doneHandler) {
_waiting++; _waiting++;
var yielded; var timer = Components.classes["@mozilla.org/timer;1"].
var interval = _hiddenDOMWindow.setInterval(function() { createInstance(Components.interfaces.nsITimer),
yielded,
useJIT = Components.utils.methodjit;
var timerCallback = {"notify":function() {
Components.utils.methodjit = useJIT;
var err = false; var err = false;
_waiting--; _waiting--;
try { try {
@ -1544,12 +1560,14 @@ Components.utils.import("resource://gre/modules/Services.jsm");
err = e; err = e;
} }
_hiddenDOMWindow.clearInterval(interval); timer.cancel();
_runningTimers.splice(_runningTimers.indexOf(timer), 1);
// requeue nsITimerCallbacks that came up during generator pumping but couldn't execute // requeue nsITimerCallbacks that came up during generator pumping but couldn't execute
for(var i=0; i<_waitTimerCallbacks.length; i++) { for(var i in _waitTimers) {
Zotero.setTimeout(_waitTimerCallbacks[i], 0); _waitTimers[i].initWithCallback(_waitTimerCallbacks[i], 0, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
} }
_waitTimers = [];
_waitTimerCallbacks = []; _waitTimerCallbacks = [];
if(err) { if(err) {
@ -1561,7 +1579,10 @@ Components.utils.import("resource://gre/modules/Services.jsm");
} else if(doneHandler) { } else if(doneHandler) {
doneHandler(yielded); doneHandler(yielded);
} }
}, 0); }}
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);
}; };
/** /**
@ -1585,17 +1606,27 @@ Components.utils.import("resource://gre/modules/Services.jsm");
* is executing * is executing
*/ */
this.setTimeout = function(func, ms, runWhenWaiting) { this.setTimeout = function(func, ms, runWhenWaiting) {
var timerCallback = function() { var timer = Components.classes["@mozilla.org/timer;1"].
createInstance(Components.interfaces.nsITimer),
useJIT = Components.utils.methodjit;
var timerCallback = {"notify":function() {
Components.utils.methodjit = useJIT;
if(_waiting && !runWhenWaiting) { if(_waiting && !runWhenWaiting) {
// if our callback gets called during Zotero.wait(), queue it to be set again // if our callback gets called during Zotero.wait(), queue it to be set again
// when Zotero.wait() completes // when Zotero.wait() completes
_waitTimers.push(timer);
_waitTimerCallbacks.push(timerCallback); _waitTimerCallbacks.push(timerCallback);
} else { } else {
// execute callback function // execute callback function
func(); func();
// remove timer from global scope, so it can be garbage collected
_runningTimers.splice(_runningTimers.indexOf(timer), 1);
} }
}; }}
_hiddenDOMWindow.setTimeout(timerCallback, ms); 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);
} }
/** /**

View file

@ -58,11 +58,49 @@
// Mozilla JSM // Mozilla JSM
} else if (~String(this).indexOf('BackstagePass')) { } else if (~String(this).indexOf('BackstagePass')) {
EXPORTED_SYMBOLS = ["Q"]; EXPORTED_SYMBOLS = ["Q"];
Components.utils.import("resource://gre/modules/Services.jsm");
var hiddenDOMWindow = Services.appShell.hiddenDOMWindow;
// Q expects an implementation of setTimeout // Q expects an implementation of setTimeout
setTimeout = hiddenDOMWindow.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);
}
};
Q = definition(); Q = definition();
// <script> // <script>