@@ -2,8 +2,9 @@ use std::sync::Mutex;
2
2
3
3
use mmtk:: {
4
4
memory_manager,
5
- scheduler:: { GCWork , WorkBucketStage } ,
5
+ scheduler:: { GCWork , GCWorker , WorkBucketStage } ,
6
6
util:: { ObjectReference , VMWorkerThread } ,
7
+ MMTK ,
7
8
} ;
8
9
9
10
use crate :: { abi:: GCThreadTLS , upcalls, Ruby } ;
@@ -65,42 +66,32 @@ impl PPPRegistry {
65
66
}
66
67
}
67
68
68
- pub fn cleanup_ppps ( & self ) {
69
- log:: debug!( "Removing dead PPPs..." ) ;
70
- {
71
- let mut ppps = self
72
- . ppps
73
- . try_lock ( )
74
- . expect ( "PPPRegistry::ppps should not have races during GC." ) ;
75
-
76
- probe ! ( mmtk_ruby, remove_dead_ppps_start, ppps. len( ) ) ;
77
- ppps. retain_mut ( |obj| {
78
- if obj. is_live ( ) {
79
- * obj = obj. get_forwarded_object ( ) . unwrap_or ( * obj) ;
80
- true
81
- } else {
82
- log:: trace!( " PPP removed: {}" , * obj) ;
83
- false
69
+ pub fn cleanup_ppps ( & self , worker : & mut GCWorker < Ruby > ) {
70
+ worker. scheduler ( ) . work_buckets [ WorkBucketStage :: VMRefClosure ] . add ( RemoveDeadPPPs ) ;
71
+ if crate :: mmtk ( ) . get_plan ( ) . current_gc_may_move_object ( ) {
72
+ let packet = {
73
+ let mut pinned_ppp_children = self
74
+ . pinned_ppp_children
75
+ . try_lock ( )
76
+ . expect ( "Unexpected contention on pinned_ppp_children" ) ;
77
+ UnpinPPPChildren {
78
+ children : std:: mem:: take ( & mut pinned_ppp_children) ,
84
79
}
85
- } ) ;
86
- probe ! ( mmtk_ruby, remove_dead_ppps_end) ;
87
- }
88
-
89
- log:: debug!( "Unpinning pinned PPP children..." ) ;
80
+ } ;
90
81
91
- if !crate :: mmtk ( ) . get_plan ( ) . current_gc_may_move_object ( ) {
92
- log:: debug!( "The current GC is non-moving. Skipped unpinning PPP children." ) ;
82
+ worker. scheduler ( ) . work_buckets [ WorkBucketStage :: VMRefClosure ] . add ( packet) ;
93
83
} else {
94
- let mut pinned_ppps = self
95
- . pinned_ppp_children
96
- . try_lock ( )
97
- . expect ( "PPPRegistry::pinned_ppp_children should not have races during GC." ) ;
98
- probe ! ( mmtk_ruby, unpin_ppp_children_start, pinned_ppps. len( ) ) ;
99
- for obj in pinned_ppps. drain ( ..) {
100
- let unpinned = memory_manager:: unpin_object ( obj) ;
101
- debug_assert ! ( unpinned) ;
102
- }
103
- probe ! ( mmtk_ruby, unpin_ppp_children_end) ;
84
+ debug ! ( "Skipping unpinning PPP children because the current GC is non-copying." ) ;
85
+ debug_assert_eq ! (
86
+ {
87
+ let pinned_ppp_children = self
88
+ . pinned_ppp_children
89
+ . try_lock( )
90
+ . expect( "Unexpected contention on pinned_ppp_children" ) ;
91
+ pinned_ppp_children. len( )
92
+ } ,
93
+ 0
94
+ ) ;
104
95
}
105
96
}
106
97
}
@@ -116,14 +107,12 @@ struct PinPPPChildren {
116
107
}
117
108
118
109
impl GCWork < Ruby > for PinPPPChildren {
119
- fn do_work (
120
- & mut self ,
121
- worker : & mut mmtk:: scheduler:: GCWorker < Ruby > ,
122
- _mmtk : & ' static mmtk:: MMTK < Ruby > ,
123
- ) {
110
+ fn do_work ( & mut self , worker : & mut GCWorker < Ruby > , _mmtk : & ' static MMTK < Ruby > ) {
124
111
let gc_tls = unsafe { GCThreadTLS :: from_vwt_check ( worker. tls ) } ;
112
+ let num_ppps = self . ppps . len ( ) ;
125
113
let mut ppp_children = vec ! [ ] ;
126
114
let mut newly_pinned_ppp_children = vec ! [ ] ;
115
+ let mut num_no_longer_ppps = 0usize ;
127
116
128
117
let visit_object = |_worker, target_object : ObjectReference , pin| {
129
118
log:: trace!(
@@ -142,6 +131,11 @@ impl GCWork<Ruby> for PinPPPChildren {
142
131
. set_temporarily_and_run_code ( visit_object, || {
143
132
for obj in self . ppps . iter ( ) . cloned ( ) {
144
133
log:: trace!( " PPP: {}" , obj) ;
134
+ if ( upcalls ( ) . is_no_longer_ppp ) ( obj) {
135
+ num_no_longer_ppps += 1 ;
136
+ log:: trace!( " No longer PPP. Skip: {}" , obj) ;
137
+ continue ;
138
+ }
145
139
( upcalls ( ) . call_gc_mark_children ) ( obj) ;
146
140
}
147
141
} ) ;
@@ -152,6 +146,16 @@ impl GCWork<Ruby> for PinPPPChildren {
152
146
}
153
147
}
154
148
149
+ let num_pinned_children = newly_pinned_ppp_children. len ( ) ;
150
+
151
+ probe ! (
152
+ mmtk_ruby,
153
+ pin_ppp_children,
154
+ num_ppps,
155
+ num_no_longer_ppps,
156
+ num_pinned_children
157
+ ) ;
158
+
155
159
{
156
160
let mut pinned_ppp_children = crate :: binding ( )
157
161
. ppp_registry
@@ -162,3 +166,68 @@ impl GCWork<Ruby> for PinPPPChildren {
162
166
}
163
167
}
164
168
}
169
+
170
+ struct RemoveDeadPPPs ;
171
+
172
+ impl GCWork < Ruby > for RemoveDeadPPPs {
173
+ fn do_work ( & mut self , _worker : & mut GCWorker < Ruby > , _mmtk : & ' static MMTK < Ruby > ) {
174
+ log:: debug!( "Removing dead PPPs..." ) ;
175
+
176
+ let registry = & crate :: binding ( ) . ppp_registry ;
177
+ {
178
+ let mut ppps = registry
179
+ . ppps
180
+ . try_lock ( )
181
+ . expect ( "PPPRegistry::ppps should not have races during GC." ) ;
182
+
183
+ let num_ppps = ppps. len ( ) ;
184
+ let mut num_no_longer_ppps = 0usize ;
185
+ let mut num_dead_ppps = 0usize ;
186
+
187
+ ppps. retain_mut ( |obj| {
188
+ if obj. is_live ( ) {
189
+ let new_obj = obj. get_forwarded_object ( ) . unwrap_or ( * obj) ;
190
+ if ( upcalls ( ) . is_no_longer_ppp ) ( new_obj) {
191
+ num_no_longer_ppps += 1 ;
192
+ log:: trace!( " No longer PPP. Remove: {}" , new_obj) ;
193
+ false
194
+ } else {
195
+ * obj = new_obj;
196
+ true
197
+ }
198
+ } else {
199
+ num_dead_ppps += 1 ;
200
+ log:: trace!( " Dead PPP removed: {}" , * obj) ;
201
+ false
202
+ }
203
+ } ) ;
204
+
205
+ probe ! (
206
+ mmtk_ruby,
207
+ remove_dead_ppps,
208
+ num_ppps,
209
+ num_no_longer_ppps,
210
+ num_dead_ppps
211
+ ) ;
212
+ }
213
+ }
214
+ }
215
+
216
+ struct UnpinPPPChildren {
217
+ children : Vec < ObjectReference > ,
218
+ }
219
+
220
+ impl GCWork < Ruby > for UnpinPPPChildren {
221
+ fn do_work ( & mut self , _worker : & mut GCWorker < Ruby > , _mmtk : & ' static MMTK < Ruby > ) {
222
+ log:: debug!( "Unpinning pinned PPP children..." ) ;
223
+
224
+ let num_children = self . children . len ( ) ;
225
+
226
+ probe ! ( mmtk_ruby, unpin_ppp_children, num_children) ;
227
+
228
+ for obj in self . children . iter ( ) {
229
+ let unpinned = memory_manager:: unpin_object ( * obj) ;
230
+ debug_assert ! ( unpinned) ;
231
+ }
232
+ }
233
+ }
0 commit comments