mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-12 06:21:29 +00:00
Move TLSF to stdlib, see #15
This commit is contained in:
2
tests/tlsf/assembly/index.ts
Normal file
2
tests/tlsf/assembly/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
import "allocator/tlsf";
|
||||
export { allocate_memory, free_memory };
|
6
tests/tlsf/assembly/tsconfig.json
Normal file
6
tests/tlsf/assembly/tsconfig.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "../../../std/assembly.json",
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
]
|
||||
}
|
13
tests/tlsf/forever.js
Normal file
13
tests/tlsf/forever.js
Normal file
@ -0,0 +1,13 @@
|
||||
var child_process = require("child_process");
|
||||
|
||||
// restarts the test forever, that is, until an issue is detected
|
||||
|
||||
var count = 0;
|
||||
while (true) {
|
||||
console.log("[ #" + ++count + " ]\n");
|
||||
var res = child_process.spawnSync("node", [ __dirname ], { stdio: "inherit" });
|
||||
if (res.status !== 0)
|
||||
throw Error("exited with " + res.status);
|
||||
if (res.error)
|
||||
throw res.error;
|
||||
}
|
29
tests/tlsf/index.js
Normal file
29
tests/tlsf/index.js
Normal file
@ -0,0 +1,29 @@
|
||||
const fs = require("fs");
|
||||
const runner = require("./runner");
|
||||
|
||||
function test(file) {
|
||||
console.log("Testing '" + file + "' ...\n");
|
||||
|
||||
const exports = new WebAssembly.Instance(WebAssembly.Module(fs.readFileSync(__dirname + "/" + file)), {
|
||||
env: {
|
||||
abort: function(msg, file, line, column) {
|
||||
throw Error("Assertion failed: " + (msg ? "'" + getString(msg) + "' " : "") + "at " + getString(file) + ":" + line + ":" + column);
|
||||
},
|
||||
log: function(ptr) { console.log(getString(ptr)); },
|
||||
logi: function(i) { console.log(i); }
|
||||
}
|
||||
}).exports;
|
||||
|
||||
function getString(ptr) {
|
||||
var len = new Uint32Array(exports.memory.buffer, ptr)[0];
|
||||
var str = new Uint16Array(exports.memory.buffer, ptr + 4).subarray(0, len);
|
||||
return String.fromCharCode.apply(String, str);
|
||||
}
|
||||
|
||||
runner(exports, 20, 20000); // picked so I/O isn't the bottleneck
|
||||
console.log("mem final: " + exports.memory.buffer.byteLength);
|
||||
console.log();
|
||||
}
|
||||
|
||||
test("tlsf.untouched.wasm");
|
||||
test("tlsf.optimized.wasm");
|
10
tests/tlsf/package.json
Normal file
10
tests/tlsf/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "npm run build:untouched && npm run build:optimized",
|
||||
"build:untouched": "asc assembly/index.ts -t tlsf.untouched.wast -b tlsf.untouched.wasm --validate --sourceMap --measure",
|
||||
"build:optimized": "asc assembly/index.ts -t tlsf.optimized.wast -b tlsf.optimized.wasm --validate --sourceMap --measure --noDebug --noAssert --optimize",
|
||||
"test": "node ./index",
|
||||
"test:forever": "node ./forever"
|
||||
}
|
||||
}
|
92
tests/tlsf/runner.js
Normal file
92
tests/tlsf/runner.js
Normal file
@ -0,0 +1,92 @@
|
||||
function runner(tlsf, runs, allocs) {
|
||||
var ptrs = [];
|
||||
|
||||
function randomAlloc(maxSize) {
|
||||
if (!maxSize) maxSize = 8192;
|
||||
var size = ((Math.random() * maxSize) >>> 0) + 1;
|
||||
size = (size + 3) & ~3;
|
||||
var ptr = tlsf.allocate_memory(size);
|
||||
if (!ptr) throw Error();
|
||||
if (ptrs.indexOf(ptr) >= 0) throw Error();
|
||||
if (tlsf.set_memory)
|
||||
tlsf.set_memory(ptr, 0xdc, size);
|
||||
ptrs.push(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
function preciseFree(ptr) {
|
||||
var idx = ptrs.indexOf(ptr);
|
||||
if (idx < 0) throw Error();
|
||||
var ptr = ptrs[idx];
|
||||
ptrs.splice(idx, 1);
|
||||
if (typeof ptr !== "number") throw Error();
|
||||
tlsf.free_memory(ptr);
|
||||
}
|
||||
|
||||
function randomFree() {
|
||||
var idx = (Math.random() * ptrs.length) >>> 0;
|
||||
var ptr = ptrs[idx];
|
||||
if (typeof ptr !== "number") throw Error();
|
||||
ptrs.splice(idx, 1);
|
||||
tlsf.free_memory(ptr);
|
||||
}
|
||||
|
||||
// remember the smallest possible memory address
|
||||
var base = tlsf.allocate_memory(64);
|
||||
console.log("base: " + base);
|
||||
tlsf.free_memory(base);
|
||||
console.log("mem initial: " + tlsf.memory.buffer.byteLength);
|
||||
|
||||
try {
|
||||
for (var j = 0; j < runs; ++j) {
|
||||
console.log("run " + (j + 1) + " (" + allocs + " allocations) ...");
|
||||
for (var i = 0; i < allocs; ++i) {
|
||||
var ptr = randomAlloc();
|
||||
|
||||
// immediately free every 4th
|
||||
if (!(i % 4)) preciseFree(ptr);
|
||||
|
||||
// occasionally free random blocks
|
||||
else if (ptrs.length && Math.random() < 0.33) randomFree();
|
||||
|
||||
// ^ sums up to clearing about half the blocks half-way
|
||||
}
|
||||
// free the rest, randomly
|
||||
while (ptrs.length) randomFree();
|
||||
|
||||
// should now be possible to reuse the entire memory
|
||||
// just try a large portion of the memory here because of SL+1 for allocs
|
||||
var size = ((tlsf.memory.buffer.byteLength - base) * 9 / 10) >>> 0;
|
||||
var ptr = tlsf.allocate_memory(size);
|
||||
if (tlsf.set_memory)
|
||||
tlsf.set_memory(ptr, 0xac, size);
|
||||
if (ptr !== base)
|
||||
throw Error("expected " + base + " but got " + ptr);
|
||||
tlsf.free_memory(ptr);
|
||||
}
|
||||
} finally {
|
||||
// mem(tlsf.memory, 0, 0x10000);
|
||||
}
|
||||
}
|
||||
|
||||
function mem(memory, offset, count) {
|
||||
if (!offset) offset = 0;
|
||||
if (!count) count = 1024;
|
||||
var mem = new Uint8Array(memory.buffer, offset);
|
||||
var stackTop = new Uint32Array(memory.buffer, 4, 1)[0];
|
||||
var hex = [];
|
||||
for (var i = 0; i < count; ++i) {
|
||||
var o = (offset + i).toString(16);
|
||||
while (o.length < 4) o = "0" + o;
|
||||
if ((i & 15) === 0) {
|
||||
hex.push("\n" + o + ":");
|
||||
}
|
||||
var h = mem[i].toString(16);
|
||||
if (h.length < 2) h = "0" + h;
|
||||
hex.push(h);
|
||||
}
|
||||
console.log(hex.join(" ") + " ...");
|
||||
}
|
||||
|
||||
if (typeof module === "object" && typeof exports === "object")
|
||||
module.exports = runner;
|
1437
tests/tlsf/tlsf.optimized.wast
Normal file
1437
tests/tlsf/tlsf.optimized.wast
Normal file
File diff suppressed because it is too large
Load Diff
2781
tests/tlsf/tlsf.untouched.wast
Normal file
2781
tests/tlsf/tlsf.untouched.wast
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user