Skip to content

Commit

Permalink
Add RTrace shadow memory and instrumentation (#1476)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: RTrace is now a class and the onrealloc callback has been split into onresize and onmove.
  • Loading branch information
dcodeIO authored Oct 6, 2020
1 parent de022c9 commit 5b2d529
Show file tree
Hide file tree
Showing 103 changed files with 1,114 additions and 1,664 deletions.
27 changes: 22 additions & 5 deletions lib/rtrace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,34 @@ A tiny utility that records allocations, retains, releases and frees performed b
Instructions
------------

Compile your module that uses the full or half runtime with `-use ASC_RTRACE=1` and include an instance of this module as the import named `rtrace`.
Compile your module that uses the full or half runtime with `-use ASC_RTRACE=1 --explicitStart` and include an instance of this module as the import named `rtrace`.

```js
var rtr = rtrace(e => {
// handle error
var rtrace = new Rtrace({
onerror(err, info) {
// handle error
},
oninfo(msg) {
// print message, optional
},
getMemory() {
// obtain the module's memory,
// e.g. with --explicitStart:
return instance.exports.memory;
}
});

WebAssembly.instantiate(..., { rtrace: rtr, ... });
var { module, instance } = await WebAssembly.instantiate(..., {
rtrace,
env: Object.assign({ //
... // only required when instrumenting memory
}, rtrace.env), //
...
});
instance.exports._start();
...

if (rtr.active) {
if (rtrace.active) {
let leakCount = rtr.check();
if (leakCount) {
// handle error
Expand Down
90 changes: 34 additions & 56 deletions lib/rtrace/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,41 @@
/** Creates a new `RTrace` instance, tracking allocations, frees and reference counts. */
declare function rtrace(
/** Block information. */
export declare interface BlockInfo {
/** Pointer to the block. */
ptr: number,
/** Block size. */
size: number,
/** Runtime header. */
header: {
/** Memory manager info bits. */
mmInfo: number,
/** Garbage collector info bits. */
gcInfo: number,
/** Runtime id. */
rtId: number,
/** Runtime size. */
rtSize: number
},
toString(): string
}

export declare interface RtraceOptions {
/** Function being called when a problem is detected. */
onerror?: (error: Error) => void,
onerror?: (error: Error, info: BlockInfo) => void,
/** Function being called with information messages. */
oninfo?: (info: string) => void
): rtrace.RTrace;

declare namespace rtrace {
/** The rtrace instance used as the `rtrace` import to the Wasm module. */
export interface RTrace {
/** Number of allocations so far. */
allocCount: number;
/** Number of reallocations so far. */
reallocCount: number;
/** Number of frees so far. */
freeCount: number;
/** Number of RC increments (retains) so far. */
incrementCount: number;
/** Number of RC decrements (releases) so far. */
decrementCount: number;

/** Called when a new block is allocated. */
onalloc(
/** New block being allocated. */
block: number
): void;

/** Called when a block is reallocated and must be moved. */
onrealloc(
/** Block being moved. */
oldBlock: number,
/** New block used from now on. */
newBlock: number
): void;

/** Called when a block is freed, implicitly or explicitly. */
onfree(
/** Block being freed. */
block: number
): void;
oninfo?: (msg: string) => void,
/** Obtains the module's memory instance. */
getMemory()
}

/** Called when a reference to a block is retained (RC incremented by one). */
onincrement(
/** Block a reference to is being retained. */
block: number
): void;
export declare class Rtrace {
[key: string]: unknown; // can be used as a Wasm import

/** Called when a reference to a block is released (RC decremented by one). */
ondecrement(
/** Block a reference to is being released. */
block: number
): void;
/** Creates a new `RTrace` instance. */
constructor(options: RtraceOptions);

/** Checks if rtrace is active, i.e. at least one event has occurred. */
readonly active: boolean;
/** Checks if rtrace is active, i.e. at least one event has occurred. */
readonly active: boolean;

/** Checks if there are any leaks and emits them via `oninfo`. Returns the number of live blocks. */
check(): number;
}
/** Checks if there are any leaks and emits them via `oninfo`. Returns the number of live blocks. */
check(): number;
}

export = rtrace;
Loading

0 comments on commit 5b2d529

Please sign in to comment.