Skip to content

Commit 32b5071

Browse files
authored
Moving to stable Rust (#147)
This PR removes use of nightly features. * `once_cell`: replaced by the `once_cell` crate. * `vec_into_raw_parts`: replaced by the actual implementation of the method in the binding. * `box_syntax`: `box X` -> `Box::new(X)`. * `specialization`: The code used to use `specialization` for type equality in traits `ArrayOopDesc<T>`. * `ArrayOopDesc<T>` is used to describe different Java arrays. In OpenJDK's code base (C++), `arrayOopDesc` has subclasses `objArrayOopDesc` (for arrays of objects) and `typeArrayOopDesc` (for arrays of primitive types). In the binding, `ArrayOopDesc<Oop>` is `objArrayOopDesc`, and `ArrayOopDesc<f64/i64/etc>` is `typeArrayOopDesc`. * Now for type equality, an enum for types is used for where type equality is needed. * `ArrayOopsDesc` no longer takes any type parameter. * `ArrayOopsDesc::data() -> &[T]` takes a Rust type parameter that provides a Rust slice to access the array data.
1 parent cb77425 commit 32b5071

File tree

7 files changed

+74
-57
lines changed

7 files changed

+74
-57
lines changed

mmtk/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ openjdk_version = "67d5d2b16aacb2ea948552fab2323ebd0abbe924"
2020
[dependencies]
2121
libc = "0.2"
2222
lazy_static = "1.1"
23+
once_cell = "1.10.0"
2324
# Be very careful to commit any changes to the following mmtk dependency, as our CI scripts (including mmtk-core CI)
2425
# rely on matching these lines to modify them: e.g. comment out the git dependency and use the local path.
2526
# These changes are safe:
2627
# - change branch
2728
# - change repo name
2829
# But other changes including adding/removing whitespaces in commented lines may break the CI.
29-
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "cd6d8984c10c294c991dcd5f154ce41073c06ab9" }
30+
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "cacded40b7622e97dea56a83179aaa6af42920d0" }
3031
# Uncomment the following to build locally
3132
# mmtk = { path = "../repos/mmtk-core" }
3233

mmtk/rust-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
nightly-2022-02-11
1+
stable

mmtk/src/abi.rs

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,8 @@ use mmtk::util::ObjectReference;
55
use mmtk::util::{Address, OpaquePointer};
66
use std::ffi::CStr;
77
use std::fmt;
8-
use std::marker::PhantomData;
98
use std::{mem, slice};
109

11-
trait EqualTo<T> {
12-
const VALUE: bool;
13-
}
14-
15-
impl<T, U> EqualTo<U> for T {
16-
default const VALUE: bool = false;
17-
}
18-
19-
impl<T> EqualTo<T> for T {
20-
const VALUE: bool = true;
21-
}
22-
23-
pub const fn type_equal<T, U>() -> bool {
24-
<T as EqualTo<U>>::VALUE
25-
}
26-
2710
#[repr(i32)]
2811
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
2912
#[allow(dead_code)]
@@ -36,6 +19,30 @@ pub enum KlassID {
3619
ObjArray,
3720
}
3821

22+
#[repr(i32)]
23+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
24+
#[allow(dead_code)]
25+
#[allow(non_camel_case_types)]
26+
pub enum BasicType {
27+
T_BOOLEAN = 4,
28+
T_CHAR = 5,
29+
T_FLOAT = 6,
30+
T_DOUBLE = 7,
31+
T_BYTE = 8,
32+
T_SHORT = 9,
33+
T_INT = 10,
34+
T_LONG = 11,
35+
T_OBJECT = 12,
36+
T_ARRAY = 13,
37+
T_VOID = 14,
38+
T_ADDRESS = 15,
39+
T_NARROWOOP = 16,
40+
T_METADATA = 17,
41+
T_NARROWKLASS = 18,
42+
T_CONFLICT = 19, // for stack value type with conflicting contents
43+
T_ILLEGAL = 99,
44+
}
45+
3946
#[repr(C)]
4047
pub struct Klass {
4148
vptr: OpaquePointer,
@@ -296,8 +303,8 @@ impl From<&OopDesc> for ObjectReference {
296303
}
297304

298305
impl OopDesc {
299-
pub unsafe fn as_array_oop<T>(&self) -> ArrayOop<T> {
300-
&*(self as *const OopDesc as *const ArrayOopDesc<T>)
306+
pub unsafe fn as_array_oop(&self) -> ArrayOop {
307+
&*(self as *const OopDesc as *const ArrayOopDesc)
301308
}
302309

303310
pub fn get_field_address(&self, offset: i32) -> Address {
@@ -325,7 +332,7 @@ impl OopDesc {
325332
} else if lh <= Klass::LH_NEUTRAL_VALUE {
326333
if lh < Klass::LH_NEUTRAL_VALUE {
327334
// Calculate array size
328-
let array_length = self.as_array_oop::<()>().length();
335+
let array_length = self.as_array_oop().length();
329336
let mut size_in_bytes: usize =
330337
(array_length as usize) << Klass::layout_helper_log2_element_size(lh);
331338
size_in_bytes += Klass::layout_helper_header_size(lh) as usize;
@@ -340,17 +347,21 @@ impl OopDesc {
340347
}
341348

342349
#[repr(C)]
343-
pub struct ArrayOopDesc<T>(OopDesc, PhantomData<T>);
350+
pub struct ArrayOopDesc(OopDesc);
344351

345-
pub type ArrayOop<T> = &'static ArrayOopDesc<T>;
352+
pub type ArrayOop = &'static ArrayOopDesc;
346353

347-
impl<T> ArrayOopDesc<T> {
348-
const ELEMENT_TYPE_SHOULD_BE_ALIGNED: bool = type_equal::<T, f64>() || type_equal::<T, i64>();
354+
impl ArrayOopDesc {
349355
const LENGTH_OFFSET: usize = mem::size_of::<Self>();
350-
fn header_size() -> usize {
356+
357+
fn element_type_should_be_aligned(ty: BasicType) -> bool {
358+
ty == BasicType::T_DOUBLE || ty == BasicType::T_LONG
359+
}
360+
361+
fn header_size(ty: BasicType) -> usize {
351362
let typesize_in_bytes =
352363
conversions::raw_align_up(Self::LENGTH_OFFSET + BYTES_IN_INT, BYTES_IN_LONG);
353-
if Self::ELEMENT_TYPE_SHOULD_BE_ALIGNED {
364+
if Self::element_type_should_be_aligned(ty) {
354365
conversions::raw_align_up(typesize_in_bytes / BYTES_IN_WORD, BYTES_IN_LONG)
355366
} else {
356367
typesize_in_bytes / BYTES_IN_WORD
@@ -359,12 +370,16 @@ impl<T> ArrayOopDesc<T> {
359370
fn length(&self) -> i32 {
360371
unsafe { *((self as *const _ as *const u8).add(Self::LENGTH_OFFSET) as *const i32) }
361372
}
362-
fn base(&self) -> *const T {
363-
let base_offset_in_bytes = Self::header_size() * BYTES_IN_WORD;
364-
unsafe { (self as *const _ as *const u8).add(base_offset_in_bytes) as _ }
373+
fn base(&self, ty: BasicType) -> Address {
374+
let base_offset_in_bytes = Self::header_size(ty) * BYTES_IN_WORD;
375+
Address::from_ptr(unsafe { (self as *const _ as *const u8).add(base_offset_in_bytes) })
365376
}
366-
pub fn data(&self) -> &[T] {
367-
unsafe { slice::from_raw_parts(self.base(), self.length() as _) }
377+
// This provides an easy way to access the array data in Rust. However, the array data
378+
// is Java types, so we have to map Java types to Rust types. The caller needs to guarantee:
379+
// 1. <T> matches the actual Java type
380+
// 2. <T> matches the argument, BasicType `ty`
381+
pub unsafe fn data<T>(&self, ty: BasicType) -> &[T] {
382+
slice::from_raw_parts(self.base(ty).to_ptr(), self.length() as _)
368383
}
369384
}
370385

mmtk/src/api.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ use mmtk::AllocationSemantics;
1414
use mmtk::Mutator;
1515
use mmtk::MutatorContext;
1616
use mmtk::MMTK;
17+
use once_cell::sync;
1718
use std::ffi::{CStr, CString};
18-
use std::lazy::SyncLazy;
1919

2020
// Supported barriers:
21-
static NO_BARRIER: SyncLazy<CString> = SyncLazy::new(|| CString::new("NoBarrier").unwrap());
22-
static OBJECT_BARRIER: SyncLazy<CString> = SyncLazy::new(|| CString::new("ObjectBarrier").unwrap());
21+
static NO_BARRIER: sync::Lazy<CString> = sync::Lazy::new(|| CString::new("NoBarrier").unwrap());
22+
static OBJECT_BARRIER: sync::Lazy<CString> =
23+
sync::Lazy::new(|| CString::new("ObjectBarrier").unwrap());
2324

2425
#[no_mangle]
2526
pub extern "C" fn mmtk_active_barrier() -> *const c_char {

mmtk/src/lib.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
// specialization is considered as an incomplete feature.
2-
#![allow(incomplete_features)]
3-
#![feature(specialization)]
4-
#![feature(box_syntax)]
5-
#![feature(vec_into_raw_parts)]
6-
#![feature(once_cell)]
7-
81
extern crate libc;
92
extern crate mmtk;
103
#[macro_use]
114
extern crate lazy_static;
5+
extern crate once_cell;
126

137
use std::ptr::null_mut;
148

mmtk/src/object_scanning.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ impl OopIterate for InstanceClassLoaderKlass {
9393
impl OopIterate for ObjArrayKlass {
9494
#[inline]
9595
fn oop_iterate(&self, oop: Oop, closure: &mut impl TransitiveClosure) {
96-
let array = unsafe { oop.as_array_oop::<Oop>() };
97-
for oop in array.data() {
96+
let array = unsafe { oop.as_array_oop() };
97+
for oop in unsafe { array.data::<Oop>(BasicType::T_OBJECT) } {
9898
closure.process_edge(Address::from_ref(oop as &Oop));
9999
}
100100
}

mmtk/src/scanning.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,13 @@ pub(crate) extern "C" fn create_process_edges_work<W: ProcessEdgesWork<VM = Open
2525
W::new(buf, true, &SINGLETON),
2626
);
2727
}
28-
let (ptr, _, capacity) = Vec::with_capacity(W::CAPACITY).into_raw_parts();
28+
let (ptr, _, capacity) = {
29+
// TODO: Use Vec::into_raw_parts() when the method is available.
30+
use std::mem::ManuallyDrop;
31+
let new_vec = Vec::with_capacity(W::CAPACITY);
32+
let mut me = ManuallyDrop::new(new_vec);
33+
(me.as_mut_ptr(), me.len(), me.capacity())
34+
};
2935
NewBuffer { ptr, capacity }
3036
}
3137

@@ -76,17 +82,17 @@ impl Scanning<OpenJDK> for VMScanning {
7682
&SINGLETON,
7783
WorkBucketStage::Prepare,
7884
vec![
79-
box ScanUniverseRoots::<W>::new(),
80-
box ScanJNIHandlesRoots::<W>::new(),
81-
box ScanObjectSynchronizerRoots::<W>::new(),
82-
box ScanManagementRoots::<W>::new(),
83-
box ScanJvmtiExportRoots::<W>::new(),
84-
box ScanAOTLoaderRoots::<W>::new(),
85-
box ScanSystemDictionaryRoots::<W>::new(),
86-
box ScanCodeCacheRoots::<W>::new(),
87-
box ScanStringTableRoots::<W>::new(),
88-
box ScanClassLoaderDataGraphRoots::<W>::new(),
89-
box ScanWeakProcessorRoots::<W>::new(),
85+
Box::new(ScanUniverseRoots::<W>::new()),
86+
Box::new(ScanJNIHandlesRoots::<W>::new()),
87+
Box::new(ScanObjectSynchronizerRoots::<W>::new()),
88+
Box::new(ScanManagementRoots::<W>::new()),
89+
Box::new(ScanJvmtiExportRoots::<W>::new()),
90+
Box::new(ScanAOTLoaderRoots::<W>::new()),
91+
Box::new(ScanSystemDictionaryRoots::<W>::new()),
92+
Box::new(ScanCodeCacheRoots::<W>::new()),
93+
Box::new(ScanStringTableRoots::<W>::new()),
94+
Box::new(ScanClassLoaderDataGraphRoots::<W>::new()),
95+
Box::new(ScanWeakProcessorRoots::<W>::new()),
9096
],
9197
);
9298
if !(Self::SCAN_MUTATORS_IN_SAFEPOINT && Self::SINGLE_THREAD_MUTATOR_SCANNING) {

0 commit comments

Comments
 (0)