Skip to content

MallocMS page accounting #689

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/scripts/ci-doc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ if ! cat $project_root/src/plan/mod.rs | grep -q "pub mod mygc;"; then
fi
cargo build

cargo install mdbook
# Install mdbook using the stable toolchain (mdbook uses scoped-tls which requires rust 1.59.0)
cargo +stable install mdbook
mdbook build $project_root/docs/portingguide
mdbook build $project_root/docs/tutorial
2 changes: 1 addition & 1 deletion .github/workflows/api-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ jobs:
- name: Install cargo-public-api
run: cargo install cargo-public-api
- name: API Diff
run: cargo public-api --diff-git-checkouts ${GITHUB_BASE_REF} ${{ github.event.pull_request.head.sha }} --deny=all
run: cargo public-api --diff-git-checkouts origin/${GITHUB_BASE_REF} ${{ github.event.pull_request.head.sha }} --deny=all
282 changes: 183 additions & 99 deletions src/policy/mallocspace/global.rs

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion src/policy/mallocspace/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub(crate) const ACTIVE_CHUNK_METADATA_SPEC: SideMetadataSpec =
// XXX: This metadata spec is currently unused as we need to add a performant way to calculate
// how many pages are active in this metadata spec. Explore SIMD vectorization with 8-bit integers
pub(crate) const ACTIVE_PAGE_METADATA_SPEC: SideMetadataSpec =
crate::util::metadata::side_metadata::spec_defs::MS_ACTIVE_PAGE;
crate::util::metadata::side_metadata::spec_defs::MALLOC_MS_ACTIVE_PAGE;

pub(crate) const OFFSET_MALLOC_METADATA_SPEC: SideMetadataSpec =
crate::util::metadata::side_metadata::spec_defs::MS_OFFSET_MALLOC;
Expand Down Expand Up @@ -173,6 +173,15 @@ pub unsafe fn is_marked_unsafe<VM: VMBinding>(object: ObjectReference) -> bool {
VM::VMObjectModel::LOCAL_MARK_BIT_SPEC.load::<VM, u8>(object, None) == 1
}

/// Set the page mark from 0 to 1. Return true if we set it successfully in this call.
pub(super) fn compare_exchange_set_page_mark(page_addr: Address) -> bool {
// The spec has 1 byte per each page. So it won't be the case that other threads may race and access other bits for the spec.
// If the compare-exchange fails, we know the byte was set to 1 before this call.
ACTIVE_PAGE_METADATA_SPEC
.compare_exchange_atomic::<u8>(page_addr, 0, 1, Ordering::SeqCst, Ordering::SeqCst)
.is_ok()
}

#[allow(unused)]
pub(super) fn is_page_marked(page_addr: Address) -> bool {
ACTIVE_PAGE_METADATA_SPEC.load_atomic::<u8>(page_addr, Ordering::SeqCst) == 1
Expand Down Expand Up @@ -217,6 +226,7 @@ pub fn unset_alloc_bit(object: ObjectReference) {
alloc_bit::unset_alloc_bit(object);
}

#[allow(unused)]
pub(super) fn set_page_mark(page_addr: Address) {
ACTIVE_PAGE_METADATA_SPEC.store_atomic::<u8>(page_addr, 1, Ordering::SeqCst);
}
Expand Down Expand Up @@ -246,10 +256,15 @@ pub unsafe fn unset_mark_bit<VM: VMBinding>(object: ObjectReference) {
VM::VMObjectModel::LOCAL_MARK_BIT_SPEC.store::<VM, u8>(object, 0, None);
}

#[allow(unused)]
pub(super) unsafe fn unset_page_mark_unsafe(page_addr: Address) {
ACTIVE_PAGE_METADATA_SPEC.store::<u8>(page_addr, 0)
}

pub(super) unsafe fn bulk_zero_page_mark(page_addr: Address, size: usize) {
ACTIVE_PAGE_METADATA_SPEC.bzero_metadata(page_addr, size)
}

pub(super) unsafe fn unset_chunk_mark_unsafe(chunk_start: Address) {
ACTIVE_CHUNK_METADATA_SPEC.store::<u8>(chunk_start, 0)
}
Expand Down
1 change: 1 addition & 0 deletions src/util/alloc/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ pub trait Allocator<VM: VMBinding>: Downcast {
_allocation_bytes,
*plan.options.analysis_factor
);

plan.analysis_manager.alloc_hook(size, align, offset);
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/util/malloc/library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@ pub use self::libc_malloc::*;
#[cfg(feature = "malloc_mimalloc")]
pub use self::mimalloc::*;

/// When we count page usage of library malloc, we assume they allocate in pages. For some malloc implementations,
/// they may use a larger page (e.g. mimalloc's 64K page). For libraries that we are not sure, we assume they use
/// normal 4k pages.
pub const BYTES_IN_MALLOC_PAGE: usize = 1 << LOG_BYTES_IN_MALLOC_PAGE;

// Different malloc libraries

// TODO: We should conditinally include some methods in the module, such as posix extension and GNU extension.

#[cfg(feature = "malloc_jemalloc")]
mod jemalloc {
// Normal 4K page
pub const LOG_BYTES_IN_MALLOC_PAGE: u8 = crate::util::constants::LOG_BYTES_IN_PAGE;
// ANSI C
pub use jemalloc_sys::{calloc, free, malloc, realloc};
// Posix
Expand All @@ -29,6 +36,8 @@ mod jemalloc {

#[cfg(feature = "malloc_mimalloc")]
mod mimalloc {
// MiMalloc 64K Page
pub const LOG_BYTES_IN_MALLOC_PAGE: u8 = 16;
// ANSI C
pub use mimalloc_sys::{
mi_calloc as calloc, mi_free as free, mi_malloc as malloc, mi_realloc as realloc,
Expand All @@ -41,6 +50,8 @@ mod mimalloc {

#[cfg(feature = "malloc_hoard")]
mod hoard {
// Normal 4K page
pub const LOG_BYTES_IN_MALLOC_PAGE: u8 = crate::util::constants::LOG_BYTES_IN_PAGE;
// ANSI C
pub use hoard_sys::{calloc, free, malloc, realloc};
// Posix
Expand All @@ -56,6 +67,8 @@ mod hoard {
feature = "malloc_hoard",
)))]
mod libc_malloc {
// Normal 4K page
pub const LOG_BYTES_IN_MALLOC_PAGE: u8 = crate::util::constants::LOG_BYTES_IN_PAGE;
// ANSI C
pub use libc::{calloc, free, malloc, realloc};
// Posix
Expand Down
2 changes: 1 addition & 1 deletion src/util/metadata/side_metadata/spec_defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ define_side_metadata_specs!(
define_side_metadata_specs!(
last_spec_as LAST_LOCAL_SIDE_METADATA_SPEC,
// Mark pages by (malloc) marksweep
MS_ACTIVE_PAGE = (global: false, log_num_of_bits: 3, log_bytes_in_region: LOG_BYTES_IN_PAGE as usize),
MALLOC_MS_ACTIVE_PAGE = (global: false, log_num_of_bits: 3, log_bytes_in_region: crate::util::malloc::library::LOG_BYTES_IN_MALLOC_PAGE as usize),
// Record objects allocated with some offset
MS_OFFSET_MALLOC = (global: false, log_num_of_bits: 0, log_bytes_in_region: LOG_MIN_OBJECT_SIZE as usize),
// Mark lines by immix
Expand Down