Skip to content

Commit 3cca6dd

Browse files
committed
Experiment: Memory/thread-safe runtime
1 parent 897d1e3 commit 3cca6dd

File tree

67 files changed

+25866
-26733
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+25866
-26733
lines changed

std/assembly/rt/common.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,44 @@
1212
// @ts-ignore: decorator
1313
@inline export const DEBUG = true;
1414

15+
// Common root and block structure
16+
17+
// @ts-ignore: decorator
18+
@inline export const INITIALIZED: u32 = 1 << 0;
19+
// @ts-ignore: decorator
20+
@inline export const COLLECTING: u32 = 1 << 1;
21+
22+
// ╒═════════════════ Common root layout (32-bit) ═════════════════╕
23+
// 3 2 1
24+
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits
25+
// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤
26+
// │ state │
27+
// ├───────────────────────────────────────────────────────────────┤
28+
// │ data0 │
29+
// ├───────────────────────────────────────────────────────────────┤
30+
// │ ... │
31+
// ╞═══════════════════════════════════════════════════════════════╡
32+
// │ ... │
33+
@unmanaged export class ROOT {
34+
/** Runtime state, i.e. INITIALIZED, COLLECTING. */
35+
state: u32;
36+
/** Runtime lock. */
37+
lock: u32;
38+
/** Additional data, either MM or GC. */
39+
data0: usize; // MM flMap
40+
/** Additional data, either MM or GC. */
41+
data1: usize; // GC roots
42+
/** Additional data, either MM or GC. */
43+
data2: usize; // GC roots_cur
44+
/** Additional data, either MM or GC. */
45+
data3: usize; // GC roots_end
46+
}
47+
48+
// @ts-ignore: decorator
49+
@lazy export const root = changetype<ROOT>((__heap_base + AL_MASK) & ~AL_MASK);
50+
// @ts-ignore: decorator
51+
@lazy export var main = false;
52+
1553
// ╒════════════════ Common block layout (32-bit) ═════════════════╕
1654
// 3 2 1
1755
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits

std/assembly/rt/pure.ts

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { DEBUG, BLOCK_OVERHEAD } from "rt/common";
2-
import { Block, freeBlock, ROOT } from "rt/tlsf";
1+
import { DEBUG, BLOCK_OVERHEAD, root } from "rt/common";
2+
import { Block, freeBlock } from "rt/tlsf";
33
import { TypeinfoFlags } from "shared/typeinfo";
44
import { onincrement, ondecrement, onfree, onalloc } from "./rtrace";
55

@@ -124,10 +124,10 @@ function decrement(s: Block): void {
124124
__visit_members(changetype<usize>(s) + BLOCK_OVERHEAD, VISIT_DECREMENT);
125125
if (isDefined(__GC_ALL_ACYCLIC)) {
126126
if (DEBUG) assert(!(info & BUFFERED_MASK));
127-
freeBlock(ROOT, s);
127+
freeBlock(s);
128128
} else {
129129
if (!(info & BUFFERED_MASK)) {
130-
freeBlock(ROOT, s);
130+
freeBlock(s);
131131
} else {
132132
s.gcInfo = BUFFERED_MASK | COLOR_BLACK | 0;
133133
}
@@ -149,31 +149,25 @@ function decrement(s: Block): void {
149149
}
150150
}
151151

152-
/** Buffer of possible roots. */
153-
// @ts-ignore: decorator
154-
@lazy var ROOTS: usize;
155-
/** Current absolute offset into the `ROOTS` buffer. */
156-
// @ts-ignore: decorator
157-
@lazy var CUR: usize = 0;
158-
/** Current absolute end offset into the `ROOTS` buffer. */
159-
// @ts-ignore: decorator
160-
@lazy var END: usize = 0;
152+
// root.data1 : Buffer of possible roots
153+
// root.data2 : Current absolute offset into the buffer
154+
// root.data3 : Current absolute end offset into the buffer
161155

162156
/** Appends a block to possible roots. */
163157
function appendRoot(s: Block): void {
164-
var cur = CUR;
165-
if (cur >= END) {
158+
var cur = root.data2;
159+
if (cur >= root.data3) {
166160
growRoots(); // TBD: either that or pick a default and force collection on overflow
167-
cur = CUR;
161+
cur = root.data2;
168162
}
169163
store<Block>(cur, s);
170-
CUR = cur + sizeof<usize>();
164+
root.data2 = cur + sizeof<usize>();
171165
}
172166

173167
/** Grows the roots buffer if it ran full. */
174168
function growRoots(): void {
175-
var oldRoots = ROOTS;
176-
var oldSize = CUR - oldRoots;
169+
var oldRoots = root.data1;
170+
var oldSize = root.data2 - oldRoots;
177171
var newSize = max(oldSize * 2, 64 << alignof<usize>());
178172
var newRoots = __alloc(newSize, 0);
179173
if (isDefined(ASC_RTRACE)) onfree(changetype<Block>(newRoots - BLOCK_OVERHEAD)); // neglect unmanaged
@@ -182,9 +176,9 @@ function growRoots(): void {
182176
if (isDefined(ASC_RTRACE)) onalloc(changetype<Block>(oldRoots - BLOCK_OVERHEAD)); // neglect unmanaged
183177
__free(oldRoots);
184178
}
185-
ROOTS = newRoots;
186-
CUR = newRoots + oldSize;
187-
END = newRoots + newSize;
179+
root.data1 = newRoots;
180+
root.data2 = newRoots + oldSize;
181+
root.data3 = newRoots + newSize;
188182
}
189183

190184
/** Collects cyclic garbage. */
@@ -194,9 +188,9 @@ export function __collect(): void {
194188
if (isDefined(__GC_ALL_ACYCLIC)) return;
195189

196190
// markRoots
197-
var roots = ROOTS;
191+
var roots = root.data1;
198192
var cur = roots;
199-
for (let pos = cur, end = CUR; pos < end; pos += sizeof<usize>()) {
193+
for (let pos = cur, end = root.data2; pos < end; pos += sizeof<usize>()) {
200194
let s = load<Block>(pos);
201195
let info = s.gcInfo;
202196
if ((info & COLOR_MASK) == COLOR_PURPLE && (info & REFCOUNT_MASK) > 0) {
@@ -205,13 +199,13 @@ export function __collect(): void {
205199
cur += sizeof<usize>();
206200
} else {
207201
if ((info & COLOR_MASK) == COLOR_BLACK && !(info & REFCOUNT_MASK)) {
208-
freeBlock(ROOT, s);
202+
freeBlock(s);
209203
} else {
210204
s.gcInfo = info & ~BUFFERED_MASK;
211205
}
212206
}
213207
}
214-
CUR = cur;
208+
root.data2 = cur;
215209

216210
// scanRoots
217211
for (let pos = roots; pos < cur; pos += sizeof<usize>()) {
@@ -224,7 +218,7 @@ export function __collect(): void {
224218
s.gcInfo = s.gcInfo & ~BUFFERED_MASK;
225219
collectWhite(s);
226220
}
227-
CUR = roots;
221+
root.data2 = roots;
228222
}
229223

230224
/** Marks a block as gray (possible member of cycle) during the collection phase. */
@@ -261,7 +255,7 @@ function collectWhite(s: Block): void {
261255
if ((info & COLOR_MASK) == COLOR_WHITE && !(info & BUFFERED_MASK)) {
262256
s.gcInfo = (info & ~COLOR_MASK) | COLOR_BLACK;
263257
__visit_members(changetype<usize>(s) + BLOCK_OVERHEAD, VISIT_COLLECTWHITE);
264-
freeBlock(ROOT, s);
258+
freeBlock(s);
265259
}
266260
}
267261

0 commit comments

Comments
 (0)