mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-29 08:52:15 +00:00
Update Binaryen and add optimize levels to asc
This commit is contained in:
parent
9cdfa35938
commit
fc40ed80f7
@ -20,10 +20,10 @@ A few early examples to get an idea:
|
|||||||
A PSON decoder implemented in AssemblyScript.
|
A PSON decoder implemented in AssemblyScript.
|
||||||
|
|
||||||
* **[TLSF memory allocator](./examples/tlsf)**<br />
|
* **[TLSF memory allocator](./examples/tlsf)**<br />
|
||||||
An port of TLSF to AssemblyScript.
|
A port of TLSF to AssemblyScript.
|
||||||
|
|
||||||
* **[μgc garbage collector](./examples/ugc)**<br />
|
* **[μgc garbage collector](./examples/ugc)**<br />
|
||||||
An port of μgc to AssemblyScript.
|
A port of μgc to AssemblyScript.
|
||||||
|
|
||||||
Or browse the [compiler tests](./tests/compiler) for a more in-depth overview of what's supported already. One of them is a [showcase](./tests/compiler/showcase.ts).
|
Or browse the [compiler tests](./tests/compiler) for a more in-depth overview of what's supported already. One of them is a [showcase](./tests/compiler/showcase.ts).
|
||||||
|
|
||||||
|
60
bin/asc.js
60
bin/asc.js
@ -32,7 +32,7 @@ Object.keys(conf).forEach(key => {
|
|||||||
|
|
||||||
var args = minimist(process.argv.slice(2), opts);
|
var args = minimist(process.argv.slice(2), opts);
|
||||||
var version = require("../package.json").version;
|
var version = require("../package.json").version;
|
||||||
var indent = 20;
|
var indent = 24;
|
||||||
if (isDev) version += "-dev";
|
if (isDev) version += "-dev";
|
||||||
|
|
||||||
if (args.version) {
|
if (args.version) {
|
||||||
@ -47,9 +47,9 @@ if (args.help || args._.length < 1) {
|
|||||||
Object.keys(conf).forEach(name => {
|
Object.keys(conf).forEach(name => {
|
||||||
var option = conf[name];
|
var option = conf[name];
|
||||||
var text = " ";
|
var text = " ";
|
||||||
if (option.aliases && option.aliases[0].length === 1)
|
|
||||||
text += "-" + option.aliases[0] + ", ";
|
|
||||||
text += "--" + name;
|
text += "--" + name;
|
||||||
|
if (option.aliases && option.aliases[0].length === 1)
|
||||||
|
text += ", -" + option.aliases[0];
|
||||||
while (text.length < indent)
|
while (text.length < indent)
|
||||||
text += " ";
|
text += " ";
|
||||||
if (Array.isArray(option.desc)) {
|
if (Array.isArray(option.desc)) {
|
||||||
@ -164,15 +164,63 @@ else if (args.trapMode !== "allow") {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.optimize)
|
var optimizeLevel = 0;
|
||||||
module.optimize();
|
var shrinkLevel = 0;
|
||||||
|
var debugInfo = !args.noDebug;
|
||||||
|
var runPasses = [];
|
||||||
|
|
||||||
|
if (args["O"]) {
|
||||||
|
if (typeof args["O"] === "number")
|
||||||
|
optimizeLevel = args["O"];
|
||||||
|
else if (args["O"] === true) {
|
||||||
|
optimizeLevel = 2;
|
||||||
|
shrinkLevel = 1;
|
||||||
|
} else if (args["0"])
|
||||||
|
optimizeLevel = 0;
|
||||||
|
else if (args["1"])
|
||||||
|
optimizeLevel = 1;
|
||||||
|
else if (args["2"])
|
||||||
|
optimizeLevel = 2;
|
||||||
|
else if (args["3"])
|
||||||
|
optimizeLevel = 3;
|
||||||
|
else
|
||||||
|
optimizeLevel = 2;
|
||||||
|
}
|
||||||
|
if (args["s"])
|
||||||
|
shrinkLevel = 1;
|
||||||
|
else if (args["z"])
|
||||||
|
shrinkLevel = 2;
|
||||||
|
|
||||||
|
// Check explicit levels
|
||||||
|
if (typeof args.optimizeLevel === "number")
|
||||||
|
optimizeLevel = args.optimizeLevel;
|
||||||
|
if (typeof args.shrinkLevel === "number")
|
||||||
|
shrinkLevel = args.shrinkLevel;
|
||||||
|
|
||||||
|
// Workaround for inlining not being performed (42.0.0)
|
||||||
|
if ((optimizeLevel >= 2 || shrinkLevel >= 2) && !debugInfo)
|
||||||
|
runPasses = [ "inlining", "inlining-optimizing" ];
|
||||||
|
|
||||||
|
// Check additional passes
|
||||||
if (args.runPasses) {
|
if (args.runPasses) {
|
||||||
if (typeof args.runPasses === "string")
|
if (typeof args.runPasses === "string")
|
||||||
args.runPasses = args.runPasses.split(",");
|
args.runPasses = args.runPasses.split(",");
|
||||||
module.runPasses(args.runPasses.map(pass => pass.trim()));
|
if (args.runPasses.length)
|
||||||
|
args.runPasses.forEach(pass => {
|
||||||
|
if (runPasses.indexOf(pass) < 0)
|
||||||
|
runPasses.push(pass);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.setOptimizeLevel(optimizeLevel);
|
||||||
|
module.setShrinkLevel(shrinkLevel);
|
||||||
|
module.setDebugInfo(debugInfo);
|
||||||
|
|
||||||
|
if (optimizeLevel || shrinkLevel)
|
||||||
|
module.optimize();
|
||||||
|
if (runPasses.length)
|
||||||
|
module.runPasses(runPasses.map(pass => pass.trim()));
|
||||||
|
|
||||||
var hasOutput = false;
|
var hasOutput = false;
|
||||||
|
|
||||||
if (args.outFile != null) {
|
if (args.outFile != null) {
|
||||||
|
25
bin/asc.json
25
bin/asc.json
@ -10,10 +10,27 @@
|
|||||||
"aliases": [ "h" ]
|
"aliases": [ "h" ]
|
||||||
},
|
},
|
||||||
"optimize": {
|
"optimize": {
|
||||||
"desc": "Optimizes the module.",
|
"desc": [
|
||||||
"type": "boolean",
|
"Optimizes the module. Also accepts the optimize level:",
|
||||||
|
" -O Equivalent to -O2s",
|
||||||
|
" -O0 Runs no optimization passes",
|
||||||
|
" -O1 Runs fast optimization passes",
|
||||||
|
" -O2 Runs default optimization passes",
|
||||||
|
" -O3 Runs all optimization passes",
|
||||||
|
" -O2s Specifies optimize level 2 with shrink level 1",
|
||||||
|
" -O3z etc."
|
||||||
|
],
|
||||||
|
"type": "number",
|
||||||
"aliases": [ "O" ]
|
"aliases": [ "O" ]
|
||||||
},
|
},
|
||||||
|
"optimizeLevel": {
|
||||||
|
"desc": "How much to focus on optimizing code.",
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"shrinkLevel": {
|
||||||
|
"desc": "How much to focus on shrinking code size.",
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
"validate": {
|
"validate": {
|
||||||
"desc": "Validates the module.",
|
"desc": "Validates the module.",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@ -43,6 +60,10 @@
|
|||||||
"desc": "Disables tree-shaking.",
|
"desc": "Disables tree-shaking.",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"noDebug": {
|
||||||
|
"desc": "Disables debug information in binaries.",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"noAssert": {
|
"noAssert": {
|
||||||
"desc": "Disables assertions.",
|
"desc": "Disables assertions.",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run build:untouched && npm run build:optimized",
|
"build": "npm run build:untouched && npm run build:optimized",
|
||||||
"build:untouched": "asc assembly/tlsf.ts -t tlsf.untouched.wast -b tlsf.untouched.wasm --validate",
|
"build:untouched": "asc assembly/tlsf.ts -t tlsf.untouched.wast -b tlsf.untouched.wasm --validate",
|
||||||
"build:optimized": "asc -O assembly/tlsf.ts -b tlsf.optimized.wasm -t tlsf.optimized.wast --validate --noAssert --runPasses inlining",
|
"build:optimized": "asc -O3 assembly/tlsf.ts -b tlsf.optimized.wasm -t tlsf.optimized.wast --validate --noDebug --noAssert",
|
||||||
"test": "node tests"
|
"test": "node tests"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ class ObjectHeader {
|
|||||||
|
|
||||||
///////////////////////////////// Fields ////////////////////////////////////
|
///////////////////////////////// Fields ////////////////////////////////////
|
||||||
|
|
||||||
|
// the next and prev pointer with tags in the least significant two bits that
|
||||||
|
// would otherwise be zero (blocks are guaranteed to be aligned to 4/8 bytes)
|
||||||
tagged_next: usize;
|
tagged_next: usize;
|
||||||
tagged_prev: usize;
|
tagged_prev: usize;
|
||||||
|
|
||||||
@ -173,13 +175,13 @@ class Control {
|
|||||||
gc_scan_fn(this, obj);
|
gc_scan_fn(this, obj);
|
||||||
} else {
|
} else {
|
||||||
gc_scan_fn(this, null);
|
gc_scan_fn(this, null);
|
||||||
obj = this.iterator.next;
|
obj = this.iterator.next; // already strips tags, see *
|
||||||
if (obj == this.to) {
|
if (obj == this.to) {
|
||||||
var from = this.from;
|
var from = this.from;
|
||||||
this.from = this.to;
|
this.from = this.to;
|
||||||
this.to = from;
|
this.to = from;
|
||||||
this.white = white ^ 1;
|
this.white = white ^ 1;
|
||||||
this.iterator = from.next;
|
this.iterator = changetype<ObjectHeader>(from.tagged_next); // *
|
||||||
this.state = SWEEP;
|
this.state = SWEEP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,10 +235,10 @@ class Control {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: should happen dynamically so it DCE's if all objects are unmanaged
|
||||||
var GC = Control.create(HEAP_BASE);
|
var GC = Control.create(HEAP_BASE);
|
||||||
var GC_BASE = HEAP_BASE + Control.SIZE;
|
// var someObject = allocate_memory(64);
|
||||||
|
// GC.register(changetype<ObjectHeader>(someObject));
|
||||||
GC.register(changetype<ObjectHeader>(GC_BASE));
|
|
||||||
|
|
||||||
// Exported interface
|
// Exported interface
|
||||||
|
|
||||||
@ -259,7 +261,7 @@ export function gc_collect(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: these functions must be generated by the compiler and combined by
|
// TODO: these functions must be generated by the compiler and combined by
|
||||||
// any potential linker. They live here for now to document their structure.
|
// a potential linker. They live here for now to document their structure.
|
||||||
|
|
||||||
function gc_scan_fn(control: Control, header: ObjectHeader | null): void {
|
function gc_scan_fn(control: Control, header: ObjectHeader | null): void {
|
||||||
if (!header) {
|
if (!header) {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run build:untouched && npm run build:optimized",
|
"build": "npm run build:untouched && npm run build:optimized",
|
||||||
"build:untouched": "asc assembly/ugc.ts -t ugc.untouched.wast -b ugc.untouched.wasm --validate",
|
"build:untouched": "asc assembly/ugc.ts -t ugc.untouched.wast -b ugc.untouched.wasm --validate",
|
||||||
"build:optimized": "asc -O assembly/ugc.ts -b ugc.optimized.wasm -t ugc.optimized.wast --validate --noAssert --runPasses inlining",
|
"build:optimized": "asc -O3 assembly/ugc.ts -b ugc.optimized.wasm -t ugc.optimized.wast --validate --noDebug --noAssert",
|
||||||
"test": "node tests"
|
"test": "node tests"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -274,9 +274,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"binaryen": {
|
"binaryen": {
|
||||||
"version": "40.0.0-nightly.20171229",
|
"version": "42.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/binaryen/-/binaryen-40.0.0-nightly.20171229.tgz",
|
"resolved": "https://registry.npmjs.org/binaryen/-/binaryen-42.0.0.tgz",
|
||||||
"integrity": "sha512-P9VXMphJKRZbdr0AAmkpgRPGVWbnDmcqt8NPuZ+W0eSeC1igGDLdreJteCdtHA7Z+qRQ4BWqtmKPZEJKRZk47w=="
|
"integrity": "sha512-1JkYPfxkkjkTrG1QekDeMyNdwbA/RIvlkpio+BJ41po9X6d7qZnlQHM/CNVhgXCtmGzlw2hbkAyYxEfnE001vw=="
|
||||||
},
|
},
|
||||||
"bn.js": {
|
"bn.js": {
|
||||||
"version": "4.11.8",
|
"version": "4.11.8",
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"url": "https://github.com/AssemblyScript/assemblyscript/issues"
|
"url": "https://github.com/AssemblyScript/assemblyscript/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"binaryen": "40.0.0-nightly.20171229",
|
"binaryen": "42.0.0",
|
||||||
"glob": "^7.1.2",
|
"glob": "^7.1.2",
|
||||||
"minimist": "^1.2.0"
|
"minimist": "^1.2.0"
|
||||||
},
|
},
|
||||||
|
@ -727,9 +727,19 @@ export class Module {
|
|||||||
_BinaryenSetStart(this.ref, func);
|
_BinaryenSetStart(this.ref, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setOptimizeLevel(level: i32 = 2): void {
|
||||||
|
_BinaryenSetOptimizeLevel(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
setShrinkLevel(level: i32 = 1): void {
|
||||||
|
_BinaryenSetShrinkLevel(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
setDebugInfo(on: bool = false): void {
|
||||||
|
_BinaryenSetDebugInfo(on);
|
||||||
|
}
|
||||||
|
|
||||||
optimize(func: FunctionRef = 0): void {
|
optimize(func: FunctionRef = 0): void {
|
||||||
// see: https://github.com/WebAssembly/binaryen/issues/1331#issuecomment-350328175
|
|
||||||
// this.runPasses([ "flatten", "ssa" ], func);
|
|
||||||
if (func) {
|
if (func) {
|
||||||
_BinaryenFunctionOptimize(func, this.ref);
|
_BinaryenFunctionOptimize(func, this.ref);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user