1
1
import { AL_MASK } from "./allocator" ;
2
2
3
- /** Common runtime header used by all objects. */
3
+ /** Common runtime header of all objects. */
4
4
@unmanaged
5
5
export class HEADER {
6
- /** Unique id of the respective class. Not yet registered with GC if zero .*/
6
+ /** Unique id of the respective class or a magic value if not yet registered .*/
7
7
classId : u32 ;
8
8
/** Size of the allocated payload. */
9
9
payloadSize : u32 ;
10
- /** Reserved field for use by GC. */
10
+ /** Reserved field for use by GC. Only present if GC is. */
11
11
reserved1 : usize ; // itcm: tagged next
12
- /** Reserved field for use by GC. */
12
+ /** Reserved field for use by GC. Only present if GC is. */
13
13
reserved2 : usize ; // itcm: prev
14
14
}
15
15
16
+ /** Whether a GC is present or not. */
17
+ @inline export const GC = true ;
18
+
16
19
/** Size of the common runtime header. */
17
- @inline export const HEADER_SIZE : usize = ( offsetof < HEADER > ( ) + AL_MASK ) & ~ AL_MASK ;
18
- /** Magic value used to validate common headers. */
19
- @inline export const HEADER_MAGIC : usize = < usize > 0xA55E4B17 ;
20
+ @inline export const HEADER_SIZE : usize = GC
21
+ ? ( offsetof < HEADER > ( ) + AL_MASK ) & ~ AL_MASK // full header if GC is present
22
+ : ( offsetof < HEADER > ( "reserved1" ) + AL_MASK ) & ~ AL_MASK ; // half header if GC is absent
23
+
24
+ /** Magic value used to validate common runtime headers. */
25
+ @inline export const HEADER_MAGIC : u32 = 0xA55E4B17 ;
20
26
21
27
/** Aligns an allocation to actual block size. */
22
28
function ALIGN ( payloadSize : usize ) : usize {
@@ -33,19 +39,19 @@ function ALIGN(payloadSize: usize): usize {
33
39
function UNREF ( ref : usize ) : HEADER {
34
40
assert ( ref >= HEAP_BASE + HEADER_SIZE ) ; // must be a heap object
35
41
var header = changetype < HEADER > ( ref - HEADER_SIZE ) ;
36
- assert ( ! header . classId && header . reserved2 == HEADER_MAGIC ) ; // must be unregistered
42
+ assert ( header . classId == HEADER_MAGIC ) ; // must be unregistered
37
43
return header ;
38
44
}
39
45
40
- // === General allocation/deallocation ============================================================
41
-
42
46
/** Allocates a new object and returns a pointer to its payload. */
43
47
export function ALLOC ( payloadSize : u32 ) : usize {
44
48
var header = changetype < HEADER > ( memory . allocate ( ALIGN ( payloadSize ) ) ) ;
45
- header . classId = 0 ;
49
+ header . classId = HEADER_MAGIC ;
46
50
header . payloadSize = payloadSize ;
47
- header . reserved1 = 0 ;
48
- header . reserved2 = HEADER_MAGIC ;
51
+ if ( GC ) {
52
+ header . reserved1 = 0 ;
53
+ header . reserved2 = 0 ;
54
+ }
49
55
var ref = changetype < usize > ( header ) + HEADER_SIZE ;
50
56
memory . fill ( ref , 0 , payloadSize ) ;
51
57
return ref ;
@@ -60,9 +66,11 @@ export function REALLOC(ref: usize, newPayloadSize: u32): usize {
60
66
if ( ALIGN ( payloadSize ) < newAlignedSize ) {
61
67
// move if the allocation isn't large enough to hold the new payload
62
68
let newHeader = changetype < HEADER > ( memory . allocate ( newAlignedSize ) ) ;
63
- newHeader . classId = 0 ;
64
- newHeader . reserved1 = 0 ;
65
- newHeader . reserved2 = HEADER_MAGIC ;
69
+ newHeader . classId = HEADER_MAGIC ;
70
+ if ( GC ) {
71
+ newHeader . reserved1 = 0 ;
72
+ newHeader . reserved2 = 0 ;
73
+ }
66
74
let newRef = changetype < usize > ( newHeader ) + HEADER_SIZE ;
67
75
memory . copy ( newRef , ref , payloadSize ) ;
68
76
memory . fill ( newRef + payloadSize , 0 , newPayloadSize - payloadSize ) ;
@@ -91,22 +99,19 @@ export function FREE(ref: usize): void {
91
99
/** Registers a managed object with GC. */
92
100
export function REGISTER < T > ( ref : usize , parentRef : usize ) : void {
93
101
var header = UNREF ( ref ) ;
94
- header . classId = /* TODO: CLASSID<T>() */ 1 ;
95
- header . reserved2 = 0 ;
102
+ header . classId = /* TODO: CLASSID<T>() */ 1 ;
96
103
// TODO
97
104
}
98
105
99
- // === ArrayBuffer ================================================================================
100
-
106
+ /** ArrayBuffer base class. */
101
107
export abstract class ArrayBufferBase {
102
108
get byteLength ( ) : i32 {
103
109
var header = changetype < HEADER > ( changetype < usize > ( this ) - HEADER_SIZE ) ;
104
110
return header . payloadSize ;
105
111
}
106
112
}
107
113
108
- // === String =====================================================================================
109
-
114
+ /** String base class. */
110
115
export abstract class StringBase {
111
116
get length ( ) : i32 {
112
117
var header = changetype < HEADER > ( changetype < usize > ( this ) - HEADER_SIZE ) ;
0 commit comments