Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rtrace shadow memory and instrumentation #1476

Merged
merged 6 commits into from
Oct 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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