зеркало из https://github.com/mozilla/pluotsorbet.git
Merge commit '6a01c526c2e7f616407a7a7ee15ee348ad9fedec' into jitopt3
Conflicts: runtime.ts
This commit is contained in:
Коммит
3c2833b59a
5
Makefile
5
Makefile
|
@ -3,6 +3,7 @@ BASIC_SRCS=$(shell find . -maxdepth 2 -name "*.ts" -not -path "./build/*")
|
|||
JIT_SRCS=$(shell find jit -name "*.ts" -not -path "./build/*")
|
||||
SHUMWAY_SRCS=$(shell find shumway -name "*.ts")
|
||||
RELEASE ?= 0
|
||||
VERSION ?=$(shell date +%s)
|
||||
|
||||
all: config-build java jasmin tests j2me shumway aot
|
||||
|
||||
|
@ -51,7 +52,9 @@ build/shumway.js: $(SHUMWAY_SRCS)
|
|||
node tools/tsc.js --sourcemap --target ES5 shumway/references.ts --out build/shumway.js
|
||||
|
||||
config-build:
|
||||
echo "config.release = ${RELEASE};" > config/build.js
|
||||
echo "// generated, build-specific configuration" > config/build.js
|
||||
echo "config.release = ${RELEASE};" >> config/build.js
|
||||
echo "config.version = \"${VERSION}\";" >> config/build.js
|
||||
|
||||
tests/tests.jar: tests
|
||||
tests:
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
// IndexedDB-getAll-shim v1.1 - https://github.com/jdscheff/IndexedDB-getAll-shim
|
||||
//
|
||||
// Copyright (c) 2012 Jeremy Scheff
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var Event, IDBIndex, IDBObjectStore, IDBRequest, getAll;
|
||||
|
||||
IDBObjectStore = window.IDBObjectStore || window.webkitIDBObjectStore || window.mozIDBObjectStore || window.msIDBObjectStore;
|
||||
IDBIndex = window.IDBIndex || window.webkitIDBIndex || window.mozIDBIndex || window.msIDBIndex;
|
||||
|
||||
if (typeof IDBObjectStore === "undefined" || typeof IDBIndex === "undefined" || (IDBObjectStore.prototype.getAll !== undefined && IDBIndex.prototype.getAll !== undefined)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IDBObjectStore.prototype.mozGetAll !== undefined && IDBIndex.prototype.mozGetAll !== undefined) {
|
||||
IDBObjectStore.prototype.getAll = IDBObjectStore.prototype.mozGetAll;
|
||||
IDBIndex.prototype.getAll = IDBIndex.prototype.mozGetAll;
|
||||
return;
|
||||
}
|
||||
|
||||
// https://github.com/axemclion/IndexedDBShim/blob/gh-pages/src/IDBRequest.js
|
||||
IDBRequest = function () {
|
||||
this.onsuccess = null;
|
||||
this.readyState = "pending";
|
||||
};
|
||||
// https://github.com/axemclion/IndexedDBShim/blob/gh-pages/src/Event.js
|
||||
Event = function (type, debug) {
|
||||
return {
|
||||
"type": type,
|
||||
debug: debug,
|
||||
bubbles: false,
|
||||
cancelable: false,
|
||||
eventPhase: 0,
|
||||
timeStamp: new Date()
|
||||
};
|
||||
};
|
||||
|
||||
getAll = function (key) {
|
||||
var request, result;
|
||||
|
||||
key = key !== undefined ? key : null;
|
||||
|
||||
request = new IDBRequest();
|
||||
result = [];
|
||||
|
||||
// this is either an IDBObjectStore or an IDBIndex, depending on the context.
|
||||
this.openCursor(key).onsuccess = function (event) {
|
||||
var cursor, e;
|
||||
|
||||
cursor = event.target.result;
|
||||
if (cursor) {
|
||||
result.push(cursor.value);
|
||||
cursor.continue();
|
||||
} else {
|
||||
if (typeof request.onsuccess === "function") {
|
||||
e = new Event("success");
|
||||
e.target = {
|
||||
readyState: "done",
|
||||
result: result
|
||||
};
|
||||
request.result = result;
|
||||
request.onsuccess(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return request;
|
||||
};
|
||||
|
||||
IDBObjectStore.prototype.getAll = getAll;
|
||||
IDBIndex.prototype.getAll = getAll;
|
||||
}());
|
|
@ -4,7 +4,7 @@
|
|||
'use strict';
|
||||
|
||||
var CompiledMethodCache = (function() {
|
||||
var DEBUG = true;
|
||||
var DEBUG = false;
|
||||
var DATABASE = "CompiledMethodCache";
|
||||
var VERSION = 1;
|
||||
var OBJECT_STORE = "methods";
|
||||
|
@ -25,13 +25,13 @@ var CompiledMethodCache = (function() {
|
|||
};
|
||||
|
||||
function restore() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
return openDatabase.then(new Promise(function(resolve, reject) {
|
||||
DEBUG && debug("restore");
|
||||
|
||||
var then = performance.now();
|
||||
var transaction = database.transaction(OBJECT_STORE, "readonly");
|
||||
var objectStore = transaction.objectStore(OBJECT_STORE);
|
||||
|
||||
var request = objectStore.mozGetAll();
|
||||
var request = objectStore.getAll();
|
||||
|
||||
request.onerror = function() {
|
||||
console.error("Error restoring: " + request.error.name);
|
||||
|
@ -39,15 +39,39 @@ var CompiledMethodCache = (function() {
|
|||
};
|
||||
|
||||
request.onsuccess = function() {
|
||||
for (var i = 0; i < request.result.length; i++) {
|
||||
var count = request.result.length;
|
||||
for (var i = 0; i < count; i++) {
|
||||
cache.set(request.result[i][KEY_PATH], request.result[i]);
|
||||
}
|
||||
DEBUG && debug("restore complete: " + count + " methods in " + (performance.now() - then) + "ms");
|
||||
resolve();
|
||||
};
|
||||
}));
|
||||
}
|
||||
|
||||
function clear() {
|
||||
return openDatabase.then(new Promise(function(resolve, reject) {
|
||||
DEBUG && debug("clear");
|
||||
|
||||
// First clear the in-memory cache, in case we've already restored it
|
||||
// from the database.
|
||||
cache.clear();
|
||||
|
||||
var then = performance.now();
|
||||
var transaction = database.transaction(OBJECT_STORE, "readwrite");
|
||||
var objectStore = transaction.objectStore(OBJECT_STORE);
|
||||
var request = objectStore.clear();
|
||||
|
||||
request.onerror = function() {
|
||||
console.error("Error clearing: " + request.error.name);
|
||||
reject(request.error.name);
|
||||
};
|
||||
|
||||
transaction.oncomplete = function() {
|
||||
DEBUG && debug("restore complete");
|
||||
request.onsuccess = function() {
|
||||
DEBUG && debug("clear complete in " + (performance.now() - then) + "ms");
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
var openDatabase = new Promise(function(resolve, reject) {
|
||||
|
@ -77,8 +101,19 @@ var CompiledMethodCache = (function() {
|
|||
|
||||
request.onsuccess = function() {
|
||||
DEBUG && debug("open success");
|
||||
|
||||
database = request.result;
|
||||
restore();
|
||||
|
||||
var oldVersion = localStorage.getItem("lastAppVersion");
|
||||
if (config.version === oldVersion) {
|
||||
DEBUG && debug("app version " + config.version + " === " + oldVersion + "; restore");
|
||||
restore().catch(console.error.bind(console));
|
||||
} else {
|
||||
DEBUG && debug("app version " + config.version + " !== " + oldVersion + "; clear");
|
||||
clear().catch(console.error.bind(console));
|
||||
localStorage.setItem("lastAppVersion", config.version);
|
||||
}
|
||||
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
|
@ -104,38 +139,9 @@ var CompiledMethodCache = (function() {
|
|||
};
|
||||
|
||||
request.onsuccess = function() {
|
||||
resolve();
|
||||
};
|
||||
|
||||
transaction.oncomplete = function() {
|
||||
DEBUG && debug("put " + obj[KEY_PATH] + " complete");
|
||||
};
|
||||
}));
|
||||
}
|
||||
|
||||
function clear() {
|
||||
DEBUG && debug("clear");
|
||||
|
||||
cache.clear();
|
||||
|
||||
return openDatabase.then(new Promise(function(resolve, reject) {
|
||||
var transaction = database.transaction(OBJECT_STORE, "readwrite");
|
||||
var objectStore = transaction.objectStore(OBJECT_STORE);
|
||||
|
||||
var request = objectStore.clear();
|
||||
|
||||
request.onerror = function() {
|
||||
console.error("Error clearing store: " + request.error.name);
|
||||
reject(request.error.name);
|
||||
};
|
||||
|
||||
request.onsuccess = function() {
|
||||
resolve();
|
||||
};
|
||||
|
||||
transaction.oncomplete = function() {
|
||||
DEBUG && debug("clear complete");
|
||||
};
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<script type="text/javascript" src="native.js" defer></script>
|
||||
<script type="text/javascript" src="string.js" defer></script>
|
||||
<script type="text/javascript" src="instrument.js" defer></script>
|
||||
<script type="text/javascript" src="libs/IndexedDB-getAll-shim.js" defer></script>
|
||||
<script type="text/javascript" src="libs/compiled-method-cache.js" defer></script>
|
||||
<script type="text/javascript" src="libs/load.js" defer></script>
|
||||
<script type="text/javascript" src="libs/zipfile.js" defer></script>
|
||||
|
@ -117,12 +118,12 @@
|
|||
</section>
|
||||
<section>
|
||||
<button id="deleteDatabase">Delete Database</button>
|
||||
<button id="clearMethodCache">Clear Code Cache</button>
|
||||
<button id="exportstorage">Export storage</button>
|
||||
<div>Import storage:</div>
|
||||
<input type="file" id="importstoragefile">
|
||||
<input type="text" id="importstorageurl" placeholder="URL to FS backup">
|
||||
<button id="importstorage">Import</button>
|
||||
<button id="clearCompiledMethodCache">Clear Compiled Method Cache</button>
|
||||
<button id="trace">Trace: OFF</button>
|
||||
<button id="printAllExceptions">Print all exceptions: OFF</button>
|
||||
<button id="profile">Profile: OFF</button>
|
||||
|
|
11
main.js
11
main.js
|
@ -175,6 +175,11 @@ function toggle(button) {
|
|||
var bigBang = 0;
|
||||
|
||||
function start() {
|
||||
if (MIDP.manifest["MIDlet-Version"] && MIDP.manifest["MIDlet-Version"] !== localStorage.getItem("lastMidletVersion")) {
|
||||
CompiledMethodCache.clear().catch(console.error.bind(console));
|
||||
localStorage.setItem("lastMidletVersion", MIDP.manifest["MIDlet-Version"]);
|
||||
}
|
||||
|
||||
J2ME.Context.setWriters(new J2ME.IndentingWriter());
|
||||
CLASSES.initializeBuiltinClasses();
|
||||
profiler && profiler.start(2000, false);
|
||||
|
@ -205,9 +210,6 @@ window.onload = function() {
|
|||
document.getElementById("deleteDatabase").onclick = function() {
|
||||
indexedDB.deleteDatabase("asyncStorage");
|
||||
};
|
||||
document.getElementById("clearMethodCache").onclick = function() {
|
||||
CompiledMethodCache.clear();
|
||||
};
|
||||
document.getElementById("exportstorage").onclick = function() {
|
||||
fs.exportStore(function(blob) {
|
||||
saveAs(blob, "fs-" + Date.now() + ".json");
|
||||
|
@ -229,6 +231,9 @@ window.onload = function() {
|
|||
});
|
||||
}
|
||||
};
|
||||
document.getElementById("clearCompiledMethodCache").onclick = function() {
|
||||
CompiledMethodCache.clear().then(function() { console.log("cleared compiled method cache") });
|
||||
};
|
||||
document.getElementById("trace").onclick = function() {
|
||||
VM.DEBUG = !VM.DEBUG;
|
||||
toggle(this);
|
||||
|
|
43
runtime.ts
43
runtime.ts
|
@ -34,6 +34,11 @@ module J2ME {
|
|||
*/
|
||||
export var enableOnStackReplacement = true;
|
||||
|
||||
/**
|
||||
* Turns on caching of JIT-compiled methods.
|
||||
*/
|
||||
export var enableCompiledMethodCache = true;
|
||||
|
||||
/**
|
||||
* Enables more compact mangled names. This helps reduce code size but may cause naming collisions.
|
||||
*/
|
||||
|
@ -1072,6 +1077,10 @@ module J2ME {
|
|||
* callers should be calling that instead of this.
|
||||
*/
|
||||
export function linkKlass(classInfo: ClassInfo) {
|
||||
// We shouldn't do any linking if we're not in the runtime phase.
|
||||
if (phase !== ExecutionPhase.Runtime) {
|
||||
return;
|
||||
}
|
||||
if (classInfo.klass) {
|
||||
return;
|
||||
}
|
||||
|
@ -1226,6 +1235,14 @@ module J2ME {
|
|||
}
|
||||
|
||||
function findCompiledMethod(klass: Klass, methodInfo: MethodInfo): Function {
|
||||
if (enableCompiledMethodCache) {
|
||||
var cachedMethod;
|
||||
if (!jsGlobal[methodInfo.mangledClassAndMethodName] && (cachedMethod = CompiledMethodCache.get(methodInfo.implKey))) {
|
||||
cachedMethodCount ++;
|
||||
linkMethod(methodInfo, cachedMethod.source, cachedMethod.referencedClasses);
|
||||
}
|
||||
}
|
||||
|
||||
return jsGlobal[methodInfo.mangledClassAndMethodName];
|
||||
}
|
||||
|
||||
|
@ -1452,12 +1469,13 @@ module J2ME {
|
|||
return;
|
||||
}
|
||||
|
||||
var compiledMethod;
|
||||
|
||||
if (compiledMethod = CompiledMethodCache.get(methodInfo.implKey)) {
|
||||
cachedMethodCount ++;
|
||||
jitWriter && jitWriter.writeLn("Getting " + methodInfo.implKey + " from compiled method cache");
|
||||
return linkMethod(methodInfo, compiledMethod.source, compiledMethod.referencedClasses);
|
||||
if (enableCompiledMethodCache) {
|
||||
var cachedMethod;
|
||||
if (cachedMethod = CompiledMethodCache.get(methodInfo.implKey)) {
|
||||
cachedMethodCount ++;
|
||||
jitWriter && jitWriter.writeLn("Getting " + methodInfo.implKey + " from compiled method cache");
|
||||
return linkMethod(methodInfo, cachedMethod.source, cachedMethod.referencedClasses);
|
||||
}
|
||||
}
|
||||
|
||||
var mangledClassAndMethodName = methodInfo.mangledClassAndMethodName;
|
||||
|
@ -1465,10 +1483,11 @@ module J2ME {
|
|||
jitWriter && jitWriter.enter("Compiling: " + methodInfo.implKey + ", currentBytecodeCount: " + methodInfo.bytecodeCount);
|
||||
var s = performance.now();
|
||||
|
||||
compiledMethodCount ++;
|
||||
var compiledMethod;
|
||||
enterTimeline("Compiling");
|
||||
try {
|
||||
compiledMethod = baselineCompileMethod(methodInfo, CompilationTarget.Runtime);
|
||||
compiledMethod = baselineCompileMethod(methodInfo, CompilationTarget[enableCompiledMethodCache ? "Static" : "Runtime"]);
|
||||
compiledMethodCount ++;
|
||||
} catch (e) {
|
||||
methodInfo.state = MethodState.CannotCompile;
|
||||
jitWriter && jitWriter.writeLn("Cannot compile: " + methodInfo.implKey + " because of " + e);
|
||||
|
@ -1484,14 +1503,12 @@ module J2ME {
|
|||
|
||||
var referencedClasses = compiledMethod.referencedClasses.map(function(v) { return v.className });
|
||||
|
||||
try {
|
||||
if (enableCompiledMethodCache) {
|
||||
CompiledMethodCache.put({
|
||||
key: methodInfo.implKey,
|
||||
source: source,
|
||||
referencedClasses: referencedClasses,
|
||||
});
|
||||
} catch(e) {
|
||||
jitWriter && jitWriter.writeLn("Cannot cache: " + methodInfo.implKey + " because of " + e);
|
||||
}).catch(stderrWriter.errorLn.bind(stderrWriter));
|
||||
}
|
||||
|
||||
linkMethod(methodInfo, source, referencedClasses);
|
||||
|
@ -1511,6 +1528,8 @@ module J2ME {
|
|||
* Links up compiled method at runtime.
|
||||
*/
|
||||
export function linkMethod(methodInfo: MethodInfo, source: string, referencedClasses: string[]) {
|
||||
jitWriter && jitWriter.writeLn("Link method: " + methodInfo.implKey);
|
||||
|
||||
enterTimeline("Eval Compiled Code");
|
||||
// This overwrites the method on the global object.
|
||||
(1, eval)(source);
|
||||
|
|
|
@ -150,8 +150,9 @@ casper.test.begin("unit tests", 16 + gfxTests.length, function(test) {
|
|||
.thenOpen("http://localhost:8000/index.html?logConsole=web,page")
|
||||
.withFrame(0, basicUnitTests);
|
||||
|
||||
// Run the same unit tests again to test the compiled method cache.
|
||||
casper
|
||||
.thenOpen("http://localhost:8000/index.html?numCalled=1000&logConsole=web,page")
|
||||
.thenOpen("http://localhost:8000/index.html?logConsole=web,page")
|
||||
.withFrame(0, basicUnitTests);
|
||||
|
||||
casper
|
||||
|
|
Загрузка…
Ссылка в новой задаче