File tree Expand file tree Collapse file tree 2 files changed +65
-0
lines changed
policy/marksweepspace/native_ms Expand file tree Collapse file tree 2 files changed +65
-0
lines changed Original file line number Diff line number Diff line change @@ -329,6 +329,56 @@ impl<VM: VMBinding> MarkSweepSpace<VM> {
329
329
}
330
330
}
331
331
332
+ /// Mark an object non-atomically. If multiple GC worker threads attempt to mark the same
333
+ /// object, more than one of them may return `true`.
334
+ fn attempt_mark_non_atomic ( & self , object : ObjectReference ) -> bool {
335
+ if !VM :: VMObjectModel :: LOCAL_MARK_BIT_SPEC . is_marked :: < VM > ( object, Ordering :: SeqCst ) {
336
+ VM :: VMObjectModel :: LOCAL_MARK_BIT_SPEC . mark :: < VM > ( object, Ordering :: SeqCst ) ;
337
+ true
338
+ } else {
339
+ false
340
+ }
341
+ }
342
+
343
+ /// Mark an object atomically.
344
+ fn attempt_mark_atomic ( & self , object : ObjectReference ) -> bool {
345
+ loop {
346
+ let old_value = VM :: VMObjectModel :: LOCAL_MARK_BIT_SPEC . load_atomic :: < VM , u8 > (
347
+ object,
348
+ None ,
349
+ Ordering :: SeqCst ,
350
+ ) ;
351
+ if old_value == 1u8 {
352
+ return false ;
353
+ }
354
+
355
+ if VM :: VMObjectModel :: LOCAL_MARK_BIT_SPEC
356
+ . compare_exchange_metadata :: < VM , u8 > (
357
+ object,
358
+ old_value,
359
+ 1u8 ,
360
+ None ,
361
+ Ordering :: SeqCst ,
362
+ Ordering :: SeqCst ,
363
+ )
364
+ . is_ok ( )
365
+ {
366
+ break ;
367
+ }
368
+ }
369
+ true
370
+ }
371
+
372
+ /// Mark an object. Return `true` if the object is newly marked. Return `false` if the object
373
+ /// was already marked.
374
+ fn attempt_mark ( & self , object : ObjectReference ) -> bool {
375
+ if VM :: UNIQUE_OBJECT_ENQUEUING {
376
+ self . attempt_mark_atomic ( object)
377
+ } else {
378
+ self . attempt_mark_non_atomic ( object)
379
+ }
380
+ }
381
+
332
382
fn trace_object < Q : ObjectQueue > (
333
383
& self ,
334
384
queue : & mut Q ,
Original file line number Diff line number Diff line change 79
79
/// Note that MMTk does not attempt to do anything to align the cursor to this value, but
80
80
/// it merely asserts with this constant.
81
81
const ALLOC_END_ALIGNMENT : usize = 1 ;
82
+
83
+ /// When set to `true`, all plans will guarantee that during each GC, each live object is
84
+ /// enqueued at most once, and therefore scanned (by either [`Scanning::scan_object`] or
85
+ /// [`Scanning::scan_object_and_trace_edges`]) at most once.
86
+ ///
87
+ /// When set to `false`, MMTk may enqueue an object multiple times due to optimizations, such as
88
+ /// using non-atomic operatios to mark objects. Consequently, an object may be scanned multiple
89
+ /// times during a GC.
90
+ ///
91
+ /// The default value is `false` because duplicated object-enqueuing is benign for most VMs, and
92
+ /// related optimizations, such as non-atomic marking, can improve GC speed. VM bindings can
93
+ /// override this if they need. For example, some VMs piggyback on object-scanning to visit
94
+ /// objects during a GC, but may have data race if multiple GC workers visit the same object at
95
+ /// the same time. Such VMs can set this constant to `true` to workaround this problem.
96
+ const UNIQUE_OBJECT_ENQUEUING : bool = false ;
82
97
}
You can’t perform that action at this time.
0 commit comments