Skip to content

Replace MaybeUninit in allocator arrays with Option#1483

Open
caizixian wants to merge 4 commits intommtk:masterfrom
caizixian:unsafe_maybeuninit_option
Open

Replace MaybeUninit in allocator arrays with Option#1483
caizixian wants to merge 4 commits intommtk:masterfrom
caizixian:unsafe_maybeuninit_option

Conversation

@caizixian
Copy link
Copy Markdown
Member

@caizixian caizixian commented Apr 21, 2026

I don't think the changes here are performance sensitive but I can run some benchmarks if needed

@wks
Copy link
Copy Markdown
Collaborator

wks commented Apr 21, 2026

Not sure if it is easy to test, but if it is not performance critical, we may just use Vec<XxxAllocator> instead of [Option<XxxAllocator>; MAX_XXX_ALLOCATORS].

@k-sareen
Copy link
Copy Markdown
Collaborator

Vec is not FFI-safe, technically. And currently the entire mutator struct is embedded inside the OpenJDK mutator.

@caizixian
Copy link
Copy Markdown
Member Author

Option is not technically FFI safe either though

@caizixian caizixian force-pushed the unsafe_maybeuninit_option branch from b9bf027 to 57b5f48 Compare April 21, 2026 08:57
@k-sareen
Copy link
Copy Markdown
Collaborator

Right. Option<NonNullReference> is FFI-safe from memory. Do we want to Box the allocators then?

@qinsoon
Copy link
Copy Markdown
Member

qinsoon commented Apr 21, 2026

Does Option<XxxAllocator> have the same layout as XxxAllocator?

The other option to remove MaybeUninit is to actually init all the allocators, but for the ones that are not used, we initialize it with a special fake space. See #1486.

@qinsoon
Copy link
Copy Markdown
Member

qinsoon commented Apr 22, 2026

This test could check the layout and ffi compatibility:

// GITHUB-CI: MMTK_PLAN=NoGC
// Just test this onece.

use lazy_static::lazy_static;

use super::mock_test_prelude::*;
use crate::util::alloc::*;
use std::mem::size_of;

#[test]
pub fn test_option_allocator_layout() {
    assert_eq!(size_of::<Option<BumpAllocator<MockVM>>>(), size_of::<BumpAllocator<MockVM>>());
    assert_eq!(size_of::<Option<LargeObjectAllocator<MockVM>>>(), size_of::<LargeObjectAllocator<MockVM>>());
    assert_eq!(size_of::<Option<MallocAllocator<MockVM>>>(), size_of::<MallocAllocator<MockVM>>());
    assert_eq!(size_of::<Option<ImmixAllocator<MockVM>>>(), size_of::<ImmixAllocator<MockVM>>());
    assert_eq!(size_of::<Option<FreeListAllocator<MockVM>>>(), size_of::<FreeListAllocator<MockVM>>());
    assert_eq!(size_of::<Option<MarkCompactAllocator<MockVM>>>(), size_of::<MarkCompactAllocator<MockVM>>());
}

#[test]
pub fn test_0_transmute_as_option_none() {
    const BUMP_ALLOCATOR_SIZE: usize = size_of::<Option<BumpAllocator<MockVM>>>();
    let zero_bump = unsafe { std::mem::transmute::<_, Option<BumpAllocator<MockVM>>>([0u8; BUMP_ALLOCATOR_SIZE]) };
    assert!(zero_bump.is_none());
}

@qinsoon
Copy link
Copy Markdown
Member

qinsoon commented Apr 22, 2026

Can you check the performance of this PR? @caizixian

@caizixian caizixian force-pushed the unsafe_maybeuninit_option branch from fa812b2 to cba54c6 Compare April 22, 2026 04:44
@caizixian
Copy link
Copy Markdown
Member Author

Unit tests added and checked with cargo test mock_test_option_allocator_layout --features mock_test

@caizixian caizixian force-pushed the unsafe_maybeuninit_option branch from cba54c6 to 5d9e8b1 Compare April 22, 2026 05:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants