Skip to content

Commit 6cac4ff

Browse files
Move triplespace backup instructions to new chapter, underneath task (#269)
1 parent 9d3bc03 commit 6cac4ff

File tree

3 files changed

+187
-183
lines changed

3 files changed

+187
-183
lines changed

docs/tutorial/src/SUMMARY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
- [Allocation](./mygc/ss/alloc.md)
1616
- [Collection](./mygc/ss/collection.md)
1717
- [Exercise](./mygc/ss/exercise.md)
18+
- [Exercise solution](./mygc/ss/exercise_solution.md)
1819
- [Building a generational copying GC](./mygc/gencopy.md)
19-
- [Further Reading](./further_reading.md)
20+
- [Further Reading](./further_reading.md)

docs/tutorial/src/mygc/gencopy.md

Lines changed: 0 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -19,185 +19,3 @@ collections needed is greatly reduced.
1919

2020
This section is currently incomplete. Instructions for building a
2121
generational copying (gencopy) collector will be added in future.
22-
23-
24-
## Triplespace backup instructions
25-
26-
First, rename all instances of `mygc` to `triplespace`, and add it as a
27-
module by following the instructions in [Create MyGC](./create.md).
28-
29-
In `global.rs`:
30-
31-
1. Add a `youngspace` field to `pub struct TripleSpace`:
32-
33-
```rust
34-
pub struct TripleSpace<VM: VMBinding> {
35-
pub hi: AtomicBool,
36-
pub copyspace0: CopySpace<VM>,
37-
pub copyspace1: CopySpace<VM>,
38-
pub youngspace: CopySpace<VM>, // Add this!
39-
pub common: CommonPlan<VM>,
40-
}
41-
```
42-
43-
2. Define the parameters for the youngspace in `new()` in
44-
`Plan for TripleSpace`:
45-
```rust
46-
fn new(
47-
vm_map: &'static VMMap,
48-
mmapper: &'static Mmapper,
49-
options: Arc<UnsafeOptionsWrapper>,
50-
_scheduler: &'static MMTkScheduler<Self::VM>,
51-
) -> Self {
52-
//change - again, completely changed.
53-
let mut heap = HeapMeta::new(HEAP_START, HEAP_END);
54-
55-
TripleSpace {
56-
hi: AtomicBool::new(false),
57-
copyspace0: CopySpace::new(
58-
"copyspace0",
59-
false,
60-
true,
61-
VMRequest::discontiguous(),
62-
vm_map,
63-
mmapper,
64-
&mut heap,
65-
),
66-
copyspace1: CopySpace::new(
67-
"copyspace1",
68-
true,
69-
true,
70-
VMRequest::discontiguous(),
71-
vm_map,
72-
mmapper,
73-
&mut heap,
74-
),
75-
76-
// Add this!
77-
youngspace: CopySpace::new(
78-
"youngspace",
79-
true,
80-
true,
81-
VMRequest::discontiguous(),
82-
vm_map,
83-
mmapper,
84-
&mut heap,
85-
),
86-
common: CommonPlan::new(vm_map, mmapper, options, heap, &TRIPLESPACE_CONSTRAINTS),
87-
}
88-
}
89-
```
90-
3. Initialise the youngspace in `gc_init()`:
91-
```rust
92-
fn gc_init(
93-
&mut self,
94-
heap_size: usize,
95-
vm_map: &'static VMMap,
96-
scheduler: &Arc<MMTkScheduler<VM>>,
97-
) {
98-
self.common.gc_init(heap_size, vm_map, scheduler);
99-
self.copyspace0.init(&vm_map);
100-
self.copyspace1.init(&vm_map);
101-
self.youngspace.init(&vm_map); // Add this!
102-
}
103-
```
104-
4. Prepare the youngspace (as a fromspace) in `prepare()`:
105-
```rust
106-
fn prepare(&self, tls: OpaquePointer) {
107-
self.common.prepare(tls, true);
108-
self.hi
109-
.store(!self.hi.load(Ordering::SeqCst), Ordering::SeqCst);
110-
let hi = self.hi.load(Ordering::SeqCst);
111-
self.copyspace0.prepare(hi);
112-
self.copyspace1.prepare(!hi);
113-
self.youngspace.prepare(true); // Add this!
114-
}
115-
```
116-
5. Release the youngspace in `release()`:
117-
```rust
118-
fn release(&self, tls: OpaquePointer) {
119-
self.common.release(tls, true);
120-
self.fromspace().release();
121-
self.youngspace().release(); // Add this!
122-
}
123-
```
124-
6. Under the reference functions `tospace()` and `fromspace()`, add a similar
125-
reference function `youngspace()`:
126-
```rust
127-
pub fn youngspace(&self) -> &CopySpace<VM> {
128-
&self.youngspace
129-
}
130-
```
131-
132-
In `mutator.rs`:
133-
1. Map a bump pointer to the youngspace (replacing the one mapped to the
134-
tospace) in `space_mapping` in `create_triplespace_mutator()`:
135-
```rust
136-
space_mapping: box vec![
137-
(AllocatorSelector::BumpPointer(0), plan.youngspace()), // Change this!
138-
(
139-
AllocatorSelector::BumpPointer(1),
140-
plan.common.get_immortal(),
141-
),
142-
(AllocatorSelector::LargeObject(0), plan.common.get_los()),
143-
],
144-
```
145-
2. Rebind the bump pointer to youngspace (rather than the tospace) in
146-
`triplespace_mutator_release()`:
147-
```rust
148-
pub fn triplespace_mutator_release<VM: VMBinding> (
149-
mutator: &mut Mutator<VM>,
150-
_tls: OpaquePointer
151-
) {
152-
let bump_allocator = unsafe {
153-
mutator
154-
.allocators
155-
. get_allocator_mut(
156-
mutator.config.allocator_mapping[AllocationType::Default]
157-
)
158-
}
159-
.downcast_mut::<BumpAllocator<VM>>()
160-
.unwrap();
161-
bump_allocator.rebind(Some(mutator.plan.youngspace())); // Change this!
162-
}
163-
```
164-
165-
In `gc_work.rs`:
166-
1. Add the youngspace to trace_object, following the same format as
167-
the tospace and fromspace:
168-
```rust
169-
fn trace_object(&mut self, object: ObjectReference) -> ObjectReference {
170-
if object.is_null() {
171-
return object;
172-
}
173-
174-
// Add this!
175-
else if self.plan().youngspace().in_space(object) {
176-
self.plan().youngspace.trace_object::<Self, TripleSpaceCopyContext<VM>>(
177-
self,
178-
object,
179-
super::global::ALLOC_TripleSpace,
180-
unsafe { self.worker().local::<TripleSpaceCopyContext<VM>>() },
181-
)
182-
}
183-
184-
else if self.plan().tospace().in_space(object) {
185-
self.plan().tospace().trace_object::<Self, TripleSpaceCopyContext<VM>>(
186-
self,
187-
object,
188-
super::global::ALLOC_TripleSpace,
189-
unsafe { self.worker().local::<MyGCCopyContext<VM>>() },
190-
)
191-
} else if self.plan().fromspace().in_space(object) {
192-
self.plan().fromspace().trace_object::<Self, MyGCCopyContext<VM>>(
193-
self,
194-
object,
195-
super::global::ALLOC_TripleSpace,
196-
unsafe { self.worker().local::<TripleSpaceCopyContext<VM>>() },
197-
)
198-
} else {
199-
self.plan().common.trace_object::<Self, TripleSpaceCopyContext<VM>>(self, object)
200-
}
201-
}
202-
}
203-
```
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# Triplespace backup instructions
2+
3+
This is *one* possible implementation of the Triplespace collector, provided
4+
in case you are stuck on the exercise.
5+
6+
**Attempt the exercise yourself before reading this.**
7+
8+
First, rename all instances of `mygc` to `triplespace`, and add it as a
9+
module by following the instructions in [Create MyGC](./create.md).
10+
11+
In `global.rs`:
12+
13+
1. Add a `youngspace` field to `pub struct TripleSpace`:
14+
15+
```rust
16+
pub struct TripleSpace<VM: VMBinding> {
17+
pub hi: AtomicBool,
18+
pub copyspace0: CopySpace<VM>,
19+
pub copyspace1: CopySpace<VM>,
20+
pub youngspace: CopySpace<VM>, // Add this!
21+
pub common: CommonPlan<VM>,
22+
}
23+
```
24+
25+
2. Define the parameters for the youngspace in `new()` in
26+
`Plan for TripleSpace`:
27+
```rust
28+
fn new(
29+
vm_map: &'static VMMap,
30+
mmapper: &'static Mmapper,
31+
options: Arc<UnsafeOptionsWrapper>,
32+
_scheduler: &'static MMTkScheduler<Self::VM>,
33+
) -> Self {
34+
//change - again, completely changed.
35+
let mut heap = HeapMeta::new(HEAP_START, HEAP_END);
36+
37+
TripleSpace {
38+
hi: AtomicBool::new(false),
39+
copyspace0: CopySpace::new(
40+
"copyspace0",
41+
false,
42+
true,
43+
VMRequest::discontiguous(),
44+
vm_map,
45+
mmapper,
46+
&mut heap,
47+
),
48+
copyspace1: CopySpace::new(
49+
"copyspace1",
50+
true,
51+
true,
52+
VMRequest::discontiguous(),
53+
vm_map,
54+
mmapper,
55+
&mut heap,
56+
),
57+
58+
// Add this!
59+
youngspace: CopySpace::new(
60+
"youngspace",
61+
true,
62+
true,
63+
VMRequest::discontiguous(),
64+
vm_map,
65+
mmapper,
66+
&mut heap,
67+
),
68+
common: CommonPlan::new(vm_map, mmapper, options, heap, &TRIPLESPACE_CONSTRAINTS),
69+
}
70+
}
71+
```
72+
3. Initialise the youngspace in `gc_init()`:
73+
```rust
74+
fn gc_init(
75+
&mut self,
76+
heap_size: usize,
77+
vm_map: &'static VMMap,
78+
scheduler: &Arc<MMTkScheduler<VM>>,
79+
) {
80+
self.common.gc_init(heap_size, vm_map, scheduler);
81+
self.copyspace0.init(&vm_map);
82+
self.copyspace1.init(&vm_map);
83+
self.youngspace.init(&vm_map); // Add this!
84+
}
85+
```
86+
4. Prepare the youngspace (as a fromspace) in `prepare()`:
87+
```rust
88+
fn prepare(&self, tls: OpaquePointer) {
89+
self.common.prepare(tls, true);
90+
self.hi
91+
.store(!self.hi.load(Ordering::SeqCst), Ordering::SeqCst);
92+
let hi = self.hi.load(Ordering::SeqCst);
93+
self.copyspace0.prepare(hi);
94+
self.copyspace1.prepare(!hi);
95+
self.youngspace.prepare(true); // Add this!
96+
}
97+
```
98+
5. Release the youngspace in `release()`:
99+
```rust
100+
fn release(&self, tls: OpaquePointer) {
101+
self.common.release(tls, true);
102+
self.fromspace().release();
103+
self.youngspace().release(); // Add this!
104+
}
105+
```
106+
6. Under the reference functions `tospace()` and `fromspace()`, add a similar
107+
reference function `youngspace()`:
108+
```rust
109+
pub fn youngspace(&self) -> &CopySpace<VM> {
110+
&self.youngspace
111+
}
112+
```
113+
114+
In `mutator.rs`:
115+
1. Map a bump pointer to the youngspace (replacing the one mapped to the
116+
tospace) in `space_mapping` in `create_triplespace_mutator()`:
117+
```rust
118+
space_mapping: box vec![
119+
(AllocatorSelector::BumpPointer(0), plan.youngspace()), // Change this!
120+
(
121+
AllocatorSelector::BumpPointer(1),
122+
plan.common.get_immortal(),
123+
),
124+
(AllocatorSelector::LargeObject(0), plan.common.get_los()),
125+
],
126+
```
127+
2. Rebind the bump pointer to youngspace (rather than the tospace) in
128+
`triplespace_mutator_release()`:
129+
```rust
130+
pub fn triplespace_mutator_release<VM: VMBinding> (
131+
mutator: &mut Mutator<VM>,
132+
_tls: OpaquePointer
133+
) {
134+
let bump_allocator = unsafe {
135+
mutator
136+
.allocators
137+
. get_allocator_mut(
138+
mutator.config.allocator_mapping[AllocationType::Default]
139+
)
140+
}
141+
.downcast_mut::<BumpAllocator<VM>>()
142+
.unwrap();
143+
bump_allocator.rebind(Some(mutator.plan.youngspace())); // Change this!
144+
}
145+
```
146+
147+
In `gc_work.rs`:
148+
1. Add the youngspace to trace_object, following the same format as
149+
the tospace and fromspace:
150+
```rust
151+
fn trace_object(&mut self, object: ObjectReference) -> ObjectReference {
152+
if object.is_null() {
153+
return object;
154+
}
155+
156+
// Add this!
157+
else if self.plan().youngspace().in_space(object) {
158+
self.plan().youngspace.trace_object::<Self, TripleSpaceCopyContext<VM>>(
159+
self,
160+
object,
161+
super::global::ALLOC_TripleSpace,
162+
unsafe { self.worker().local::<TripleSpaceCopyContext<VM>>() },
163+
)
164+
}
165+
166+
else if self.plan().tospace().in_space(object) {
167+
self.plan().tospace().trace_object::<Self, TripleSpaceCopyContext<VM>>(
168+
self,
169+
object,
170+
super::global::ALLOC_TripleSpace,
171+
unsafe { self.worker().local::<MyGCCopyContext<VM>>() },
172+
)
173+
} else if self.plan().fromspace().in_space(object) {
174+
self.plan().fromspace().trace_object::<Self, MyGCCopyContext<VM>>(
175+
self,
176+
object,
177+
super::global::ALLOC_TripleSpace,
178+
unsafe { self.worker().local::<TripleSpaceCopyContext<VM>>() },
179+
)
180+
} else {
181+
self.plan().common.trace_object::<Self, TripleSpaceCopyContext<VM>>(self, object)
182+
}
183+
}
184+
}
185+
```

0 commit comments

Comments
 (0)