@@ -54,13 +54,15 @@ extern mod rustrt {
54
54
fn rust_get_stack_segment ( ) -> * StackSegment ;
55
55
}
56
56
57
- // Is fp contained in segment?
58
- unsafe fn is_frame_in_segment ( fp : * Word , segment : * StackSegment ) -> bool {
59
- let begin: Word = unsafe :: reinterpret_cast ( & segment) ;
60
- let end: Word = unsafe :: reinterpret_cast ( & ( * segment) . end ) ;
61
- let frame: Word = unsafe :: reinterpret_cast ( & fp) ;
57
+ unsafe fn bump < T , U > ( ptr : * T , count : uint ) -> * U {
58
+ return unsafe :: reinterpret_cast ( & ptr:: offset ( ptr, count) ) ;
59
+ }
62
60
63
- return begin <= frame && frame <= end;
61
+ unsafe fn align_to_pointer < T > ( ptr : * T ) -> * T {
62
+ let align = sys:: min_align_of :: < * T > ( ) ;
63
+ let ptr: uint = unsafe :: reinterpret_cast ( & ptr) ;
64
+ let ptr = ( ptr + ( align - 1 ) ) & -align;
65
+ return unsafe :: reinterpret_cast ( & ptr) ;
64
66
}
65
67
66
68
type SafePoint = { sp_meta : * Word , fn_meta : * Word } ;
@@ -69,59 +71,41 @@ type SafePoint = { sp_meta: *Word, fn_meta: *Word };
69
71
// any.
70
72
unsafe fn is_safe_point ( pc : * Word ) -> Option < SafePoint > {
71
73
let module_meta = rustrt:: rust_gc_metadata ( ) ;
72
- let num_safe_points_ptr: * u32 = unsafe :: reinterpret_cast ( & module_meta) ;
73
- let num_safe_points = * num_safe_points_ptr as Word ;
74
- let safe_points: * Word =
75
- ptr:: offset ( unsafe :: reinterpret_cast ( & module_meta) , 1 ) ;
74
+ let num_safe_points = * module_meta;
75
+ let safe_points: * Word = bump ( module_meta, 1 ) ;
76
76
77
77
if ptr:: is_null ( pc) {
78
78
return None ;
79
79
}
80
80
81
81
// FIXME (#2997): Use binary rather than linear search.
82
- let mut sp = 0 as Word ;
83
- while sp < num_safe_points {
84
- let sp_loc = * ptr:: offset ( safe_points, sp* 3 ) as * Word ;
82
+ let mut spi = 0 ;
83
+ while spi < num_safe_points {
84
+ let sp: * * Word = bump ( safe_points, spi* 3 ) ;
85
+ let sp_loc = * sp;
85
86
if sp_loc == pc {
86
- return Some (
87
- { sp_meta: * ptr:: offset ( safe_points, sp* 3 + 1 ) as * Word ,
88
- fn_meta : * ptr:: offset ( safe_points, sp* 3 + 2 ) as * Word } ) ;
87
+ return Some ( { sp_meta: * bump ( sp, 1 ) , fn_meta: * bump ( sp, 2 ) } ) ;
89
88
}
90
- sp += 1 ;
89
+ spi += 1 ;
91
90
}
92
91
return None ;
93
92
}
94
93
95
94
type Visitor = fn ( root : * * Word , tydesc : * Word ) -> bool ;
96
95
97
- unsafe fn bump < T , U > ( ptr : * T , count : uint ) -> * U {
98
- return unsafe :: reinterpret_cast ( & ptr:: offset ( ptr, count) ) ;
99
- }
100
-
101
- unsafe fn align_to_pointer < T > ( ptr : * T ) -> * T {
102
- let align = sys:: min_align_of :: < * T > ( ) ;
103
- let ptr: uint = unsafe :: reinterpret_cast ( & ptr) ;
104
- let ptr = ( ptr + ( align - 1 ) ) & -align;
105
- return unsafe :: reinterpret_cast ( & ptr) ;
106
- }
107
-
108
96
// Walks the list of roots for the given safe point, and calls visitor
109
97
// on each root.
110
98
unsafe fn walk_safe_point ( fp : * Word , sp : SafePoint , visitor : Visitor ) {
111
99
let fp_bytes: * u8 = unsafe :: reinterpret_cast ( & fp) ;
112
- let sp_meta_u32s : * u32 = unsafe :: reinterpret_cast ( & sp. sp_meta ) ;
100
+ let sp_meta : * u32 = unsafe :: reinterpret_cast ( & sp. sp_meta ) ;
113
101
114
- let num_stack_roots = * sp_meta_u32s as uint ;
115
- let num_reg_roots = * ptr:: offset ( sp_meta_u32s , 1 ) as uint ;
102
+ let num_stack_roots = * sp_meta as uint ;
103
+ let num_reg_roots = * ptr:: offset ( sp_meta , 1 ) as uint ;
116
104
117
- let stack_roots: * u32 =
118
- unsafe :: reinterpret_cast ( & ptr:: offset ( sp_meta_u32s, 2 ) ) ;
119
- let reg_roots: * u8 =
120
- unsafe :: reinterpret_cast ( & ptr:: offset ( stack_roots, num_stack_roots) ) ;
121
- let addrspaces: * Word =
122
- unsafe :: reinterpret_cast ( & ptr:: offset ( reg_roots, num_reg_roots) ) ;
123
- let tydescs: * * * Word =
124
- unsafe :: reinterpret_cast ( & ptr:: offset ( addrspaces, num_stack_roots) ) ;
105
+ let stack_roots: * u32 = bump ( sp_meta, 2 ) ;
106
+ let reg_roots: * u8 = bump ( stack_roots, num_stack_roots) ;
107
+ let addrspaces: * Word = align_to_pointer ( bump ( reg_roots, num_reg_roots) ) ;
108
+ let tydescs: * * * Word = bump ( addrspaces, num_stack_roots) ;
125
109
126
110
// Stack roots
127
111
let mut sri = 0 ;
@@ -152,13 +136,14 @@ unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) {
152
136
}
153
137
}
154
138
155
- type Memory = uint ;
156
-
157
- const task_local_heap : Memory = 1 ;
158
- const exchange_heap : Memory = 2 ;
159
- const stack : Memory = 4 ;
139
+ // Is fp contained in segment?
140
+ unsafe fn is_frame_in_segment ( fp : * Word , segment : * StackSegment ) -> bool {
141
+ let begin : Word = unsafe :: reinterpret_cast ( & segment ) ;
142
+ let end : Word = unsafe :: reinterpret_cast ( & ( * segment ) . end ) ;
143
+ let frame : Word = unsafe :: reinterpret_cast ( & fp ) ;
160
144
161
- const need_cleanup: Memory = exchange_heap | stack;
145
+ return begin <= frame && frame <= end;
146
+ }
162
147
163
148
// Find and return the segment containing the given frame pointer. At
164
149
// stack segment boundaries, returns true for boundary, so that the
@@ -191,6 +176,14 @@ unsafe fn find_segment_for_frame(fp: *Word, segment: *StackSegment)
191
176
return { segment: segment, boundary: false } ;
192
177
}
193
178
179
+ type Memory = uint ;
180
+
181
+ const task_local_heap: Memory = 1 ;
182
+ const exchange_heap: Memory = 2 ;
183
+ const stack: Memory = 4 ;
184
+
185
+ const need_cleanup: Memory = exchange_heap | stack;
186
+
194
187
// Walks stack, searching for roots of the requested type, and passes
195
188
// each root to the visitor.
196
189
unsafe fn walk_gc_roots ( mem : Memory , sentinel : * * Word , visitor : Visitor ) {
0 commit comments