Make sure all roots are iterated by delaying builtin generation; Cleanup

This commit is contained in:
dcodeIO 2018-07-20 20:32:25 +02:00
parent 41ad2f8a70
commit 2fa7d6678c
11 changed files with 411 additions and 871 deletions

View File

@ -2629,8 +2629,7 @@ export function compileCall(
// gc
case "gc.iterateRoots": {
// TOOD: make it so that this can only be called from a library file?
case "iterateRoots": {
if (typeArguments) {
compiler.error(
DiagnosticCode.Type_0_is_not_generic,
@ -2661,49 +2660,10 @@ export function compileCall(
);
return module.createUnreachable();
}
let exprs = new Array<ExpressionRef>();
for (let element of compiler.program.elementsLookup.values()) {
if (element.kind != ElementKind.GLOBAL) continue;
let global = <Global>element;
let classReference = global.type.classReference;
if (
global.is(CommonFlags.COMPILED) &&
classReference !== null &&
!classReference.hasDecorator(DecoratorFlags.UNMANAGED)
) {
if (global.is(CommonFlags.INLINED)) {
let value = global.constantIntegerValue;
exprs.push(
module.createCallIndirect(
expr,
[
compiler.options.isWasm64
? module.createI64(i64_low(value), i64_high(value))
: module.createI32(i64_low(value))
],
signatureReference.toSignatureString()
)
);
} else {
exprs.push(
module.createCallIndirect(
expr,
[
module.createGetGlobal(
global.internalName,
compiler.options.nativeSizeType
)
],
signatureReference.toSignatureString()
)
);
}
}
}
compiler.currentType = Type.void;
return exprs.length
? module.createBlock(null, exprs)
: module.createNop();
// just emit a call even if the function doesn't yet exist
compiler.needsIterateRoots = true;
return module.createCall("~iterateRoots", [ expr ], NativeType.None);
}
}
var expr = deferASMCall(compiler, prototype, operands, contextualType, reportNode);
@ -2977,3 +2937,54 @@ export function compileAbort(
module.createUnreachable()
]);
}
/** Compiles the iterateRoots function if requires. */
export function compileIterateRoots(compiler: Compiler): void {
var module = compiler.module;
var exprs = new Array<ExpressionRef>();
for (let element of compiler.program.elementsLookup.values()) {
if (element.kind != ElementKind.GLOBAL) continue;
let global = <Global>element;
let classReference = global.type.classReference;
if (
global.is(CommonFlags.COMPILED) &&
classReference !== null &&
!classReference.hasDecorator(DecoratorFlags.UNMANAGED)
) {
if (global.is(CommonFlags.INLINED)) {
let value = global.constantIntegerValue;
exprs.push(
module.createCallIndirect(
module.createGetLocal(0, NativeType.I32),
[
compiler.options.isWasm64
? module.createI64(i64_low(value), i64_high(value))
: module.createI32(i64_low(value))
],
"iv"
)
);
} else {
exprs.push(
module.createCallIndirect(
module.createGetLocal(0, NativeType.I32),
[
module.createGetGlobal(
global.internalName,
compiler.options.nativeSizeType
)
],
"iv"
)
);
}
}
}
var typeRef = compiler.ensureFunctionType([ Type.i32 ], Type.void);
module.addFunction("~iterateRoots", typeRef, [],
exprs.length
? module.createBlock(null, exprs)
: module.createNop()
);
}

View File

@ -5,8 +5,9 @@
import {
compileCall as compileBuiltinCall,
compileAllocate as compileBuiltinAllocate,
compileAbort as compileBuiltinAbort
compileAllocate,
compileAbort,
compileIterateRoots
} from "./builtins";
import {
@ -286,6 +287,8 @@ export class Compiler extends DiagnosticEmitter {
argcVar: GlobalRef = 0;
/** Argument count helper setter. */
argcSet: FunctionRef = 0;
/** Indicates whether the iterateRoots function must be generated. */
needsIterateRoots: bool = false;
/** Compiles a {@link Program} to a {@link Module} using the specified options. */
static compile(program: Program, options: Options | null = null): Module {
@ -408,6 +411,9 @@ export class Compiler extends DiagnosticEmitter {
this.makeModuleExport(name, moduleExport.element);
}
// set up gc
if (this.needsIterateRoots) compileIterateRoots(this);
return module;
}
@ -974,7 +980,7 @@ export class Compiler extends DiagnosticEmitter {
}
/** Either reuses or creates the function type matching the specified signature. */
private ensureFunctionType(
ensureFunctionType(
parameterTypes: Type[] | null,
returnType: Type,
thisType: Type | null = null
@ -2022,7 +2028,7 @@ export class Compiler extends DiagnosticEmitter {
flow.set(FlowFlags.RETURNS);
// TODO: requires exception-handling spec.
return compileBuiltinAbort(this, null, statement);
return compileAbort(this, null, statement);
}
compileTryStatement(statement: TryStatement): ExpressionRef {
@ -6524,7 +6530,7 @@ export class Compiler extends DiagnosticEmitter {
// allocate a new instance first and assign 'this' to the temp. local
exprs[0] = module.createSetLocal(
tempLocal.index,
compileBuiltinAllocate(this, classReference, expression)
compileAllocate(this, classReference, expression)
);
// once all field values have been set, return 'this'
@ -7497,7 +7503,7 @@ export class Compiler extends DiagnosticEmitter {
var initializers = new Array<ExpressionRef>();
initializers.push(
module.createSetLocal(tempLocal.index,
compileBuiltinAllocate(this, classInstance, reportNode)
compileAllocate(this, classInstance, reportNode)
)
);

View File

@ -6,13 +6,17 @@
// Largely based on the Bach Le's μgc, see: https://github.com/bullno1/ugc
const TRACE = true;
const TRACE = false;
import {
AL_MASK,
MAX_SIZE_32
} from "../internal/allocator";
import {
iterateRoots
} from "../gc";
/** Collector states. */
const enum State {
/** Not yet initialized. */
@ -31,8 +35,8 @@ var state = State.INIT;
var white = 0;
// From and to spaces
var from: ManagedObject;
var to: ManagedObject;
var from: ManagedObjectSet;
var to: ManagedObjectSet;
var iter: ManagedObject;
// ╒═══════════════ Managed object layout (32-bit) ════════════════╕
@ -83,16 +87,6 @@ class ManagedObject {
this.nextWithColor = (this.nextWithColor & ~3) | color;
}
/** Inserts an object to this list. */
push(obj: ManagedObject): void {
var prev = this.prev;
trace(" push", 3, objToRef(prev), objToRef(obj), objToRef(this));
obj.next = this;
obj.prev = prev;
prev.next = obj;
this.prev = obj;
}
/** Unlinks this object from its list. */
unlink(): void {
var next = this.next;
@ -102,12 +96,6 @@ class ManagedObject {
prev.next = next;
}
clear(): void {
if (TRACE) trace(" clear", 1, objToRef(this));
this.nextWithColor = changetype<usize>(this);
this.prev = this;
}
/** Marks this object as gray, that is reachable with unscanned children. */
makeGray(): void {
if (TRACE) trace(" makeGray", 1, objToRef(this));
@ -119,24 +107,38 @@ class ManagedObject {
}
}
function markRoots(): void {
if (TRACE) trace(" markRoots");
gc.iterateRoots(function markRoot(ref: usize): void {
if (TRACE) trace(" markRoot", 1, ref);
if (ref) __gc_mark(ref);
});
/** A set of managed objects. Used for the from and to spaces. */
@unmanaged
class ManagedObjectSet extends ManagedObject {
/** Inserts an object. */
push(obj: ManagedObject): void {
var prev = this.prev;
if (TRACE) trace(" push", 3, objToRef(prev), objToRef(obj), objToRef(this));
obj.next = this;
obj.prev = prev;
prev.next = obj;
this.prev = obj;
}
/** Clears this list. */
clear(): void {
if (TRACE) trace(" clear", 1, objToRef(this));
this.nextWithColor = changetype<usize>(this);
this.prev = this;
}
}
/** Performs a single step according to the current state. */
function step(): void {
export function step(): bool {
var obj: ManagedObject;
switch (state) {
case State.INIT: {
if (TRACE) trace("gc~step/INIT");
from = changetype<ManagedObject>(memory.allocate(ManagedObject.SIZE));
from = changetype<ManagedObjectSet>(memory.allocate(ManagedObject.SIZE));
from.visitFn = changetype<(ref: usize) => void>(<u32>-1); // would error
from.clear();
to = changetype<ManagedObject>(memory.allocate(ManagedObject.SIZE));
to = changetype<ManagedObjectSet>(memory.allocate(ManagedObject.SIZE));
to.visitFn = changetype<(ref: usize) => void>(<u32>-1); // would error
to.clear();
iter = to;
@ -146,7 +148,7 @@ function step(): void {
}
case State.IDLE: {
if (TRACE) trace("gc~step/IDLE");
markRoots();
iterateRoots(__gc_mark);
state = State.MARK;
if (TRACE) trace("gc~state = MARK");
break;
@ -160,7 +162,7 @@ function step(): void {
obj.visitFn(objToRef(obj));
} else {
if (TRACE) trace("gc~step/MARK finish");
markRoots();
iterateRoots(__gc_mark);
obj = iter.next;
if (obj === to) {
let prevFrom = from;
@ -189,6 +191,7 @@ function step(): void {
break;
}
}
return state != State.IDLE;
}
@inline function refToObj(ref: usize): ManagedObject {
@ -201,7 +204,6 @@ function step(): void {
// Garbage collector interface
/** Allocates a managed object. */
@global export function __gc_allocate(
size: usize,
visitFn: (ref: usize) => void
@ -216,21 +218,20 @@ function step(): void {
return objToRef(obj);
}
/** Marks a reachable object. Called from the visitFn functions. */
@global export function __gc_mark(ref: usize): void {
if (TRACE) trace("gc.mark", 1, ref);
var obj = refToObj(ref);
if (obj.color == white) obj.makeGray();
}
/** Links a managed child object to its parent object. */
@global export function __gc_link(parentRef: usize, childRef: usize): void {
if (TRACE) trace("gc.link", 2, parentRef, childRef);
var parent = refToObj(parentRef);
if (parent.color == <i32>!white && refToObj(childRef).color == white) parent.makeGray();
}
/** Performs a full garbage collection cycle. */
@global export function __gc_mark(ref: usize): void {
if (TRACE) trace("gc.mark", 1, ref);
if (ref) {
let obj = refToObj(ref);
if (obj.color == white) obj.makeGray();
}
}
@global export function __gc_collect(): void {
if (TRACE) trace("gc.collect");
// begin collecting if not yet collecting

View File

@ -1,16 +1,16 @@
export namespace gc {
@builtin export declare function iterateRoots(fn: (ref: usize) => void): void; // tslint:disable-line
export namespace gc {
export function allocate(size: usize, visitFn: (ref: usize) => void): usize {
if (isDefined(__gc_allocate)) return __gc_allocate(size, visitFn); // tslint:disable-line
WARNING("Calling 'gc.allocate' requires a garbage collector to be present.");
return <usize>unreachable();
}
export function mark(ref: usize): void {
if (isDefined(__gc_mark)) { __gc_mark(ref); return; } // tslint:disable-line
WARNING("Calling 'gc.mark' requires a garbage collector to be present.");
export function collect(): void {
if (isDefined(__gc_collect)) { __gc_collect(); return; } // tslint:disable-line
WARNING("Calling 'gc.collect' requires a garbage collector to be present.");
unreachable();
}
@ -20,9 +20,9 @@ export namespace gc {
unreachable();
}
export function collect(): void {
if (isDefined(__gc_collect)) { __gc_collect(); return; } // tslint:disable-line
WARNING("Calling 'gc.collect' requires a garbage collector to be present.");
export function mark(ref: usize): void {
if (isDefined(__gc_mark)) { __gc_mark(ref); return; } // tslint:disable-line
WARNING("Calling 'gc.mark' requires a garbage collector to be present.");
unreachable();
}
}

View File

@ -350,16 +350,14 @@ declare namespace memory {
/** Garbage collector operations. */
declare namespace gc {
/** Calls the specified function with every reference within the root set. */
export function iterateRoots(fn: (ref: usize) => void): void;
/** Allocates a managed object identified by its visitor function. */
export function allocate(size: usize, visitFn: (ref: usize) => void): usize;
/** Marks a managed object as reachable. */
export function mark(ref: usize): void;
/** Links a managed child with its parent. */
export function link(parentRef: usize, childRef: usize): void;
/** Performs a full garbage collection cycle. */
export function collect(): void;
/** Must be called when a managed object becomes a child of another one. */
export function link(parentRef: usize, childRef: usize): void;
/** Must be called when a managed object is found reachable. */
export function mark(ref: usize): void;
}
/** Table operations. */

View File

@ -34,27 +34,14 @@
(i32.const 0)
(i32.const 8)
(i32.const 14)
(i32.const 40)
(i32.const 37)
)
(unreachable)
)
)
)
(func $start (; 2 ;) (type $v)
(call_indirect (type $iv)
(i32.const 8)
(i32.const 0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/B.d)
(i32.const 0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/a_ref)
(i32.const 0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/b_ref)
(call $~iterateRoots
(i32.const 0)
)
(if
@ -73,4 +60,22 @@
)
)
)
(func $~iterateRoots (; 3 ;) (type $iv) (param $0 i32)
(call_indirect (type $iv)
(i32.const 8)
(get_local $0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/B.d)
(get_local $0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/a_ref)
(get_local $0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/b_ref)
(get_local $0)
)
)
)

View File

@ -11,5 +11,5 @@ var a_ref: A | null = changetype<A>(24);
var b_ref: B = changetype<B>(32);
var i: i32 = 0;
gc.iterateRoots((ref: usize): void => { assert(<u32>ref == ++i << 3); });
iterateRoots((ref: usize): void => { assert(<u32>ref == ++i << 3); });
assert(i == 4);

View File

@ -41,7 +41,7 @@
(i32.const 0)
(i32.const 8)
(i32.const 14)
(i32.const 40)
(i32.const 37)
)
(unreachable)
)
@ -54,24 +54,9 @@
(drop
(get_global $std/gc-integration/B.d)
)
(block
(call_indirect (type $iv)
(get_global $std/gc-integration/B.c)
(call $~iterateRoots
(i32.const 0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/B.d)
(i32.const 0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/a_ref)
(i32.const 0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/b_ref)
(i32.const 0)
)
)
(if
(i32.eqz
(i32.eq
@ -90,4 +75,22 @@
)
)
)
(func $~iterateRoots (; 3 ;) (type $iv) (param $0 i32)
(call_indirect (type $iv)
(get_global $std/gc-integration/B.c)
(get_local $0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/B.d)
(get_local $0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/a_ref)
(get_local $0)
)
(call_indirect (type $iv)
(get_global $std/gc-integration/b_ref)
(get_local $0)
)
)
)

View File

@ -1,13 +1,11 @@
(module
(type $iv (func (param i32)))
(type $iii (func (param i32 i32) (result i32)))
(type $iiFFFFFv (func (param i32 i32 f64 f64 f64 f64 f64)))
(type $v (func))
(type $i (func (result i32)))
(type $ii (func (param i32) (result i32)))
(type $iiv (func (param i32 i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $i (func (result i32)))
(import "env" "trace" (func $~lib/env/trace (param i32 i32 f64 f64 f64 f64 f64)))
(type $v (func))
(import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32)))
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
@ -18,37 +16,19 @@
(global $~lib/collector/itcm/iter (mut i32) (i32.const 0))
(global $~argc (mut i32) (i32.const 0))
(global $std/gc/obj (mut i32) (i32.const 0))
(global $std/gc/head (mut i32) (i32.const 0))
(global $std/gc/obj2 (mut i32) (i32.const 0))
(global $~started (mut i32) (i32.const 0))
(table 2 2 anyfunc)
(elem (i32.const 0) $std/gc/MyObject_visit $~lib/collector/itcm/markRoots~markRoot|1)
(elem (i32.const 0) $std/gc/MyObject_visit $~lib/collector/itcm/__gc_mark)
(memory $0 1)
(data (i32.const 8) "\0b\00\00\00g\00c\00.\00a\00l\00l\00o\00c\00a\00t\00e")
(data (i32.const 36) "\0c\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00I\00N\00I\00T")
(data (i32.const 64) "\08\00\00\00 \00 \00 \00c\00l\00e\00a\00r")
(data (i32.const 84) "\0f\00\00\00g\00c\00~\00s\00t\00a\00t\00e\00 \00=\00 \00I\00D\00L\00E")
(data (i32.const 120) "\0c\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00I\00D\00L\00E")
(data (i32.const 148) "\0c\00\00\00 \00 \00 \00m\00a\00r\00k\00R\00o\00o\00t\00s")
(data (i32.const 176) "\0b\00\00\00 \00 \00 \00m\00a\00r\00k\00R\00o\00o\00t")
(data (i32.const 204) "\07\00\00\00g\00c\00.\00m\00a\00r\00k")
(data (i32.const 224) "\0b\00\00\00 \00 \00 \00m\00a\00k\00e\00G\00r\00a\00y")
(data (i32.const 252) "\t\00\00\00 \00 \00 \00u\00n\00l\00i\00n\00k")
(data (i32.const 276) "\07\00\00\00 \00 \00 \00p\00u\00s\00h")
(data (i32.const 296) "\0f\00\00\00g\00c\00~\00s\00t\00a\00t\00e\00 \00=\00 \00M\00A\00R\00K")
(data (i32.const 332) "\14\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00M\00A\00R\00K\00 \00i\00t\00e\00r\00a\00t\00e")
(data (i32.const 376) "\13\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00M\00A\00R\00K\00 \00f\00i\00n\00i\00s\00h")
(data (i32.const 420) "\10\00\00\00g\00c\00~\00s\00t\00a\00t\00e\00 \00=\00 \00S\00W\00E\00E\00P")
(data (i32.const 456) "\12\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00S\00W\00E\00E\00P\00 \00f\00r\00e\00e")
(data (i32.const 496) "\14\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00S\00W\00E\00E\00P\00 \00f\00i\00n\00i\00s\00h")
(data (i32.const 540) "\t\00\00\00s\00t\00d\00/\00g\00c\00.\00t\00s")
(data (i32.const 564) "\n\00\00\00g\00c\00.\00c\00o\00l\00l\00e\00c\00t")
(data (i32.const 8) "\t\00\00\00s\00t\00d\00/\00g\00c\00.\00t\00s")
(export "memory" (memory $0))
(export "table" (table $0))
(export "main" (func $std/gc/main))
(func $std/gc/MyObject_visit (; 2 ;) (type $iv) (param $0 i32)
(func $std/gc/MyObject_visit (; 1 ;) (type $iv) (param $0 i32)
(nop)
)
(func $~lib/allocator/arena/__memory_allocate (; 3 ;) (type $ii) (param $0 i32) (result i32)
(func $~lib/allocator/arena/__memory_allocate (; 2 ;) (type $ii) (param $0 i32) (result i32)
(local $1 i32)
(local $2 i32)
(local $3 i32)
@ -134,26 +114,12 @@
)
(i32.const 0)
)
(func $~lib/memory/memory.allocate (; 4 ;) (type $ii) (param $0 i32) (result i32)
(func $~lib/memory/memory.allocate (; 3 ;) (type $ii) (param $0 i32) (result i32)
(call $~lib/allocator/arena/__memory_allocate
(get_local $0)
)
)
(func $~lib/collector/itcm/ManagedObject#clear (; 5 ;) (type $iv) (param $0 i32)
(call $~lib/env/trace
(i32.const 64)
(i32.const 1)
(f64.convert_u/i32
(i32.add
(get_local $0)
(i32.const 16)
)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(func $~lib/collector/itcm/ManagedObjectSet#clear (; 4 ;) (type $iv) (param $0 i32)
(i32.store
(get_local $0)
(get_local $0)
@ -163,7 +129,7 @@
(get_local $0)
)
)
(func $~lib/collector/itcm/ManagedObject#get:color (; 6 ;) (type $ii) (param $0 i32) (result i32)
(func $~lib/collector/itcm/ManagedObject#get:color (; 5 ;) (type $ii) (param $0 i32) (result i32)
(i32.and
(i32.load
(get_local $0)
@ -171,7 +137,7 @@
(i32.const 3)
)
)
(func $~lib/collector/itcm/ManagedObject#get:next (; 7 ;) (type $ii) (param $0 i32) (result i32)
(func $~lib/collector/itcm/ManagedObject#get:next (; 6 ;) (type $ii) (param $0 i32) (result i32)
(i32.and
(i32.load
(get_local $0)
@ -179,7 +145,7 @@
(i32.const -4)
)
)
(func $~lib/collector/itcm/ManagedObject#set:next (; 8 ;) (type $iiv) (param $0 i32) (param $1 i32)
(func $~lib/collector/itcm/ManagedObject#set:next (; 7 ;) (type $iiv) (param $0 i32) (param $1 i32)
(i32.store
(get_local $0)
(i32.or
@ -193,81 +159,32 @@
)
)
)
(func $~lib/collector/itcm/ManagedObject#unlink (; 9 ;) (type $iv) (param $0 i32)
(func $~lib/collector/itcm/ManagedObject#unlink (; 8 ;) (type $iv) (param $0 i32)
(local $1 i32)
(local $2 i32)
(set_local $1
(i32.store offset=4
(tee_local $1
(call $~lib/collector/itcm/ManagedObject#get:next
(get_local $0)
)
)
(call $~lib/env/trace
(i32.const 252)
(i32.const 3)
(f64.convert_u/i32
(i32.add
(tee_local $2
(tee_local $0
(i32.load offset=4
(get_local $0)
)
)
(i32.const 16)
)
)
(f64.convert_u/i32
(i32.add
(get_local $0)
(i32.const 16)
)
)
(f64.convert_u/i32
(i32.add
(get_local $1)
(i32.const 16)
)
)
(f64.const 0)
(f64.const 0)
)
(i32.store offset=4
(get_local $1)
(get_local $2)
)
(call $~lib/collector/itcm/ManagedObject#set:next
(get_local $2)
(get_local $0)
(get_local $1)
)
)
(func $~lib/collector/itcm/ManagedObject#push (; 10 ;) (type $iiv) (param $0 i32) (param $1 i32)
(func $~lib/collector/itcm/ManagedObjectSet#push (; 9 ;) (type $iiv) (param $0 i32) (param $1 i32)
(local $2 i32)
(call $~lib/env/trace
(i32.const 276)
(i32.const 3)
(f64.convert_u/i32
(i32.add
(tee_local $2
(set_local $2
(i32.load offset=4
(get_local $0)
)
)
(i32.const 16)
)
)
(f64.convert_u/i32
(i32.add
(get_local $1)
(i32.const 16)
)
)
(f64.convert_u/i32
(i32.add
(get_local $0)
(i32.const 16)
)
)
(f64.const 0)
(f64.const 0)
)
(call $~lib/collector/itcm/ManagedObject#set:next
(get_local $1)
(get_local $0)
@ -285,21 +202,7 @@
(get_local $1)
)
)
(func $~lib/collector/itcm/ManagedObject#makeGray (; 11 ;) (type $iv) (param $0 i32)
(call $~lib/env/trace
(i32.const 224)
(i32.const 1)
(f64.convert_u/i32
(i32.add
(get_local $0)
(i32.const 16)
)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(func $~lib/collector/itcm/ManagedObject#makeGray (; 10 ;) (type $iv) (param $0 i32)
(if
(i32.eq
(get_local $0)
@ -314,7 +217,7 @@
(call $~lib/collector/itcm/ManagedObject#unlink
(get_local $0)
)
(call $~lib/collector/itcm/ManagedObject#push
(call $~lib/collector/itcm/ManagedObjectSet#push
(get_global $~lib/collector/itcm/to)
(get_local $0)
)
@ -331,19 +234,10 @@
)
)
)
(func $~lib/collector/itcm/__gc_mark (; 12 ;) (type $iv) (param $0 i32)
(func $~lib/collector/itcm/__gc_mark (; 11 ;) (type $iv) (param $0 i32)
(local $1 i32)
(call $~lib/env/trace
(i32.const 204)
(i32.const 1)
(f64.convert_u/i32
(if
(get_local $0)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(if
(i32.eq
(call $~lib/collector/itcm/ManagedObject#get:color
@ -361,41 +255,8 @@
)
)
)
(func $~lib/collector/itcm/markRoots~markRoot|1 (; 13 ;) (type $iv) (param $0 i32)
(call $~lib/env/trace
(i32.const 176)
(i32.const 1)
(f64.convert_u/i32
(get_local $0)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(if
(get_local $0)
(call $~lib/collector/itcm/__gc_mark
(get_local $0)
)
)
)
(func $~lib/collector/itcm/markRoots (; 14 ;) (type $v)
(call $~lib/env/trace
(i32.const 148)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(call_indirect (type $iv)
(get_global $std/gc/obj)
(i32.const 1)
)
)
(func $~lib/collector/itcm/ManagedObject#set:color (; 15 ;) (type $iiv) (param $0 i32) (param $1 i32)
(func $~lib/collector/itcm/ManagedObject#set:color (; 12 ;) (type $iiv) (param $0 i32) (param $1 i32)
(i32.store
(get_local $0)
(i32.or
@ -409,12 +270,12 @@
)
)
)
(func $~lib/memory/memory.free (; 16 ;) (type $iv) (param $0 i32)
(func $~lib/memory/memory.free (; 13 ;) (type $iv) (param $0 i32)
(call $std/gc/MyObject_visit
(get_local $0)
)
)
(func $~lib/collector/itcm/step (; 17 ;) (type $v)
(func $~lib/collector/itcm/step (; 14 ;) (type $i) (result i32)
(local $0 i32)
(block $break|0
(block $case3|0
@ -436,15 +297,6 @@
(br $break|0)
)
)
(call $~lib/env/trace
(i32.const 36)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(set_global $~lib/collector/itcm/from
(call $~lib/memory/memory.allocate
(i32.const 16)
@ -454,7 +306,7 @@
(get_global $~lib/collector/itcm/from)
(i32.const -1)
)
(call $~lib/collector/itcm/ManagedObject#clear
(call $~lib/collector/itcm/ManagedObjectSet#clear
(get_global $~lib/collector/itcm/from)
)
(set_global $~lib/collector/itcm/to
@ -466,7 +318,7 @@
(get_global $~lib/collector/itcm/to)
(i32.const -1)
)
(call $~lib/collector/itcm/ManagedObject#clear
(call $~lib/collector/itcm/ManagedObjectSet#clear
(get_global $~lib/collector/itcm/to)
)
(set_global $~lib/collector/itcm/iter
@ -475,38 +327,13 @@
(set_global $~lib/collector/itcm/state
(i32.const 1)
)
(call $~lib/env/trace
(i32.const 84)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(call $~iterateRoots
(i32.const 1)
)
(call $~lib/env/trace
(i32.const 120)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(call $~lib/collector/itcm/markRoots)
(set_global $~lib/collector/itcm/state
(i32.const 2)
)
(call $~lib/env/trace
(i32.const 296)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(br $break|0)
)
(if
@ -519,20 +346,6 @@
(get_global $~lib/collector/itcm/to)
)
(block
(call $~lib/env/trace
(i32.const 332)
(i32.const 1)
(f64.convert_u/i32
(i32.add
(get_local $0)
(i32.const 16)
)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(set_global $~lib/collector/itcm/iter
(get_local $0)
)
@ -556,16 +369,9 @@
)
)
(block
(call $~lib/env/trace
(i32.const 376)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(call $~iterateRoots
(i32.const 1)
)
(call $~lib/collector/itcm/markRoots)
(if
(i32.eq
(call $~lib/collector/itcm/ManagedObject#get:next
@ -596,15 +402,6 @@
(set_global $~lib/collector/itcm/state
(i32.const 3)
)
(call $~lib/env/trace
(i32.const 420)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
)
)
)
@ -619,20 +416,6 @@
(get_global $~lib/collector/itcm/to)
)
(block
(call $~lib/env/trace
(i32.const 456)
(i32.const 1)
(f64.convert_u/i32
(i32.add
(get_local $0)
(i32.const 16)
)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(set_global $~lib/collector/itcm/iter
(call $~lib/collector/itcm/ManagedObject#get:next
(get_local $0)
@ -643,47 +426,22 @@
)
)
(block
(call $~lib/env/trace
(i32.const 496)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(call $~lib/collector/itcm/ManagedObject#clear
(call $~lib/collector/itcm/ManagedObjectSet#clear
(get_global $~lib/collector/itcm/to)
)
(set_global $~lib/collector/itcm/state
(i32.const 1)
)
(call $~lib/env/trace
(i32.const 84)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
)
)
)
)
(func $~lib/collector/itcm/__gc_allocate (; 18 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(call $~lib/env/trace
(i32.const 8)
(i32.ne
(get_global $~lib/collector/itcm/state)
(i32.const 1)
(f64.convert_u/i32
(get_local $0)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(func $~lib/collector/itcm/__gc_allocate (; 15 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(if
(i32.gt_u
(get_local $0)
@ -691,7 +449,9 @@
)
(unreachable)
)
(drop
(call $~lib/collector/itcm/step)
)
(i32.store offset=8
(tee_local $2
(call $~lib/memory/memory.allocate
@ -707,7 +467,7 @@
(get_local $2)
(get_global $~lib/collector/itcm/white)
)
(call $~lib/collector/itcm/ManagedObject#push
(call $~lib/collector/itcm/ManagedObjectSet#push
(get_global $~lib/collector/itcm/from)
(get_local $2)
)
@ -716,23 +476,14 @@
(i32.const 16)
)
)
(func $~lib/gc/gc.allocate (; 19 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(func $~lib/gc/gc.allocate (; 16 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(call $~lib/collector/itcm/__gc_allocate
(get_local $0)
(get_local $1)
)
)
(func $~lib/collector/itcm/__gc_collect (; 20 ;) (type $v)
(func $~lib/collector/itcm/__gc_collect (; 17 ;) (type $v)
(local $0 i32)
(call $~lib/env/trace
(i32.const 564)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(block $break|0
(block $case1|0
(br_if $case1|0
@ -750,8 +501,10 @@
)
(br $break|0)
)
(drop
(call $~lib/collector/itcm/step)
)
)
(loop $continue|1
(if
(i32.ne
@ -759,16 +512,18 @@
(i32.const 1)
)
(block
(drop
(call $~lib/collector/itcm/step)
)
(br $continue|1)
)
)
)
)
(func $~lib/gc/gc.collect (; 21 ;) (type $v)
(func $~lib/gc/gc.collect (; 18 ;) (type $v)
(call $~lib/collector/itcm/__gc_collect)
)
(func $std/gc/main (; 22 ;) (type $i) (result i32)
(func $std/gc/main (; 19 ;) (type $i) (result i32)
(if
(i32.eqz
(get_global $~started)
@ -782,12 +537,13 @@
)
(i32.const 0)
)
(func $start (; 23 ;) (type $v)
(func $start (; 20 ;) (type $v)
(local $0 i32)
(local $1 i32)
(local $2 i32)
(local $3 i32)
(set_global $~lib/allocator/arena/startOffset
(i32.const 592)
(i32.const 32)
)
(set_global $~lib/allocator/arena/offset
(get_global $~lib/allocator/arena/startOffset)
@ -805,24 +561,23 @@
(get_global $std/gc/obj)
(i32.const 123)
)
(set_global $std/gc/head
(set_local $2
(i32.load offset=4
(tee_local $0
(i32.sub
(get_global $std/gc/obj)
(i32.const 16)
)
)
(set_local $1
(i32.load offset=4
(get_global $std/gc/head)
)
)
(if
(tee_local $0
(tee_local $1
(i32.ne
(tee_local $2
(tee_local $3
(i32.and
(i32.load
(get_global $std/gc/head)
(get_local $0)
)
(i32.const -4)
)
@ -830,30 +585,30 @@
(i32.const 0)
)
)
(set_local $0
(set_local $1
(i32.ne
(get_local $1)
(get_local $2)
(i32.const 0)
)
)
)
(if
(get_local $0)
(set_local $0
(i32.eq
(get_local $2)
(get_local $1)
(set_local $1
(i32.eq
(get_local $3)
(get_local $2)
)
)
)
(if
(i32.eqz
(get_local $0)
(get_local $1)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 540)
(i32.const 8)
(i32.const 19)
(i32.const 2)
)
@ -862,12 +617,12 @@
)
(if
(i32.load offset=8
(get_global $std/gc/head)
(get_local $0)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 540)
(i32.const 8)
(i32.const 21)
(i32.const 2)
)
@ -876,12 +631,12 @@
)
(if
(i32.load offset=12
(get_global $std/gc/head)
(get_local $0)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 540)
(i32.const 8)
(i32.const 23)
(i32.const 2)
)
@ -891,14 +646,14 @@
(if
(i32.ne
(i32.load offset=16
(get_global $std/gc/head)
(get_local $0)
)
(i32.const 123)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 540)
(i32.const 8)
(i32.const 25)
(i32.const 2)
)
@ -911,4 +666,14 @@
)
(call $~lib/gc/gc.collect)
)
(func $~iterateRoots (; 21 ;) (type $iv) (param $0 i32)
(call_indirect (type $iv)
(get_global $std/gc/obj)
(get_local $0)
)
(call_indirect (type $iv)
(get_global $std/gc/obj2)
(get_local $0)
)
)
)

View File

@ -10,10 +10,10 @@ function MyObject_visit(ref: usize): void {} // function table index == classId
// allocate a managed instance
var obj: MyObject | null = changetype<MyObject>(gc.allocate(offsetof<MyObject>(), MyObject_visit));
obj.a = 123;
var head = changetype<usize>(obj) - 16;
// check header
{
let head = changetype<usize>(obj) - 16;
let next = load<u32>(head, 0) & ~3;
let prev = load<u32>(head, 4);
assert(next != 0 && prev != 0 && next == prev);
@ -29,6 +29,8 @@ gc.collect(); // should keep 'obj' because it's a referenced root (see trace out
obj = null;
gc.collect(); // should free 'obj' because it isn't referenced anymore (see trace output)
var obj2: MyObject; // should also iterate globals defined late
export function main(): i32 { return 0; }
// BEWARE: The compiler does not emit any integrations except gc.iterateRoots yet, hence trying to

View File

@ -1,13 +1,11 @@
(module
(type $iv (func (param i32)))
(type $iii (func (param i32 i32) (result i32)))
(type $iiFFFFFv (func (param i32 i32 f64 f64 f64 f64 f64)))
(type $v (func))
(type $i (func (result i32)))
(type $ii (func (param i32) (result i32)))
(type $iiv (func (param i32 i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $i (func (result i32)))
(import "env" "trace" (func $~lib/env/trace (param i32 i32 f64 f64 f64 f64 f64)))
(type $v (func))
(import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32)))
(global $~lib/internal/allocator/AL_BITS i32 (i32.const 3))
(global $~lib/internal/allocator/AL_SIZE i32 (i32.const 8))
@ -15,7 +13,7 @@
(global $~lib/internal/allocator/MAX_SIZE_32 i32 (i32.const 1073741824))
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
(global $~lib/collector/itcm/TRACE i32 (i32.const 1))
(global $~lib/collector/itcm/TRACE i32 (i32.const 0))
(global $~lib/collector/itcm/State.INIT i32 (i32.const 0))
(global $~lib/collector/itcm/State.IDLE i32 (i32.const 1))
(global $~lib/collector/itcm/State.MARK i32 (i32.const 2))
@ -28,38 +26,20 @@
(global $~lib/collector/itcm/ManagedObject.SIZE i32 (i32.const 16))
(global $~argc (mut i32) (i32.const 0))
(global $std/gc/obj (mut i32) (i32.const 0))
(global $std/gc/head (mut i32) (i32.const 0))
(global $std/gc/obj2 (mut i32) (i32.const 0))
(global $~started (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 588))
(global $HEAP_BASE i32 (i32.const 32))
(table 2 2 anyfunc)
(elem (i32.const 0) $std/gc/MyObject_visit $~lib/collector/itcm/markRoots~markRoot|1)
(elem (i32.const 0) $std/gc/MyObject_visit $~lib/collector/itcm/__gc_mark)
(memory $0 1)
(data (i32.const 8) "\0b\00\00\00g\00c\00.\00a\00l\00l\00o\00c\00a\00t\00e\00")
(data (i32.const 36) "\0c\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00I\00N\00I\00T\00")
(data (i32.const 64) "\08\00\00\00 \00 \00 \00c\00l\00e\00a\00r\00")
(data (i32.const 84) "\0f\00\00\00g\00c\00~\00s\00t\00a\00t\00e\00 \00=\00 \00I\00D\00L\00E\00")
(data (i32.const 120) "\0c\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00I\00D\00L\00E\00")
(data (i32.const 148) "\0c\00\00\00 \00 \00 \00m\00a\00r\00k\00R\00o\00o\00t\00s\00")
(data (i32.const 176) "\0b\00\00\00 \00 \00 \00m\00a\00r\00k\00R\00o\00o\00t\00")
(data (i32.const 204) "\07\00\00\00g\00c\00.\00m\00a\00r\00k\00")
(data (i32.const 224) "\0b\00\00\00 \00 \00 \00m\00a\00k\00e\00G\00r\00a\00y\00")
(data (i32.const 252) "\t\00\00\00 \00 \00 \00u\00n\00l\00i\00n\00k\00")
(data (i32.const 276) "\07\00\00\00 \00 \00 \00p\00u\00s\00h\00")
(data (i32.const 296) "\0f\00\00\00g\00c\00~\00s\00t\00a\00t\00e\00 \00=\00 \00M\00A\00R\00K\00")
(data (i32.const 332) "\14\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00M\00A\00R\00K\00 \00i\00t\00e\00r\00a\00t\00e\00")
(data (i32.const 376) "\13\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00M\00A\00R\00K\00 \00f\00i\00n\00i\00s\00h\00")
(data (i32.const 420) "\10\00\00\00g\00c\00~\00s\00t\00a\00t\00e\00 \00=\00 \00S\00W\00E\00E\00P\00")
(data (i32.const 456) "\12\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00S\00W\00E\00E\00P\00 \00f\00r\00e\00e\00")
(data (i32.const 496) "\14\00\00\00g\00c\00~\00s\00t\00e\00p\00/\00S\00W\00E\00E\00P\00 \00f\00i\00n\00i\00s\00h\00")
(data (i32.const 540) "\t\00\00\00s\00t\00d\00/\00g\00c\00.\00t\00s\00")
(data (i32.const 564) "\n\00\00\00g\00c\00.\00c\00o\00l\00l\00e\00c\00t\00")
(data (i32.const 8) "\t\00\00\00s\00t\00d\00/\00g\00c\00.\00t\00s\00")
(export "memory" (memory $0))
(export "table" (table $0))
(export "main" (func $std/gc/main))
(func $std/gc/MyObject_visit (; 2 ;) (type $iv) (param $0 i32)
(func $std/gc/MyObject_visit (; 1 ;) (type $iv) (param $0 i32)
(nop)
)
(func $~lib/allocator/arena/__memory_allocate (; 3 ;) (type $ii) (param $0 i32) (result i32)
(func $~lib/allocator/arena/__memory_allocate (; 2 ;) (type $ii) (param $0 i32) (result i32)
(local $1 i32)
(local $2 i32)
(local $3 i32)
@ -167,30 +147,14 @@
)
(i32.const 0)
)
(func $~lib/memory/memory.allocate (; 4 ;) (type $ii) (param $0 i32) (result i32)
(func $~lib/memory/memory.allocate (; 3 ;) (type $ii) (param $0 i32) (result i32)
(return
(call $~lib/allocator/arena/__memory_allocate
(get_local $0)
)
)
)
(func $~lib/collector/itcm/ManagedObject#clear (; 5 ;) (type $iv) (param $0 i32)
(call $~lib/env/trace
(i32.const 64)
(i32.const 1)
(f64.convert_u/i32
(block $~lib/collector/itcm/objToRef|inlined.0 (result i32)
(i32.add
(get_local $0)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
)
)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(func $~lib/collector/itcm/ManagedObjectSet#clear (; 4 ;) (type $iv) (param $0 i32)
(i32.store
(get_local $0)
(get_local $0)
@ -200,7 +164,7 @@
(get_local $0)
)
)
(func $~lib/collector/itcm/ManagedObject#get:color (; 6 ;) (type $ii) (param $0 i32) (result i32)
(func $~lib/collector/itcm/ManagedObject#get:color (; 5 ;) (type $ii) (param $0 i32) (result i32)
(i32.and
(i32.load
(get_local $0)
@ -208,7 +172,7 @@
(i32.const 3)
)
)
(func $~lib/collector/itcm/ManagedObject#get:next (; 7 ;) (type $ii) (param $0 i32) (result i32)
(func $~lib/collector/itcm/ManagedObject#get:next (; 6 ;) (type $ii) (param $0 i32) (result i32)
(i32.and
(i32.load
(get_local $0)
@ -219,7 +183,7 @@
)
)
)
(func $~lib/collector/itcm/ManagedObject#set:next (; 8 ;) (type $iiv) (param $0 i32) (param $1 i32)
(func $~lib/collector/itcm/ManagedObject#set:next (; 7 ;) (type $iiv) (param $0 i32) (param $1 i32)
(i32.store
(get_local $0)
(i32.or
@ -233,7 +197,7 @@
)
)
)
(func $~lib/collector/itcm/ManagedObject#unlink (; 9 ;) (type $iv) (param $0 i32)
(func $~lib/collector/itcm/ManagedObject#unlink (; 8 ;) (type $iv) (param $0 i32)
(local $1 i32)
(local $2 i32)
(set_local $1
@ -246,36 +210,6 @@
(get_local $0)
)
)
(call $~lib/env/trace
(i32.const 252)
(i32.const 3)
(f64.convert_u/i32
(block $~lib/collector/itcm/objToRef|inlined.2 (result i32)
(i32.add
(get_local $2)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
)
)
)
(f64.convert_u/i32
(block $~lib/collector/itcm/objToRef|inlined.3 (result i32)
(i32.add
(get_local $0)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
)
)
)
(f64.convert_u/i32
(block $~lib/collector/itcm/objToRef|inlined.4 (result i32)
(i32.add
(get_local $1)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
)
)
)
(f64.const 0)
(f64.const 0)
)
(i32.store offset=4
(get_local $1)
(get_local $2)
@ -285,43 +219,13 @@
(get_local $1)
)
)
(func $~lib/collector/itcm/ManagedObject#push (; 10 ;) (type $iiv) (param $0 i32) (param $1 i32)
(func $~lib/collector/itcm/ManagedObjectSet#push (; 9 ;) (type $iiv) (param $0 i32) (param $1 i32)
(local $2 i32)
(set_local $2
(i32.load offset=4
(get_local $0)
)
)
(call $~lib/env/trace
(i32.const 276)
(i32.const 3)
(f64.convert_u/i32
(block $~lib/collector/itcm/objToRef|inlined.5 (result i32)
(i32.add
(get_local $2)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
)
)
)
(f64.convert_u/i32
(block $~lib/collector/itcm/objToRef|inlined.6 (result i32)
(i32.add
(get_local $1)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
)
)
)
(f64.convert_u/i32
(block $~lib/collector/itcm/objToRef|inlined.7 (result i32)
(i32.add
(get_local $0)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
)
)
)
(f64.const 0)
(f64.const 0)
)
(call $~lib/collector/itcm/ManagedObject#set:next
(get_local $1)
(get_local $0)
@ -339,23 +243,7 @@
(get_local $1)
)
)
(func $~lib/collector/itcm/ManagedObject#makeGray (; 11 ;) (type $iv) (param $0 i32)
(call $~lib/env/trace
(i32.const 224)
(i32.const 1)
(f64.convert_u/i32
(block $~lib/collector/itcm/objToRef|inlined.1 (result i32)
(i32.add
(get_local $0)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
)
)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(func $~lib/collector/itcm/ManagedObject#makeGray (; 10 ;) (type $iv) (param $0 i32)
(if
(i32.eq
(get_local $0)
@ -370,7 +258,7 @@
(call $~lib/collector/itcm/ManagedObject#unlink
(get_local $0)
)
(call $~lib/collector/itcm/ManagedObject#push
(call $~lib/collector/itcm/ManagedObjectSet#push
(get_global $~lib/collector/itcm/to)
(get_local $0)
)
@ -390,19 +278,11 @@
)
)
)
(func $~lib/collector/itcm/__gc_mark (; 12 ;) (type $iv) (param $0 i32)
(func $~lib/collector/itcm/__gc_mark (; 11 ;) (type $iv) (param $0 i32)
(local $1 i32)
(call $~lib/env/trace
(i32.const 204)
(i32.const 1)
(f64.convert_u/i32
(if
(get_local $0)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(block
(set_local $1
(block $~lib/collector/itcm/refToObj|inlined.0 (result i32)
(i32.sub
@ -423,41 +303,9 @@
)
)
)
(func $~lib/collector/itcm/markRoots~markRoot|1 (; 13 ;) (type $iv) (param $0 i32)
(call $~lib/env/trace
(i32.const 176)
(i32.const 1)
(f64.convert_u/i32
(get_local $0)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(if
(get_local $0)
(call $~lib/collector/itcm/__gc_mark
(get_local $0)
)
)
)
(func $~lib/collector/itcm/markRoots (; 14 ;) (type $v)
(call $~lib/env/trace
(i32.const 148)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(call_indirect (type $iv)
(get_global $std/gc/obj)
(i32.const 1)
)
)
(func $~lib/collector/itcm/ManagedObject#set:color (; 15 ;) (type $iiv) (param $0 i32) (param $1 i32)
(func $~lib/collector/itcm/ManagedObject#set:color (; 12 ;) (type $iiv) (param $0 i32) (param $1 i32)
(i32.store
(get_local $0)
(i32.or
@ -474,16 +322,16 @@
)
)
)
(func $~lib/allocator/arena/__memory_free (; 16 ;) (type $iv) (param $0 i32)
(func $~lib/allocator/arena/__memory_free (; 13 ;) (type $iv) (param $0 i32)
(nop)
)
(func $~lib/memory/memory.free (; 17 ;) (type $iv) (param $0 i32)
(func $~lib/memory/memory.free (; 14 ;) (type $iv) (param $0 i32)
(call $~lib/allocator/arena/__memory_free
(get_local $0)
)
(return)
)
(func $~lib/collector/itcm/step (; 18 ;) (type $v)
(func $~lib/collector/itcm/step (; 15 ;) (type $i) (result i32)
(local $0 i32)
(local $1 i32)
(block $break|0
@ -521,15 +369,6 @@
(br $break|0)
)
(block
(call $~lib/env/trace
(i32.const 36)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(set_global $~lib/collector/itcm/from
(call $~lib/memory/memory.allocate
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
@ -539,7 +378,7 @@
(get_global $~lib/collector/itcm/from)
(i32.const -1)
)
(call $~lib/collector/itcm/ManagedObject#clear
(call $~lib/collector/itcm/ManagedObjectSet#clear
(get_global $~lib/collector/itcm/from)
)
(set_global $~lib/collector/itcm/to
@ -551,7 +390,7 @@
(get_global $~lib/collector/itcm/to)
(i32.const -1)
)
(call $~lib/collector/itcm/ManagedObject#clear
(call $~lib/collector/itcm/ManagedObjectSet#clear
(get_global $~lib/collector/itcm/to)
)
(set_global $~lib/collector/itcm/iter
@ -560,40 +399,15 @@
(set_global $~lib/collector/itcm/state
(get_global $~lib/collector/itcm/State.IDLE)
)
(call $~lib/env/trace
(i32.const 84)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
)
)
(block
(call $~lib/env/trace
(i32.const 120)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(call $~iterateRoots
(i32.const 1)
)
(call $~lib/collector/itcm/markRoots)
(set_global $~lib/collector/itcm/state
(get_global $~lib/collector/itcm/State.MARK)
)
(call $~lib/env/trace
(i32.const 296)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(br $break|0)
)
)
@ -609,22 +423,6 @@
(get_global $~lib/collector/itcm/to)
)
(block
(call $~lib/env/trace
(i32.const 332)
(i32.const 1)
(f64.convert_u/i32
(block $~lib/collector/itcm/objToRef|inlined.8 (result i32)
(i32.add
(get_local $0)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
)
)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(set_global $~lib/collector/itcm/iter
(get_local $0)
)
@ -638,7 +436,7 @@
(i32.const 1)
)
(call_indirect (type $iv)
(block $~lib/collector/itcm/objToRef|inlined.9 (result i32)
(block $~lib/collector/itcm/objToRef|inlined.0 (result i32)
(i32.add
(get_local $0)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
@ -650,16 +448,9 @@
)
)
(block
(call $~lib/env/trace
(i32.const 376)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(call $~iterateRoots
(i32.const 1)
)
(call $~lib/collector/itcm/markRoots)
(set_local $0
(call $~lib/collector/itcm/ManagedObject#get:next
(get_global $~lib/collector/itcm/iter)
@ -693,15 +484,6 @@
(set_global $~lib/collector/itcm/state
(get_global $~lib/collector/itcm/State.SWEEP)
)
(call $~lib/env/trace
(i32.const 420)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
)
)
)
@ -719,22 +501,6 @@
(get_global $~lib/collector/itcm/to)
)
(block
(call $~lib/env/trace
(i32.const 456)
(i32.const 1)
(f64.convert_u/i32
(block $~lib/collector/itcm/objToRef|inlined.10 (result i32)
(i32.add
(get_local $0)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
)
)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(set_global $~lib/collector/itcm/iter
(call $~lib/collector/itcm/ManagedObject#get:next
(get_local $0)
@ -745,49 +511,24 @@
)
)
(block
(call $~lib/env/trace
(i32.const 496)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(call $~lib/collector/itcm/ManagedObject#clear
(call $~lib/collector/itcm/ManagedObjectSet#clear
(get_global $~lib/collector/itcm/to)
)
(set_global $~lib/collector/itcm/state
(get_global $~lib/collector/itcm/State.IDLE)
)
(call $~lib/env/trace
(i32.const 84)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
)
)
(br $break|0)
)
)
(i32.ne
(get_global $~lib/collector/itcm/state)
(get_global $~lib/collector/itcm/State.IDLE)
)
(func $~lib/collector/itcm/__gc_allocate (; 19 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
)
(func $~lib/collector/itcm/__gc_allocate (; 16 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(call $~lib/env/trace
(i32.const 8)
(i32.const 1)
(f64.convert_u/i32
(get_local $0)
)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(if
(i32.gt_u
(get_local $0)
@ -798,7 +539,9 @@
)
(unreachable)
)
(drop
(call $~lib/collector/itcm/step)
)
(set_local $2
(call $~lib/memory/memory.allocate
(i32.add
@ -815,18 +558,18 @@
(get_local $2)
(get_global $~lib/collector/itcm/white)
)
(call $~lib/collector/itcm/ManagedObject#push
(call $~lib/collector/itcm/ManagedObjectSet#push
(get_global $~lib/collector/itcm/from)
(get_local $2)
)
(block $~lib/collector/itcm/objToRef|inlined.11 (result i32)
(block $~lib/collector/itcm/objToRef|inlined.1 (result i32)
(i32.add
(get_local $2)
(get_global $~lib/collector/itcm/ManagedObject.SIZE)
)
)
)
(func $~lib/gc/gc.allocate (; 20 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(func $~lib/gc/gc.allocate (; 17 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(return
(call $~lib/collector/itcm/__gc_allocate
(get_local $0)
@ -834,17 +577,8 @@
)
)
)
(func $~lib/collector/itcm/__gc_collect (; 21 ;) (type $v)
(func $~lib/collector/itcm/__gc_collect (; 18 ;) (type $v)
(local $0 i32)
(call $~lib/env/trace
(i32.const 564)
(i32.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
(f64.const 0)
)
(block $break|0
(block $case1|0
(block $case0|0
@ -866,8 +600,10 @@
(br $break|0)
)
)
(drop
(call $~lib/collector/itcm/step)
)
)
(block $break|1
(loop $continue|1
(if
@ -876,18 +612,20 @@
(get_global $~lib/collector/itcm/State.IDLE)
)
(block
(drop
(call $~lib/collector/itcm/step)
)
(br $continue|1)
)
)
)
)
)
(func $~lib/gc/gc.collect (; 22 ;) (type $v)
(func $~lib/gc/gc.collect (; 19 ;) (type $v)
(call $~lib/collector/itcm/__gc_collect)
(return)
)
(func $std/gc/main (; 23 ;) (type $i) (result i32)
(func $std/gc/main (; 20 ;) (type $i) (result i32)
(if
(i32.eqz
(get_global $~started)
@ -901,12 +639,13 @@
)
(i32.const 0)
)
(func $start (; 24 ;) (type $v)
(func $start (; 21 ;) (type $v)
(local $0 i32)
(local $1 i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(set_global $~lib/allocator/arena/startOffset
(i32.and
(i32.add
@ -935,17 +674,17 @@
(get_global $std/gc/obj)
(i32.const 123)
)
(set_global $std/gc/head
(block
(set_local $0
(i32.sub
(get_global $std/gc/obj)
(i32.const 16)
)
)
(block
(set_local $0
(set_local $1
(i32.and
(i32.load
(get_global $std/gc/head)
(get_local $0)
)
(i32.xor
(i32.const 3)
@ -953,71 +692,49 @@
)
)
)
(set_local $1
(set_local $2
(i32.load offset=4
(get_global $std/gc/head)
(get_local $0)
)
)
(if
(i32.eqz
(if (result i32)
(tee_local $2
(tee_local $3
(if (result i32)
(tee_local $2
(i32.ne
(get_local $0)
(i32.const 0)
)
)
(tee_local $3
(i32.ne
(get_local $1)
(i32.const 0)
)
)
(i32.ne
(get_local $2)
(i32.const 0)
)
(get_local $3)
)
)
(i32.eq
(get_local $0)
(get_local $1)
)
(get_local $2)
)
(get_local $3)
)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 540)
(i32.const 8)
(i32.const 19)
(i32.const 2)
)
(unreachable)
)
)
(set_local $2
(i32.load offset=8
(get_global $std/gc/head)
)
)
(if
(i32.eqz
(i32.eq
(get_local $2)
(i32.const 0)
)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 540)
(i32.const 21)
(i32.const 2)
)
(unreachable)
)
)
(set_local $3
(i32.load offset=12
(get_global $std/gc/head)
(i32.load offset=8
(get_local $0)
)
)
(if
@ -1030,29 +747,51 @@
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 540)
(i32.const 23)
(i32.const 8)
(i32.const 21)
(i32.const 2)
)
(unreachable)
)
)
(set_local $4
(i32.load offset=16
(get_global $std/gc/head)
(i32.load offset=12
(get_local $0)
)
)
(if
(i32.eqz
(i32.eq
(get_local $4)
(i32.const 0)
)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 8)
(i32.const 23)
(i32.const 2)
)
(unreachable)
)
)
(set_local $5
(i32.load offset=16
(get_local $0)
)
)
(if
(i32.eqz
(i32.eq
(get_local $5)
(i32.const 123)
)
)
(block
(call $~lib/env/abort
(i32.const 0)
(i32.const 540)
(i32.const 8)
(i32.const 25)
(i32.const 2)
)
@ -1066,4 +805,14 @@
)
(call $~lib/gc/gc.collect)
)
(func $~iterateRoots (; 22 ;) (type $iv) (param $0 i32)
(call_indirect (type $iv)
(get_global $std/gc/obj)
(get_local $0)
)
(call_indirect (type $iv)
(get_global $std/gc/obj2)
(get_local $0)
)
)
)