-
Notifications
You must be signed in to change notification settings - Fork 0
/
gc.go
126 lines (96 loc) · 2.95 KB
/
gc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package main
import (
"bytes"
"fmt"
)
const (
readOnlyType = 0x2
)
func readOnlyGcHeader(id int) int {
return (id << 47) | readOnlyType
}
// ---------------------------------------------------------------------------------------------------------------------
type GcState struct {
scopes []int
roots GcRoots
}
// ---------------------------------------------------------------------------------------------------------------------
type GcRoots []GcRoot
// ---------------------------------------------------------------------------------------------------------------------
type GcRoot struct {
off int
typ *Type
}
// ---------------------------------------------------------------------------------------------------------------------
func (gr GcRoots) String() string {
buf := bytes.NewBufferString("")
for _, root := range gr {
buf.WriteString(".")
buf.WriteString(root.typ.AsmName())
}
return buf.String()
}
func (gs *GcState) OpenScope() {
gs.scopes = append(gs.scopes, len(gs.roots))
}
func (gs *GcState) CloseScope() {
gs.roots = gs.roots[:gs.scopes[len(gs.scopes)-1]]
}
func (gs *GcState) Add(off int, t *Type) {
if t.IsPointer() {
gs.roots = append(gs.roots, GcRoot{ off: off, typ: t })
}
}
func (gs *GcState) Remove(off int, t *Type) {
if t.IsPointer() {
for i, root := range gs.roots {
if root.off == off && root.typ == t {
gs.roots = append(gs.roots[:i], gs.roots[i+1:]...)
return
}
}
panic(fmt.Sprintf("GC root of type (%v) at offset (%v) not found", t, off))
}
}
func (gs *GcState) Snapshot() GcRoots {
return append([]GcRoot{}, gs.roots...)
}
// ---------------------------------------------------------------------------------------------------------------------
type GcTypes struct {
types []*Type
}
func (gt *GcTypes) AddBuiltins(symtab *SymTab) {
// Id = 0
gt.types = append(gt.types, &Type{Kind:Struct, Data: &StructType{Name: "<unknown>"}})
// ---------------------------------------------------------------------------------
// NOTE: The following 2 types must appear in this order as their ID is defined in
// in arrays.clara source code
//
// Id = 1
b := symtab.MustResolve("bytes")
gt.types = append(gt.types, b.Type)
// Id = 2
i := symtab.MustResolve("[]int")
gt.types = append(gt.types, i.Type)
// Id = 3
sa := symtab.MustResolve("[]string")
gt.types = append(gt.types, sa.Type)
// ---------------------------------------------------------------------------------
// Other heap types which do not have an explicit constructor
// Id = 4
s := symtab.MustResolve("string")
gt.types = append(gt.types, s.Type)
// Id = 5, Create fake type for all functions
fn := &Type{ Function, &FunctionType{} }
gt.types = append(gt.types, fn)
// Id = 6
bs := symtab.MustResolve("bytes")
gt.types = append(gt.types, bs.Type)
// Id = 7
t := symtab.MustResolve("[]T")
gt.types = append(gt.types, t.Type)
}
func (gt *GcTypes) AssignId(typ *Type) int {
gt.types = append(gt.types, typ)
return len(gt.types) - 1
}