Skip to content

Commit 989740f

Browse files
committed
Strongly-typed API for setting MMTk options
After the MMTKBuilder refactoring in mmtk-core, mmtk-ruby now has access to the strongly-typed Options struct. This allows us to provide a strongly-typed API for setting the options, instead of serializing option values into strings and set them via environment variables or API functions based on string-parsing. We now provide API for setting the plan and the heap size. More options can be made available later. Environment variables MMTK_* still work.
1 parent dc42592 commit 989740f

File tree

1 file changed

+39
-4
lines changed

1 file changed

+39
-4
lines changed

mmtk/src/api.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,60 @@
11
// All functions here are extern function. There is no point for marking them as unsafe.
22
#![allow(clippy::not_unsafe_ptr_arg_deref)]
33

4+
use std::ffi::CStr;
5+
46
use crate::abi;
57
use crate::binding::RubyBinding;
68
use crate::mmtk;
79
use crate::Ruby;
810
use mmtk::memory_manager;
11+
use mmtk::memory_manager::mmtk_init;
912
use mmtk::scheduler::{GCController, GCWorker};
1013
use mmtk::util::constants::MIN_OBJECT_SIZE;
14+
use mmtk::util::options::PlanSelector;
1115
use mmtk::util::{Address, ObjectReference};
1216
use mmtk::util::{VMMutatorThread, VMThread, VMWorkerThread};
1317
use mmtk::AllocationSemantics;
1418
use mmtk::MMTKBuilder;
1519
use mmtk::Mutator;
1620

21+
/// Create an MMTKBuilder instance with default options.
22+
/// This instance shall be consumed by `mmtk_init_binding`.
23+
#[no_mangle]
24+
pub extern "C" fn mmtk_builder_default() -> *mut MMTKBuilder {
25+
Box::into_raw(Box::new(MMTKBuilder::default()))
26+
}
27+
28+
/// Set the `heap_size` option.
1729
#[no_mangle]
18-
pub extern "C" fn mmtk_init_binding(heap_size: usize, upcalls: *const abi::RubyUpcalls) {
19-
let mut builder = MMTKBuilder::default();
30+
pub extern "C" fn mmtk_builder_set_heap_size(builder: *mut MMTKBuilder, heap_size: usize) {
31+
let builder = unsafe { &mut *builder };
2032
builder.options.heap_size.set(heap_size);
21-
let mmtk = builder.build();
22-
let mmtk_static = Box::leak(Box::new(mmtk));
33+
}
34+
35+
/// Set the plan. `plan_name` is a case-sensitive C-style ('\0'-terminated) string matching
36+
/// one of the cases of `enum PlanSelector`.
37+
#[no_mangle]
38+
pub extern "C" fn mmtk_builder_set_plan(builder: *mut MMTKBuilder, plan_name: *const libc::c_char) {
39+
let builder = unsafe { &mut *builder };
40+
let plan_name_cstr = unsafe { CStr::from_ptr(plan_name) };
41+
let plan_name_str = plan_name_cstr.to_str().unwrap();
42+
let plan_selector = plan_name_str.parse::<PlanSelector>().unwrap();
43+
builder.options.plan.set(plan_selector);
44+
}
45+
46+
/// Build an MMTk instance.
47+
///
48+
/// - `builder` is the pointer to the `MMTKBuilder` instance cretaed by the
49+
/// `mmtk_builder_default()` function, and the `MMTKBuilder` will be consumed after building
50+
/// the MMTk instance.
51+
/// - `upcalls` points to the struct that contains upcalls. It is allocated in C as static.
52+
#[no_mangle]
53+
pub extern "C" fn mmtk_init_binding(builder: *mut MMTKBuilder, upcalls: *const abi::RubyUpcalls) {
54+
let builder = unsafe { Box::from_raw(builder) };
55+
let mmtk_boxed = mmtk_init(&builder);
56+
let mmtk_static = Box::leak(Box::new(mmtk_boxed));
57+
2358
let binding = RubyBinding::new(mmtk_static, upcalls);
2459

2560
crate::BINDING

0 commit comments

Comments
 (0)