mmtk 0.33.0

MMTk is a framework for the design and implementation of high-performance and portable memory managers.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
# API Migration Guide

This document lists changes to the MMTk-VM API that require changes to be made by the VM bindings.
VM binding developers can use this document as a guide to update their code to maintain
compatibility with the latest release of MMTk.


## View control

Choose how many details you want to read.

{{#include ../../assets/snippets/view-controls.html}}

<!--

Notes for the mmtk-core developers:

-   Make sure you add to the **upcoming release**.  Check the current version in `Cargo.toml`.
-   You may add new items or edit existing items before a release, whichever makes sense.
-   No need to mention API changes that are source compatible and do not require VM binding code
    to be updated.
-   Use the [template](template.md).
-   100 characters per line.  Those who read this doc in text editors and IDEs will thank you.
    -   vim: "gq" formats the selected lines, and "gqap" formats one paragraph.
    -   vscode: The "Rewrap" plugin can re-wrap a paragraph with one hot key.

-->

<div id="api-migration-detail-body"><!-- We use JavaScript to process things within this div. -->

<!-- Insert new versions here -->

## 0.33.0

### `GCTriggerPolicy::on_gc_start/on_gc_end` repurposed for GC cycles

```admonish tldr
The old `on_gc_start` and `on_gc_end` (called once per STW pause) are renamed to `on_pause_start`
and `on_pause_end`. `on_pause_start` is now also called after all mutators have stopped, instead of
at the very start of GC scheduling before mutators are asked to stop. The names `on_gc_start` and
`on_gc_end` are reused for a new pair of hooks with different semantics: they are called once per
*GC cycle* rather than once per pause. For stop-the-world GCs, no changes are needed for the delegated
GC trigger; however, for concurrent GCs, the GC trigger needs to differentiate pauses and GC cycles,
and use the correct hooks correspondingly.
```

API changes:

-   trait `util::heap::GCTriggerPolicy`
    +   `on_gc_start`: Renamed to `on_pause_start`.
        *   Previously called once for every STW pause, when GC was scheduled and before mutators
            were told to stop.
        *   Now called after all mutators have stopped (i.e. once the world is actually stopped for
            the pause). Implementations that only use this hook to record a timestamp or the
            reserved-page count for computing GC time/space overhead should still work correctly,
            but the recorded time will now reflect the start of the actual pause rather than the
            start of GC scheduling (which also includes time spent waiting for mutators to reach a
            safepoint).
    +   `on_gc_end`: Renamed to `on_pause_end`.
        *   No change to timing, only the name.
    +   `on_gc_start`/`on_gc_end`: New methods that reuse the old names, but with different meaning.
        *   A GC cycle consists of one or more STW pauses plus any concurrent work in between them.
            These new hooks are called once per GC cycle, rather than once per pause.
        *   For a stop-the-world plan, a GC cycle is exactly one pause, so `on_gc_start`/`on_gc_end`
            fire at the same time as `on_pause_start`/`on_pause_end`.
        *   For a concurrent plan whose cycle spans multiple pauses (e.g. an initial mark pause and
            a final mark pause with concurrent marking in between), `on_gc_start` is only called for
            the first pause of the cycle, and `on_gc_end` only for the last.

This only affects VM bindings that provide a custom `GCTriggerPolicy` (via
`Collection::create_gc_trigger`).

### Collection enabling/disabling is now managed by MMTk instead of the VM binding

```admonish tldr
`Collection::is_collection_enabled()` is removed.  MMTk now tracks whether collection is enabled
itself, via the new, nestable `disable_collection()`/`enable_collection()` API on `MMTK` (and
`memory_manager`).
```

API changes:

-   trait `vm::Collection`
    +   `is_collection_enabled()`: Removed.
        *   Previously, the VM binding implemented this method to tell MMTk whether GC is
            currently allowed. MMTk now manages this state itself, so the binding no longer needs
            to (and no longer can) answer this question.
        *   If the binding previously disabled collection at certain times (e.g. before some
            initialization completed), it should instead call the new `memory_manager::disable_collection()`
            at the point where it used to start returning `false`, and `memory_manager::enable_collection()`
            at the point where it used to start returning `true` again.
-   module `memory_manager`
    +   `disable_collection()`: now returns `Result<bool, GcStatus>`. `Ok(true)`
        means this call actually switched collection from enabled to disabled; `Ok(false)` means
        it only increased the nesting depth of an already-disabled status. `Err(status)` means
        collection could not be disabled right now, with `status` naming why (e.g. a GC is in
        progress or has been requested); the VM binding should check safepoints, expect a pause,
        or wait for the concurrent GC to finish, then call this function again.
    *   `enable_collection()`: return true if the GC is enabled after the call. Otherwise, the function
        returns false.
    +   `is_collection_enabled()`: New. Returns whether collection is currently enabled.

See also:

-   PR: <https://github.com/mmtk/mmtk-core/pull/1457>

### `Slot` is required to implement `Sync`

```admonish tldr
`vm::slot::Slot` now needs to implement `Sync`.
```

API changes:
-   module `vm::slot`
    +   `Slot`: Now required to implement `Sync`
        *   The provided `SimpleSlot` in mmtk-core already implements `Sync`.  If the VM binding
            uses it, no change is needed.
        *   If the VM binding's `Slot` implementation does not include raw pointers (`*const T` and
            `*mut T`), chance is high that it automatically implements `Sync`.  If this is the case,
            no change is needed.
        *   Otherwise, the VM binding should declare `unsafe impl Sync for ...` for the slot type.

### Thread IDs require `Debug` instead of `Display`

```admonish tldr
`mmtk::util::os::OS::ThreadIDType` now needs to implement `Debug` instead of `Display`.
```

API changes:

-   module `util::os`
    +   `OS::ThreadIDType`: This associated type now requires `Debug` instead of `Display`.
        *   This allows platforms where the native thread ID type does not implement `Display`,
            such as `libc::pthread_t` on musl.
        *   Bindings that provide an OS implementation should derive or implement `Debug` for
            their thread ID type.

### The `<'w>` lifetime in `ObjectTracerContext`

```admonish tldr
Your existing source code probably still works.
```

API changes:

-   module `vm::scanning`
    +   `ObjectTracerContext::TracerType`: Now has a `<'w>` lifetime parameter
    +   `ObjectTracerContext::with_tracer`: Now has a `<'w>` lifetime parameter
        *   `'w` is the lifetime of the `worker` argument, and is passed to the
            `Self::TracerType<'w>` argument of the `func` callback.  It basically means the
            `ObjectTracer` provided to the `func` callback borrows the `worker` during the callback.
            This has always been true, but we now made it explicit through the lifetime parameter.

### Type argument changes in `Finalizable::keep_alive` module

```admonish tldr
`Finalizable::keep_alive` now has the `<OT: ObjectTracer>` type parameter.
```

API changes:

-   module `vm::reference_glue`
    +   `Finalizable::keep_alive`: Now has the `<OT: ObjectTracer>` type parameter instead of
        `<E: ProcessEdgesWork>`.  The `trace` parameter is now `&mut OT`.  It still has the
        `trace_object` method like the old `ProcessEdgesWork` trait, and is supposed to be used the
        same way.

### The Cargo feature "is_mmtk_object" is removed

```admonish tldr
The "is_mmtk_object" cargo feature is removed.  Anything previously enabled by the "is_mmtk_object"
feature are now enabled by the "vo_bit" feature.
```

API changes: None.  If a VM binding uses the "is_mmtk_object" feature, it should now use the
"vo_bit" feature if not already using, and existing code should still compile.

### Side metadata base addresses are no longer constants

```admonish tldr
Side metadata addresses are now chosen at runtime.  The old address constants are removed and
replaced with accessor functions that must only be called after MMTk is initialized.
```

API changes:

-   module `util::metadata::side_metadata`
    +   `GLOBAL_SIDE_METADATA_BASE_ADDRESS`: Removed.
        *   Use `global_side_metadata_base_address()` instead.
    +   `GLOBAL_SIDE_METADATA_VM_BASE_ADDRESS`: Removed.
        *   Use `global_side_metadata_vm_base_address()` instead.
    +   `VO_BIT_SIDE_METADATA_ADDR`: Removed.
        *   Use `vo_bit_side_metadata_addr()` instead.
-   module `util::metadata::vo_bit`
    +   `VO_BIT_SIDE_METADATA_ADDR`: Removed.
        *   Use `vo_bit_side_metadata_addr()` instead.

These addresses are no longer constants because MMTk now chooses the side metadata base address at
boot time. Bindings should fetch them from the accessor functions after MMTk initialization has
completed. Bindings can assume the addresses will not change once they are initialized.

## 0.32.0

### Allocation options changed

```admonish tldr
`AllocationOptions` now has multiple boolean fields instead of one `OnAllocationFail` field.  Now
polling cannot be disabled.  Instead we can now poll and over-commit in one allocation.
```

API changes:

-   module `util::alloc::allocator`
    +   `OnAllocationFail`: Removed.
    +   `AllocationOptions`: It now has two boolean fields:
        *   `allow_overcommit`
        *   `at_safepoint`
        *   `allow_oom_call`

Variants of the old `enum OnAllocationFail` should be migrated to the new API according to the
following table:

| variant         | `allow_overcommit` | `at_safepoint` | `allow_oom_call` |
|-----------------|--------------------|----------------|------------------|
| `RequestGC`     | `false`            | `true`         | `true`           |
| `ReturnFailure` | `false`            | `false`        | `false`          |
| `OverCommit`    | `true`             | `false`        | `false`          |

Note that MMTk now always polls before trying to get more pages from the page resource, and it may
trigger GC.  The old `OnAllocationFail::OverCommit` used to prevent polling, but it is no longer
possible.

See also:

-   PR: <https://github.com/mmtk/mmtk-core/pull/1400>

### Removed the notion of "mmap chunk"

```admonish tldr
Constants such as `MMAP_CHUNK_BYTES` were related to the implementation details of the memory
mapper, and should not have been exposed.
```

API changes:

-   module `util::conversions`
    +   `mmap_chunk_align_down`: Removed.
    +   `mmap_chunk_align_up`: Removed.
-   module `util::heap::vm_layout`
    +   `LOG_MMAP_CHUNK_BYTES`: Removed.
    +   `MMAP_CHUNK_BYTES`: Removed.

### `Options` no longer differentiates between environment variables and command line arguments.

```admonish tldr
We replaced both `Options::set_from_command_line` and `Options::set_from_env_var` with
`Options::set_from_string` because all options can now be set via either environment variable or
command line arguments.
```

API changes:

-   module `util::options`
    +   `Options::set_from_command_line`: Removed.
        *   Use `Options::set_from_string` instead.
    +   `Options::set_from_env_var`: Removed.
        *   Use `Options::set_from_string` instead.
    +   `Options::set_bulk_from_command_line`: Removed.
        *   Use `Options::set_bulk_from_string` instead.
    +   All `<T>` in `MMTKOption<T>` now must implement `FromStr`.
        *   This means you can parse a string into `T` when setting an `MMTKOption<T>`.  For
            example, `options.plan.set(user_input.parse()?);`.

### The feature `immix_stress_copying` is removed.

```admonish tldr
The feature `immix_stress_copying` is removed. Bindings can use MMTk options with the following values
to achieve the same behavior as before: `immix_always_defrag=true,immix_defrag_every_block=true,immix_defrag_headroom_percent=50`
```

API changes:

-   The feature `immix_stress_copying` is removed.
-   module `util::options`
    +   `Options` includes `immix_always_defrag`, which defaults to `false`.
    +   `Options` includes `immix_defrag_every_block`, which defaults to `false`.
    +   `Options` includes `immix_defrag_headroom_percent`, which defaults to `2`.

See also:

-   PR: <https://github.com/mmtk/mmtk-core/pull/1324>

## 0.30.0

### `live_bytes_in_last_gc` becomes a runtime option, and returns a map for live bytes in each space

```admonish tldr
`count_live_bytes_in_gc` is now a runtime option instead of a features (build-time), and we collect
live bytes statistics per space. Correspondingly, `memory_manager::live_bytes_in_last_gc` now returns a map for
live bytes in each space.
```

API changes:

-   module `util::options`
    +   `Options` includes `count_live_bytes_in_gc`, which defaults to `false`. This can be turned on at run-time.
    +   The old `count_live_bytes_in_gc` feature is removed.
-   module `memory_manager`
    +   `live_bytes_in_last_gc` now returns a `HashMap<&'static str, LiveBytesStats>`. The keys are
        strings for space names, and the values are statistics for live bytes in the space.

See also:

-   PR: <https://github.com/mmtk/mmtk-core/pull/1238>


### mmap-related functions require annotation

```admonish tldr
Memory-mapping functions in `mmtk::util::memory` now take an additional `MmapAnnotation` argument.
```

API changes:

-   module `util::memory`
    +   The following functions take an additional `MmapAnnotation` argument.
        *   `dzmmap`
        *   `dzmmap_noreplace`
        *   `mmap_noreserve`

## 0.28.0

### `handle_user_collection_request` returns `bool`

```admonish tldr
`memory_manager::handle_user_collection_request` now returns a boolean value to indicate whether a GC
is triggered by the method or not. Bindings may use the return value to do some post-gc cleanup, or
simply ignore the return value.
```

API changes:

-   module `memory_manager`
    +   `handle_user_collection_request` now returns `bool` to indicate if a GC is triggered by the method.
        Bindings may use the value, or simply ignore it.

See also:

-   PR: <https://github.com/mmtk/mmtk-core/issues/1205>
-   Examples:
    + https://github.com/mmtk/mmtk-julia/pull/177: Ignore return value.


### `ObjectReference` must point inside an object

```admonish tldr
`ObjectReference` is now required to be an address within an object.  The concept of "in-object
address" and related methods are removed.  Some methods which used to depend on the "in-object
address" no longer need the `<VM>` type argument.
```

API changes:

-   struct `ObjectReference`
    +   Its "raw address" must be within an object now.
    +   The following methods which were used to access the in-object address are removed.
        *   `from_address`
        *   `to_address`
        *   When accessing side metadata, the "raw address" should be used, instead.
    +   The following methods no longer have the `<VM>` type argument.
        *   `get_forwarded_object`
        *   `is_in_any_space`
        *   `is_live`
        *   `is_movable`
        *   `is_reachable`
-   module `memory_manager`
    +   `is_mmtk_object`: It now requires the address parameter to be non-zero and word-aligned.
        *   Otherwise it will not be a legal `ObjectReference` in the first place.  The user should
            filter out such illegal values.
    +   The following functions no longer have the `<VM>` type argument.
        *   `find_object_from_internal_pointer`
        *   `is_in_mmtk_space`
        *   `is_live_object`
        *   `is_pinned`
        *   `pin_object`
        *   `unpin_object`
-   struct `Region`
    +   The following methods no longer have the `<VM>` type argument.
        *   `containing`
-   trait `ObjectModel`
    +   `IN_OBJECT_ADDRESS_OFFSET`: removed because it is no longer needed.

See also:

-   PR: <https://github.com/mmtk/mmtk-core/issues/1170>
-   Examples:
    +   https://github.com/mmtk/mmtk-openjdk/pull/286: a simple case
    +   https://github.com/mmtk/mmtk-jikesrvm/issues/178: a VM that needs much change for this

## 0.27.0

### `is_mmtk_object` returns `Option<ObjectReference>`

```admonish tldr
`memory_manager::is_mmtk_object` now returns `Option<ObjectReference>` instead of `bool`.
Bindings can use the returned object reference instead of computing the object reference at the binding side.
```

API changes:
* module `memory_manager`
  - `is_mmtk_object` now returns `Option<ObjectReference>`.

See also:

-   PR: <https://github.com/mmtk/mmtk-core/pull/1165>
-   Example: <https://github.com/mmtk/mmtk-ruby/pull/86>

### Introduce `ObjectModel::IN_OBJECT_ADDRESS_OFFSET`

```admonish tldr
We used to have `ObjectModel::ref_to_address` and `ObjectModel::address_to_ref`, and require
the object reference and the in-object address to have a constant offset. Now, the two methods
are removed, and replaced with a constant `ObjectModel::IN_OBJECT_ADDRESS_OFFSET`.
```

API changes:
* trait `ObjectModel`
  - The methods `ref_to_address` and `address_to_ref` are removed.
  - Users are required to specify `IN_OBJECT_ADDRESS_OFFSET` instead, which is the offset from the object
    reference to the in-object address (the in-object address was the return value for the old `ref_to_address()`).
* type `ObjectReference`
  - Add a constant `ALIGNMENT` which equals to the word size. All object references should be at least aligned
    to the word size. This is checked in debug builds when an `ObjectReference` is constructed.

See also:

-   PR: <https://github.com/mmtk/mmtk-core/pull/1159>
-   Example: <https://github.com/mmtk/mmtk-openjdk/pull/283>

## 0.26.0

### Rename "edge" to "slot"

```admonish tldr
The word "edge" **in many identifiers** have been changed to "slot" if it actaully means slot.
Notable items include the traits `Edge`, `EdgeVisitor`, the module `edge_shape`, and member types
and functions in the `Scanning` and `VMBinding` traits.  The VM bindings should not only make
changes in response to the changes in MMTk-core, but also make changes to their own identifiers if
they also use "edge" where it should have been "slot".  The find/replace tools in text editors and
the refactoring/renaming tools in IDEs should be helpful.
```

API changes:

*   module `edge_shape` -> `slot`
*   type `RootsWorkFactory`
    -   `<ES: Edge>` -> `<SL: Slot>`
    -   `create_process_edge_roots_work` -> `create_process_roots_work`
*   type `SimpleEdge` -> `SimpleSlot`
*   type `UnimplementedMemorySliceEdgeIterator` -> `UnimplementedMemorySliceSlotIterator`
*   trait `Edge` -> `Slot`
*   trait `EdgeVisitor` -> `SlotVisitor`
    -   `<ES: Edge>` -> `<SL: Slot>`
    -   `visit_edge` -> `visit_slot`
*   trait `MemorySlice`
    -   `Edge` -> `SlotType`
    -   `EdgeIterator` -> `SlotIterator`
    -   `iter_edges` -> `iter_slots`
*   trait `Scanning`
    -   `support_edge_enqueuing` -> `support_slot_enqueuing`
    -   `scan_object`
        +   `<EV: EdgeVisitor>` -> `<SV: SlotVisitor>`
    -   `scan_roots_in_mutator_thread`
        +   Type parameter of `factory` changed. See type `RootsWorkFactory`.
    -   `scan_vm_specific_roots`
        +   Same as above.
*   trait `VMBinding`
    -   `VMEdge` -> `VMSlot`

See also:

-   PR: <https://github.com/mmtk/mmtk-core/pull/1134>
-   Example: <https://github.com/mmtk/mmtk-openjdk/pull/274>


## 0.25.0

### `ObjectReference` is no longer nullable

```admonish tldr
`ObjectReference` can no longer represent a NULL reference.  Some methods of `ObjectReference` and
the write barrier functions in `memory_manager` are changed.  VM bindings need to re-implement
methods of the `Edge`, `ObjectModel` and `ReferenceGlue` traits.
```

API changes:

*   type `ObjectReference`
    -   It can no longer represent NULL reference.
        +   It is now backed by `NonZeroUsize`, and MMTk uses `Option<ObjectReference>` universally
            when an `ObjectReference` may or may not exist.  It is more idiomatic in Rust.
    -   The constant `ObjectReference::NULL` is removed.
    -   `is_null()` is removed.
    -   `from_raw_address(addr)`
        +   The return type is changed to `Option<ObjectReference>`.
        +   It returns `None` if `addr` is not zero.
        +   If you know `addr` cannot be zero, you can use the new method
            `from_raw_address_unchecked(addr)`, instead.
*   module `mmtk::memory_manager`
    -   **Only affects users of write barriers**
    -   `object_reference_write_pre(mutator, obj, slot, target)`
        +   The `target` parameter is now `Option<ObjectReference>`.
        +   Pass `None` if the slot was holding a NULL reference or any non-reference value.
    -   `object_reference_write_post(mutator, obj, slot, target)`
        +   Same as above.
    -   `object_reference_write(mutator, obj, slot, target)`
        +   It is labelled as `#[deprecated]` and needs to be redesigned.  It cannot handle the case
            of storing a non-reference value (such as tagged small integer) into the slot.
        +   Before a replacement is available, use `object_reference_write_pre` and
            `object_reference_write_post`, instead.
*   trait `Edge`
    -   `load()`
        +   The return type is changed to `Option<ObjectReference>`.
        +   It returns `None` if the slot is holding a NULL reference or other non-reference
            values.  MMTk will skip those slots.
*   trait `ObjectModel`
    -   `copy(from, semantics, copy_context)`
        +   Previously VM bindings convert the result of `copy_context.alloc_copy()` to
            `ObjectReference` using `ObjectReference::from_raw_address()`.
        +   Because `CopyContext::alloc_copy()` never returns zero, you can use
            `ObjectReference::from_raw_address_unchecked()` to skip the zero check.
    -   `get_reference_when_copied_to(from, to)`
        +   `to` is never zero because MMTk only calls this after the destination is determined.
        +   You may skip the zero check, too.
    -   `address_to_ref(addr)`
        +   `addr` is never zero because this method is an inverse operation of
            `ref_to_address(objref)` where `objref` is never NULL.
        +   You may skip the zero check, too.
*   trait `ReferenceGlue`
    -   *Note: If your VM binding is still using `ReferenceGlue` and the reference processor and
        finalization processor in mmtk-core, it is strongly recommended to switch to the
        `Scanning::process_weak_refs` method and implement weak reference and finalization
        processing on the VM side.*
    -   `get_referent()`
        +   The return type is changed to `Option<ObjectReference>`.
        +   It now returns `None` if the referent is cleared.
    -   `clear_referent()`
        +   It now needs to be explicitly implemented because `ObjectReference::NULL` no longer
            exists.
        +   Note: The `Edge` trait does not have a method for storing NULL to a slot.  The VM
            binding needs to implement its own method to store NULL to a slot.

Not API change, but worth noting:

*   Functions that return `Option<ObjectReference>`
    -   `memory_manager::get_finalized_object`
    -   `ObjectReference::get_forwarded_object`
        +   The functions listed above did not change, as they still return
            `Option<ObjectReference>`.  But some VM bindings used to expose them to native programs
            by wrapping them into `extern "C"` functions that return `ObjectReference`, and return
            `ObjectReference::NULL` for `None`.  This is no longer possible since we removed
            `ObjectReference::NULL`.  The VM bindings should use
            `mmtk::util::api_util::NullableObjectReference` for the return type instead.

See also:

-   PR: <https://github.com/mmtk/mmtk-core/pull/1064>
-   PR: <https://github.com/mmtk/mmtk-core/pull/1130> (for write barriers)
-   Example: <https://github.com/mmtk/mmtk-openjdk/pull/265>
-   Example: <https://github.com/mmtk/mmtk-openjdk/pull/273> (for write barriers)


### Instance methods of `ObjectReference` changed

```admonish tldr
Some methods of `ObjectReference` now have a type parameter `<VM>`.  `ObjectReference::value()` is
removed.
```

API changes:

*   type `ObjectReference`
    -   The following methods now require a generic argument `<VM: VMBinding>`:
        -   `ObjectReference::is_reachable`
        -   `ObjectReference::is_live`
        -   `ObjectReference::is_movable`
        -   `ObjectReference::get_forwarded_object`
        -   `ObjectReference::is_in_any_space`
        -   `ObjectReference::is_sane`
    -   `ObjectReference::value()` is removed.
        +   Use `ObjectReference::to_raw_address()` instead.

See also:

-   PR: <https://github.com/mmtk/mmtk-core/pull/1122>
-   Example: <https://github.com/mmtk/mmtk-openjdk/pull/272>


### The GC controller (a.k.a. coordinator) is removed

```admonish tldr
The GC controller thread is removed from MMTk core.  The VM binding needs to re-implement
`Collection::spawn_gc_thread` and call `GCWorker::run` differently.
```

API changes:

*   type `GCWorker`
    -   `GCWorker::run`
        +   It now takes ownership of the `Box<GCWorker>` instance instead of borrowing it.
        +   The VM binding can simply call the method `worker.run()` on the worker instance from
            `GCThreadContext::Worker(worker)`.
*   module `mmtk::memory_manager`
    -   `start_worker`
        +   It is now a simple wrapper of `GCWorker::run` for legacy code.  It takes ownership of
            the `Box<GCWorker>` instance, too.
*   trait `Collection`
    -   `Collection::spawn_gc_thread`
        +   It no longer asks the binding to spawn the controller thread.
        +   The VM binding can simply remove the code path related to creating the controller
            thread.
        +   Note the API change when calling `GCWorker::run` or `start_worker`.

See also:

-   PR: <https://github.com/mmtk/mmtk-core/pull/1067>
-   Example: <https://github.com/mmtk/mmtk-openjdk/pull/268>

</div>

<script type="text/javascript">
const isApiMigrationGuide = true;
</script>

<!--
vim: tw=100
-->