mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-05-12 15:27:24 +00:00
some thoughts on pure gc
This commit is contained in:
parent
f44dbf2646
commit
88a595f4cb
@ -1,7 +1,7 @@
|
|||||||
// A Pure Reference Counting Garbage Collector
|
// A Pure Reference Counting Garbage Collector
|
||||||
//
|
//
|
||||||
// After the paper by DAVID F. BACON, CLEMENT R. ATTANASIO, V.T. RAJAN, STEPHEN E.SMITH
|
// After the paper by DAVID F. BACON, CLEMENT R. ATTANASIO, V.T. RAJAN, STEPHEN E. SMITH
|
||||||
// D.Bacon, IBM T.J. Watson Research Center
|
// D. Bacon, IBM T.J. Watson Research Center
|
||||||
// 2001 ACM 0164-0925/99/0100-0111 $00.75
|
// 2001 ACM 0164-0925/99/0100-0111 $00.75
|
||||||
|
|
||||||
import { HEADER, HEADER_SIZE } from "../runtime";
|
import { HEADER, HEADER_SIZE } from "../runtime";
|
||||||
@ -10,8 +10,9 @@ ERROR("not implemented");
|
|||||||
|
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
|
||||||
// TODO: new builtin
|
// TODO: new builtins
|
||||||
declare function ITERATECHILDREN(s: Header, fn: (t: Header) => void): void;
|
declare function ITERATECHILDREN(s: Header, fn: (t: Header) => void): void;
|
||||||
|
declare function ISACYCLIC(s: Header): bool;
|
||||||
|
|
||||||
/** Object Colorings for Cycle Collection */
|
/** Object Colorings for Cycle Collection */
|
||||||
const enum Color {
|
const enum Color {
|
||||||
@ -42,16 +43,17 @@ var rootsBuffer: usize = 0;
|
|||||||
var rootsOffset: usize = 0; // insertion offset
|
var rootsOffset: usize = 0; // insertion offset
|
||||||
var rootsLength: usize = 0; // insertion limit
|
var rootsLength: usize = 0; // insertion limit
|
||||||
|
|
||||||
function appendRoot(header: Header): void {
|
function appendRoot(s: Header): void {
|
||||||
if (rootsOffset >= rootsLength) {
|
if (rootsOffset >= rootsLength) {
|
||||||
// grow for now
|
// grow for now
|
||||||
let newLength = rootsLength ? 2 * rootsLength : 256 * sizeof<usize>();
|
let newLength = rootsLength ? 2 * rootsLength : 256 * sizeof<usize>();
|
||||||
let newBuffer = memory.allocate(newLength);
|
let newBuffer = memory.allocate(newLength);
|
||||||
memory.copy(newBuffer, rootsBuffer, rootsLength);
|
memory.copy(newBuffer, rootsBuffer, rootsOffset);
|
||||||
rootsBuffer = newBuffer;
|
rootsBuffer = newBuffer;
|
||||||
rootsLength = newLength;
|
rootsLength = newLength;
|
||||||
|
memory.free(rootsBuffer);
|
||||||
}
|
}
|
||||||
store<usize>(rootsBuffer + rootsOffset, header);
|
store<usize>(rootsBuffer + rootsOffset, s);
|
||||||
rootsOffset += sizeof<usize>();
|
rootsOffset += sizeof<usize>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +66,7 @@ function systemFree(s: Header): void {
|
|||||||
|
|
||||||
function increment(s: Header): void {
|
function increment(s: Header): void {
|
||||||
s.rc += 1;
|
s.rc += 1;
|
||||||
s.color = Color.BLACK;
|
s.color = ISACYCLIC(s) ? Color.GREEN : Color.BLACK; // TODO: is this about correct?
|
||||||
}
|
}
|
||||||
|
|
||||||
// When a reference to a node S is deleted, the reference count is decremented. If the reference
|
// When a reference to a node S is deleted, the reference count is decremented. If the reference
|
||||||
@ -73,8 +75,15 @@ function increment(s: Header): void {
|
|||||||
|
|
||||||
function decrement(s: Header): void {
|
function decrement(s: Header): void {
|
||||||
s.rc -= 1;
|
s.rc -= 1;
|
||||||
if (!s.rc) release(s);
|
if (s.color == Color.GREEN) { // if (ISACYCLIC<T>()) { ... }
|
||||||
else possibleRoot(s);
|
if (!s.rc) systemFree(s);
|
||||||
|
// TODO: is this correct? here, if `decrement` was generic (propagate from UNLINK<T,TParent>)
|
||||||
|
// the green condition could be eliminated both here and in increment (just using black).
|
||||||
|
// acyclic types also don't need ITERATECHILDREN then as these really just inc/dec/free.
|
||||||
|
} else {
|
||||||
|
if (!s.rc) release(s);
|
||||||
|
else possibleRoot(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the reference count of a node reaches zero, the contained pointers are deleted, the object
|
// When the reference count of a node reaches zero, the contained pointers are deleted, the object
|
||||||
@ -82,7 +91,7 @@ function decrement(s: Header): void {
|
|||||||
// in the Roots buffer and will be freed later (in the procedure MarkRoots).
|
// in the Roots buffer and will be freed later (in the procedure MarkRoots).
|
||||||
|
|
||||||
function release(s: Header): void {
|
function release(s: Header): void {
|
||||||
ITERATECHILDREN(s, t => decrement(t));
|
ITERATECHILDREN(s, t => decrement(t)); // TODO: skip if acyclic ?
|
||||||
s.color = Color.BLACK;
|
s.color = Color.BLACK;
|
||||||
if (!s.buffered) systemFree(s);
|
if (!s.buffered) systemFree(s);
|
||||||
}
|
}
|
||||||
@ -208,7 +217,7 @@ function scanBlack(s: Header): void {
|
|||||||
s.color = Color.BLACK;
|
s.color = Color.BLACK;
|
||||||
ITERATECHILDREN(s, t => {
|
ITERATECHILDREN(s, t => {
|
||||||
t.rc += 1;
|
t.rc += 1;
|
||||||
if (t.color == Color.BLACK) scanBlack(t);
|
if (t.color != Color.BLACK) scanBlack(t);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +255,7 @@ function __gc_collect(): void {
|
|||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
|
|
||||||
// A significant constant-factor improvement can be obtained for cycle collection by observice that
|
// A significant constant-factor improvement can be obtained for cycle collection by observing that
|
||||||
// some objects are inherently acyclic. We speculate that they will comprise the majorits of
|
// some objects are inherently acyclic. We speculate that they will comprise the majorits of
|
||||||
// objects in many applications. Therefore, if we can avoid cycle collection for inherently acyclic
|
// objects in many applications. Therefore, if we can avoid cycle collection for inherently acyclic
|
||||||
// object, we will significantly reduce the overhead of cycle collection as a whole. [...]
|
// object, we will significantly reduce the overhead of cycle collection as a whole. [...]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user