Skip to content

Commit bc6a944

Browse files
authored
Fix GC interface and collect automatically (AssemblyScript#848)
1 parent 5b51057 commit bc6a944

39 files changed

+15152
-10146
lines changed

std/assembly/gc.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/// <reference path="./rt/index.d.ts" />
2+
3+
/** Garbage collector interface. */
4+
export namespace gc {
5+
6+
/** Can be set to `false` to disable automatic collection. Defaults to `true`. */
7+
export var auto: bool = true;
8+
9+
/** Performs a full garbage collection cycle. */
10+
export function collect(): void {
11+
__collect();
12+
}
13+
}

std/assembly/index.d.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -1032,16 +1032,12 @@ declare namespace memory {
10321032
export function compare(vl: usize, vr: usize, n: usize): i32;
10331033
}
10341034

1035-
/** Garbage collector operations. */
1035+
/** Garbage collector interface. */
10361036
declare namespace gc {
1037-
/** Whether the garbage collector interface is implemented. */
1038-
export const implemented: bool;
1037+
/** Can be set to `false` to disable automatic collection. Defaults to `true`. */
1038+
export var auto: bool;
10391039
/** Performs a full garbage collection cycle. */
10401040
export function collect(): void;
1041-
/** Retains a reference, making sure that it doesn't become collected. */
1042-
export function retain(ref: usize): void;
1043-
/** Releases a reference, allowing it to become collected. */
1044-
export function release(ref: usize): void;
10451041
}
10461042

10471043
/** Table operations. */

std/assembly/rt/tlsf.ts

+20-3
Original file line numberDiff line numberDiff line change
@@ -477,14 +477,31 @@ export function initializeRoot(): void {
477477
ROOT = root;
478478
}
479479

480+
// @ts-ignore: decorator
481+
@lazy
482+
var collectLock: bool = false;
483+
480484
/** Allocates a block of the specified size. */
481485
export function allocateBlock(root: Root, size: usize): Block {
486+
if (DEBUG) assert(!collectLock); // must not allocate while collecting
482487
var payloadSize = prepareSize(size);
483488
var block = searchBlock(root, payloadSize);
484489
if (!block) {
485-
growMemory(root, payloadSize);
486-
block = <Block>searchBlock(root, payloadSize);
487-
if (DEBUG) assert(block); // must be found now
490+
if (gc.auto) {
491+
if (DEBUG) collectLock = true;
492+
__collect();
493+
if (DEBUG) collectLock = false;
494+
block = searchBlock(root, payloadSize);
495+
if (!block) {
496+
growMemory(root, payloadSize);
497+
block = <Block>searchBlock(root, payloadSize);
498+
if (DEBUG) assert(block); // must be found now
499+
}
500+
} else {
501+
growMemory(root, payloadSize);
502+
block = <Block>searchBlock(root, payloadSize);
503+
if (DEBUG) assert(block); // must be found now
504+
}
488505
}
489506
if (DEBUG) assert((block.mmInfo & ~TAGS_MASK) >= payloadSize); // must fit
490507
block.gcInfo = 0; // RC=0

0 commit comments

Comments
 (0)