This commit is contained in:
dcode
2019-03-14 05:11:03 +01:00
parent 6163a73ab5
commit a5e14a0eaa
24 changed files with 739 additions and 102 deletions

View File

@ -1,8 +1,10 @@
// Largely based on Bach Le's μgc, see: https://github.com/bullno1/ugc
// @ts-ignore: decorator
@inline const TRACE = false;
/** Size of a managed object header. */
// @ts-ignore: decorator
@inline export const HEADER_SIZE: usize = (offsetof<ManagedObject>() + AL_MASK) & ~AL_MASK;
import { AL_MASK, MAX_SIZE_32 } from "../util/allocator";
@ -146,6 +148,7 @@ function step(): void {
if (obj !== toSpace) {
if (TRACE) trace("gc~step/MARK iterate", 1, objToRef(obj));
iter = obj;
// @ts-ignore: cast
obj.color = <i32>!white;
// if (TRACE) {
// trace(" next/prev/hook", 3,
@ -163,6 +166,7 @@ function step(): void {
let from = fromSpace;
fromSpace = toSpace;
toSpace = from;
// @ts-ignore: cast
white = <i32>!white;
iter = from.next;
state = State.SWEEP;
@ -188,14 +192,17 @@ function step(): void {
}
}
// @ts-ignore: decorator
@inline function refToObj(ref: usize): ManagedObject {
return changetype<ManagedObject>(ref - HEADER_SIZE);
}
// @ts-ignore: decorator
@inline function objToRef(obj: ManagedObject): usize {
return changetype<usize>(obj) + HEADER_SIZE;
}
// @ts-ignore: decorator
@global @unsafe export function __gc_allocate( // TODO: make this register only / reuse header
size: usize,
markFn: (ref: usize) => void
@ -210,12 +217,15 @@ function step(): void {
return objToRef(obj);
}
// @ts-ignore: decorator
@global @unsafe export function __gc_link(parentRef: usize, childRef: usize): void {
if (TRACE) trace("gc.link", 2, parentRef, childRef);
var parent = refToObj(parentRef);
// @ts-ignore: cast
if (parent.color == <i32>!white && refToObj(childRef).color == white) parent.makeGray();
}
// @ts-ignore: decorator
@global @unsafe export function __gc_mark(ref: usize): void {
if (TRACE) trace("gc.mark", 1, ref);
if (ref) {
@ -224,6 +234,7 @@ function step(): void {
}
}
// @ts-ignore: decorator
@global @unsafe export function __gc_collect(): void {
if (TRACE) trace("gc.collect");
// begin collecting if not yet collecting