Skip to content

Commit 0e207b9

Browse files
committed
initial gc stuff
1 parent 2b30d28 commit 0e207b9

File tree

9 files changed

+320
-111
lines changed

9 files changed

+320
-111
lines changed

src/compiler/scala/tools/nsc/backend/llvm/GenLLVM.scala

Lines changed: 136 additions & 98 deletions
Large diffs are not rendered by default.

src/llvmrt/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ WARNINGS = -Wall
33
CPPFLAGS = `icu-config --cppflags`
44
CFLAGS = -g $(WARNINGS) -std=c99 -fexceptions `llvm-config --cflags $(COMPONENTS)`
55
CXXFLAGS = -g $(WARNINGS) -fexceptions `llvm-config --cxxflags $(COMPONENTS)`
6-
LDFLAGS = `icu-config --ldflags-searchpath --ldflags-icuio` `llvm-config --ldflags $(COMPONENTS)` `apr-1-config --link-ld --libs` -all_load
6+
LDFLAGS = `icu-config --ldflags-searchpath --ldflags-icuio` `llvm-config --ldflags $(COMPONENTS)` `apr-1-config --link-ld --libs`
77
LDLIBS = `icu-config --ldflags-libsonly --ldflags-icuio` `llvm-config --libs $(COMPONENTS)` -lm
88

99
RTOBJECTS = runtime.bc object.bc boxes.bc arrays.bc strings.bc fp.bc io.bc

src/llvmrt/arrays.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <stdlib.h>
77
#include <stdio.h>
88

9+
#include "gc.h"
10+
911
static void *vtable_array[] = {
1012
method_java_Dlang_DObject_Mclone_Rjava_Dlang_DObject,
1113
method_java_Dlang_DObject_Mequals_Ajava_Dlang_DObject_Rscala_DBoolean,
@@ -24,6 +26,7 @@ struct klass *arrayOf(struct klass *klass)
2426
ac->instsize = 0;
2527
ac->super = &class_java_Dlang_DObject;
2628
ac->vtable = vtable_array;
29+
ac->npointers = 0;
2730
ac->numiface = 0;
2831
ac->arrayklass = NULL;
2932
ac->elementklass = klass;
@@ -32,7 +35,7 @@ struct klass *arrayOf(struct klass *klass)
3235
return klass->arrayklass;
3336
}
3437

35-
#define PRIM_ARRAY(t) struct klass t ## _array = { { sizeof("]" # t)-1, "]" # t }, 0, NULL, NULL, NULL, NULL, 0 }
38+
#define PRIM_ARRAY(t) struct klass t ## _array = { { sizeof("]" # t)-1, "]" # t }, 0, &class_java_Dlang_DObject, vtable_array, NULL, NULL, 0, 0 }
3639

3740
PRIM_ARRAY(bool);
3841
PRIM_ARRAY(byte);
@@ -93,25 +96,25 @@ new_array(uint8_t k, struct klass *et, int32_t ndims, int32_t dim0, ...)
9396
break;
9497
}
9598
datasize = sizeof(struct array) + dim0 * eltsize;
96-
data = a = calloc(1, datasize);
99+
data = a = gcalloc(datasize);
97100
a->super.klass = aclass;
98101
a->length = dim0;
99102
va_start(dims, dim0);
100103
for (int32_t n = 0; n < ndims - 1; n++) {
101104
int32_t dimN = va_arg(dims, int32_t);
102105
void **td;
103106
aclass = arrayOf(aclass);
104-
a = calloc(1, sizeof(struct array) + dimN * sizeof(void*));
107+
a = gcalloc(sizeof(struct array) + dimN * sizeof(void*));
105108
a->super.klass = aclass;
106109
a->length = dimN;
107110
for (size_t i = 0; i < dimN; i++) {
108111
void *de;
109-
de = malloc(datasize);
112+
de = gcalloc(datasize);
110113
memcpy(de, data, datasize);
111114
((void**)a->data)[i] = de;
112115
}
113116
/* FIXME - extra allocation overhead */
114-
free(data);
117+
// free(data);
115118
datasize = sizeof(struct array) + dimN * sizeof(void*);
116119
data = a;
117120
}

src/llvmrt/gc.c

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
#include <stdio.h>
4+
#include <stdbool.h>
5+
6+
struct gcobj {
7+
struct gcobj* prev;
8+
struct gcobj* nextwork;
9+
struct java_lang_Object obj[];
10+
}
11+
12+
static struct gcobj* head = NULL;
13+
14+
/* 1MB shadow stack */
15+
#define STACK_SIZE (1024*1024/sizeof(struct gcobj*))
16+
static struct gcobj* shadowstack[STACK_SIZE];
17+
static struct gcobj** shadowsp = &(shadowstack[0]);
18+
static struct gcobj** shadowlimit = &(shadowstack[STACK_SIZE]);
19+
20+
#define ROOT_SIZE (1024)
21+
static struct java_lang_Object** staticroots[ROOT_SIZE];
22+
static struct java_lang_Object*** nextroot = &(staticroots[0]);
23+
static struct java_lang_Object*** rootlimit = &(staticroots[ROOT_SIZE]);
24+
25+
static size_t heapsize = 0;
26+
#define HEAPLIMIT (64*1024*1024)
27+
28+
static inline struct gcobj* object2gc(struct java_lang_Object *obj) {
29+
return (struct gcobj*)(((void*)obj)-offsetof(struct gcobj, obj[0]));
30+
}
31+
32+
static inline struct java_lang_Object* gc2object(struct gcobj *gc) {
33+
return &(gc->obj[0]);
34+
}
35+
36+
struct java_lang_Object* rt_new(struct klass *klass)
37+
{
38+
return gcalloc(klass->instsize);
39+
}
40+
41+
struct java_lang_Object* gcalloc(size_t nbytes) {
42+
size_t objsize = sizeof(struct gcobj)+nbytes;
43+
if (heapsize + objsize > HEAPLIMIT) marksweep();
44+
if (heapsize + objsize > HEAPLIMIT) {
45+
fprintf(stderr, "Out of heap\n");
46+
abort();
47+
}
48+
struct gcobj* gcp = (struct gcobj*)calloc(1, objsize);
49+
struct java_lang_Object* obj = gc2object(gcp);
50+
gcp->prev = head;
51+
head = gcp;
52+
rt_initobj(obj, klass);
53+
return obj;
54+
}
55+
56+
void rt_addroot(struct java_lang_Object** obj) {
57+
if (nextroot == rootlimit) {
58+
fprintf(stderr, "Too many roots\n");
59+
fflush(stderr);
60+
abort();
61+
}
62+
*(nextroot++) = obj;
63+
}
64+
65+
void rt_pushref(struct java_lang_Object* obj) {
66+
if (obj == NULL) return;
67+
if (shadowsp == shadowlimit) {
68+
fprintf(stderr, "Stack overflow\n");
69+
fflush(stderr);
70+
abort();
71+
}
72+
*(shadowsp++) = object2gc(obj);
73+
}
74+
75+
void rt_popref(uint32_t n) {
76+
if (shadowsp-n < &(shadowstack[0])) {
77+
fprintf(stderr, "Stack underflow\n");
78+
fflush(stderr);
79+
abort();
80+
}
81+
shadowsp-=n;
82+
}
83+
84+
void marksweep() {
85+
struct gcobj* workq = NULL;
86+
for (struct java_lang_Object** curp = &(staticroots[0]); curp < nextroot; curp++) {
87+
struct gcobj* cur = object2gc(*curp);
88+
if (!cur->nextwork) {
89+
if (workq) {
90+
cur->nextwork = workq;
91+
} else {
92+
cur->nextwork = cur;
93+
}
94+
workq = cur;
95+
}
96+
}
97+
for (struct gcobj **curp = &(shadowstack[0]); curp < shadowsp; curp++) {
98+
struct gcobj* cur = *curp;
99+
if (!cur->nextwork) {
100+
if (workq) {
101+
cur->nextwork = workq;
102+
} else {
103+
cur->nextwork = cur;
104+
}
105+
workq = cur;
106+
}
107+
}
108+
while (workq) {
109+
struct gcobj* cur = workq;
110+
struct java_lang_Object* obj = gc2object(cur);
111+
struct klass* k = obj->klass;
112+
if (k->instsize == 0) {
113+
struct array* a = (struct array*)obj;
114+
if (k->elementklass) {
115+
struct java_lang_Object** data = (struct java_lang_Object**)&(a->data[0]);
116+
for (size_t i = 0; i < a->length; i++) {
117+
struct java_lang_Object* p = *(data+i);
118+
struct gcobj* gcp = object2gc(p);
119+
if (gcp->nextwork == NULL) {
120+
gcp->nextwork = workq;
121+
workq = gcp;
122+
}
123+
}
124+
}
125+
} else {
126+
while (k != class_java_Dlang_DObject) {
127+
struct klass* sk = k->super;
128+
struct java_lang_Object** ps;
129+
ps = (struct reference*)(((char*)obj)+sk->instsize);
130+
for (size_t i = 0; i < k->npointers; ++i) {
131+
struct java_lang_Object* p = (ps+i)->object;
132+
struct gcobj* gcp = object2gc(p);
133+
if (gcp->nextwork == NULL) {
134+
gcp->nextwork = workq;
135+
workq = gcp;
136+
}
137+
}
138+
k = sk;
139+
}
140+
}
141+
if (workq->nextwork == workq) {
142+
workq == NULL;
143+
}
144+
}
145+
/* everything live has non-null nextwork */
146+
workq = head;
147+
head = NULL;
148+
while (workq) {
149+
struct gcobj* cur = workq;
150+
workq = cur->prev;
151+
if (cur->nextwork) {
152+
/* cur is live */
153+
cur->prev = head
154+
head = cur;
155+
cur->nextwork = NULL;
156+
} else {
157+
if (cur->klass-> == /*...*/) {
158+
}
159+
free(cur);
160+
}
161+
}
162+
}

src/llvmrt/gc.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef GC_H
2+
#define GC_H
3+
4+
struct java_lang_Object;
5+
6+
struct java_lang_Object* gcalloc(size_t nbytes);
7+
void rt_pushref(struct java_lang_Object* obj);
8+
void rt_popref(size_t n);
9+
10+
#endif

src/llvmrt/klass.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct klass {
2222
void **vtable;
2323
struct klass *arrayklass;
2424
struct klass *elementklass;
25+
uint32_t npointers;
2526
uint32_t numiface;
2627
struct ifaceinfo ifaces[];
2728
};

src/llvmrt/object.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct klass class_java_Dlang_DObject = {
2020
NULL,
2121
NULL,
2222
0,
23+
0,
2324
};
2425

2526
int32_t

src/llvmrt/runtime.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,6 @@ static void printclassname(FILE* f, struct klass *klass)
1212
fprintf(f, "%.*s", klass->name.len, klass->name.bytes);
1313
}
1414

15-
struct java_lang_Object *rt_new(struct klass *klass)
16-
{
17-
struct java_lang_Object* obj = (struct java_lang_Object*)calloc(1, klass->instsize);
18-
rt_initobj(obj, klass);
19-
return obj;
20-
}
21-
2215
void rt_initobj(struct java_lang_Object *object, struct klass *klass)
2316
{
2417
object->klass = klass;

src/llvmrt/strings.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ struct klass class_java_Dlang_DString = {
3939
NULL,
4040
NULL,
4141
0,
42+
0,
4243
};
4344

4445
void

0 commit comments

Comments
 (0)