|
1 | 1 | // All functions here are extern function. There is no point for marking them as unsafe. |
2 | 2 | #![allow(clippy::not_unsafe_ptr_arg_deref)] |
3 | 3 |
|
| 4 | +use std::ffi::CStr; |
| 5 | + |
4 | 6 | use crate::abi; |
5 | 7 | use crate::binding::RubyBinding; |
6 | 8 | use crate::mmtk; |
7 | 9 | use crate::Ruby; |
8 | 10 | use mmtk::memory_manager; |
| 11 | +use mmtk::memory_manager::mmtk_init; |
9 | 12 | use mmtk::scheduler::{GCController, GCWorker}; |
10 | 13 | use mmtk::util::constants::MIN_OBJECT_SIZE; |
| 14 | +use mmtk::util::options::PlanSelector; |
11 | 15 | use mmtk::util::{Address, ObjectReference}; |
12 | 16 | use mmtk::util::{VMMutatorThread, VMThread, VMWorkerThread}; |
13 | 17 | use mmtk::AllocationSemantics; |
14 | 18 | use mmtk::MMTKBuilder; |
15 | 19 | use mmtk::Mutator; |
16 | 20 |
|
| 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. |
17 | 29 | #[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 }; |
20 | 32 | 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 | + |
23 | 58 | let binding = RubyBinding::new(mmtk_static, upcalls); |
24 | 59 |
|
25 | 60 | crate::BINDING |
|
0 commit comments