1
1
// Rust garbage collection.
2
2
3
3
#include < algorithm>
4
+ #include < iostream>
4
5
#include < utility>
5
6
#include < vector>
6
7
#include < stdint.h>
7
8
8
9
#include " rust_gc.h"
9
10
#include " rust_internal.h"
11
+ #include " rust_shape.h"
10
12
11
13
#ifdef __WIN32__
12
14
#include < windows.h>
@@ -24,13 +26,10 @@ struct frame {
24
26
uint8_t *bp; // The frame pointer.
25
27
void (*ra)(); // The return address.
26
28
27
- frame (void *in_bp) : bp((uint8_t *)in_bp) {}
28
-
29
- inline void read_ra () {
30
- ra = *(void (**)())(bp + sizeof (void *));
31
- }
29
+ frame (void *in_bp, void (*in_ra)()) : bp((uint8_t *)in_bp), ra(in_ra) {}
32
30
33
31
inline void next () {
32
+ ra = *(void (**)())(bp + sizeof (void *));
34
33
bp = *(uint8_t **)bp;
35
34
}
36
35
};
@@ -106,11 +105,15 @@ class safe_point_map {
106
105
107
106
class gc {
108
107
private:
108
+ rust_task *task;
109
+
109
110
void mark (std::vector<root> &roots);
110
111
void sweep ();
111
112
112
113
public:
113
- void run (rust_task *task);
114
+ gc (rust_task *in_task) : task(in_task) {}
115
+
116
+ void run ();
114
117
std::vector<frame> backtrace ();
115
118
};
116
119
@@ -127,6 +130,14 @@ gc::mark(std::vector<root> &roots) {
127
130
std::vector<root>::iterator ri = roots.begin (), rend = roots.end ();
128
131
while (ri < rend) {
129
132
DPRINT (" root: %p\n " , ri->data );
133
+
134
+ shape::arena arena;
135
+ shape::type_param *params = shape::type_param::make (ri->tydesc ,
136
+ arena);
137
+ shape::log log (task, ri->tydesc ->shape , params,
138
+ ri->tydesc ->shape_tables , ri->data , std::cerr);
139
+ log.walk (true );
140
+
130
141
++ri;
131
142
}
132
143
// TODO
@@ -140,17 +151,21 @@ gc::sweep() {
140
151
std::vector<frame>
141
152
gc::backtrace () {
142
153
std::vector<frame> frames;
143
- frame f (__builtin_frame_address (0 ));
154
+
155
+ // Ideally we would use the current value of EIP here, but there's no
156
+ // portable way to get that and there are never any GC roots in our C++
157
+ // frames anyhow.
158
+ frame f (__builtin_frame_address (0 ), (void (*)())NULL );
159
+
144
160
while (f.ra != END_OF_STACK_RA) {
145
- f.read_ra ();
146
161
frames.push_back (f);
147
162
f.next ();
148
163
}
149
164
return frames;
150
165
}
151
166
152
167
void
153
- gc::run (rust_task *task ) {
168
+ gc::run () {
154
169
safe_point_map map;
155
170
156
171
// Find roots.
@@ -187,8 +202,8 @@ maybe_gc(rust_task *task) {
187
202
}
188
203
189
204
if (zeal) {
190
- gc gc;
191
- gc.run (task );
205
+ gc gc (task) ;
206
+ gc.run ();
192
207
}
193
208
}
194
209
0 commit comments