1
1
use crate :: JuliaVM ;
2
- use crate :: {
3
- get_mutator_from_ref, get_next_julia_mutator, reset_mutator_count, MUTATORS , MUTATOR_TLS ,
4
- SINGLETON ,
5
- } ;
2
+ use crate :: { get_mutator_from_ref, MUTATORS , MUTATOR_TLS , SINGLETON } ;
6
3
use mmtk:: util:: opaque_pointer:: * ;
7
4
use mmtk:: util:: Address ;
8
5
use mmtk:: vm:: ActivePlan ;
9
6
use mmtk:: Mutator ;
10
7
use mmtk:: Plan ;
11
8
use mmtk:: { plan:: ObjectQueue , scheduler:: GCWorker , util:: ObjectReference } ;
12
9
10
+ use std:: sync:: RwLockReadGuard ;
11
+
12
+ pub struct JuliaMutatorIterator < ' a > {
13
+ guard : RwLockReadGuard < ' a , Vec < ObjectReference > > ,
14
+ cursor : usize ,
15
+ }
16
+
17
+ impl < ' a > JuliaMutatorIterator < ' a > {
18
+ fn new ( guard : RwLockReadGuard < ' a , Vec < ObjectReference > > ) -> Self {
19
+ Self {
20
+ guard : guard,
21
+ cursor : 0 ,
22
+ }
23
+ }
24
+ }
25
+
26
+ impl < ' a > Iterator for JuliaMutatorIterator < ' a > {
27
+ type Item = & ' a mut Mutator < JuliaVM > ;
28
+
29
+ fn next ( & mut self ) -> Option < Self :: Item > {
30
+ let ref mutators = self . guard ;
31
+
32
+ let mutator_idx = self . cursor ;
33
+ self . cursor += 1 ;
34
+
35
+ let mutator = mutators. get ( mutator_idx) ;
36
+
37
+ match mutator {
38
+ Some ( m) => {
39
+ let mutator = unsafe { get_mutator_from_ref ( * m) } ;
40
+ Some ( unsafe { & mut * mutator } )
41
+ }
42
+ None => None ,
43
+ }
44
+ }
45
+ }
46
+
13
47
pub struct VMActivePlan { }
14
48
15
49
impl ActivePlan < JuliaVM > for VMActivePlan {
@@ -18,7 +52,7 @@ impl ActivePlan<JuliaVM> for VMActivePlan {
18
52
}
19
53
20
54
fn number_of_mutators ( ) -> usize {
21
- unimplemented ! ( )
55
+ Self :: mutators ( ) . count ( )
22
56
}
23
57
24
58
fn is_mutator ( tls : VMThread ) -> bool {
@@ -35,30 +69,9 @@ impl ActivePlan<JuliaVM> for VMActivePlan {
35
69
unimplemented ! ( )
36
70
}
37
71
38
- fn reset_mutator_iterator ( ) {
39
- unsafe { reset_mutator_count ( ) }
40
- }
41
-
42
- fn get_next_mutator ( ) -> Option < & ' static mut Mutator < JuliaVM > > {
43
- let mutators = MUTATORS . read ( ) . unwrap ( ) ;
44
- // println!("All mutators: {:?}", mutators.iter());
45
-
46
- let mutator_idx = unsafe { get_next_julia_mutator ( ) } ;
47
-
48
- // println!("Next mutator is: {:?}", mutator_idx);
49
-
50
- let mutator = mutators. get ( mutator_idx) ;
51
-
52
- let res = match mutator {
53
- Some ( m) => {
54
- let mutator = unsafe { get_mutator_from_ref ( * m) } ;
55
- // println!("Next mutator is: {:?}", mutator);
56
- Some ( unsafe { & mut * mutator } )
57
- }
58
- None => None ,
59
- } ;
60
-
61
- res
72
+ fn mutators < ' a > ( ) -> Box < dyn Iterator < Item = & ' a mut Mutator < JuliaVM > > + ' a > {
73
+ let guard = MUTATORS . read ( ) . unwrap ( ) ;
74
+ Box :: new ( JuliaMutatorIterator :: new ( guard) )
62
75
}
63
76
64
77
fn vm_trace_object < Q : ObjectQueue > (
@@ -71,29 +84,24 @@ impl ActivePlan<JuliaVM> for VMActivePlan {
71
84
}
72
85
}
73
86
74
- #[ no_mangle]
75
- pub extern "C" fn get_next_mutator_tls ( ) -> OpaquePointer {
76
- let mutators = MUTATORS . read ( ) . unwrap ( ) ;
77
-
78
- let mutator_idx = unsafe { get_next_julia_mutator ( ) } ;
79
- let mutator = mutators. get ( mutator_idx) ;
80
-
81
- let res = match mutator {
82
- Some ( m) => {
83
- let mutator = unsafe { get_mutator_from_ref ( * m) } ;
87
+ // Expose the mutator iterator so they can be used in C.
84
88
85
- unsafe { ( * mutator) . mutator_tls . 0 . 0 }
86
- }
87
- None => {
88
- unsafe { reset_mutator_count ( ) }
89
- OpaquePointer :: from_address ( unsafe { Address :: zero ( ) } )
90
- }
91
- } ;
89
+ #[ no_mangle]
90
+ pub extern "C" fn new_mutator_iterator ( ) -> * mut JuliaMutatorIterator < ' static > {
91
+ let guard = MUTATORS . read ( ) . unwrap ( ) ;
92
+ Box :: into_raw ( Box :: new ( JuliaMutatorIterator :: new ( guard) ) )
93
+ }
92
94
93
- res
95
+ #[ no_mangle]
96
+ pub extern "C" fn get_next_mutator_tls ( iter : * mut JuliaMutatorIterator < ' static > ) -> OpaquePointer {
97
+ match unsafe { iter. as_mut ( ) } . unwrap ( ) . next ( ) {
98
+ Some ( m) => m. mutator_tls . 0 . 0 ,
99
+ None => OpaquePointer :: from_address ( Address :: ZERO ) ,
100
+ }
94
101
}
95
102
96
103
#[ no_mangle]
97
- pub extern "C" fn reset_count_tls ( ) {
98
- unsafe { reset_mutator_count ( ) }
104
+ pub extern "C" fn close_mutator_iterator ( iter : * mut JuliaMutatorIterator < ' static > ) {
105
+ // The boxed pointer will get dropped
106
+ let _to_drop = unsafe { Box :: from_raw ( iter) } ;
99
107
}
0 commit comments