Skip to content
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

Implement AllocatorInfo #889

Merged
merged 9 commits into from
Aug 22, 2023
Merged

Implement AllocatorInfo #889

merged 9 commits into from
Aug 22, 2023

Conversation

playXE
Copy link
Contributor

@playXE playXE commented Aug 5, 2023

This type adds AllocatorInfo enum that can be used to query offset of allocator fields for fast-path generation. Currently all bindings have to re-declare *Allocator types with the same layout as in mmtk-core in order to get offset of these fields. This enum simplifies that, all you need to do is invoke get_allocator_info(selector).

Copy link
Member

@qinsoon qinsoon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the changes look good. This is something we need to properly support compiler generated allocation fastpath.

src/util/alloc/mod.rs Outdated Show resolved Hide resolved
src/memory_manager.rs Outdated Show resolved Hide resolved
limit_offset: usize,
top_offset: usize,
},
Immix {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can just remove the Immix variant as well. Immix's overflow_alloc (which uses the large cursor/limit) and alloc_slow_hot (which tries to find a recyclable line) is considered as the 'intermediate' path (i.e. between fastpath and slowpath). Normally the compiler don't need to inline it. In that case, generating allocation fastpath for Immix would be the same as BumpPointer fastpath (just checking cursor/limit, and adjust cursor).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not small limit still be checked? Or am I wrong here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have to check "small_limit". If the allocation can fit into the normal buffer (cursor/limit), it will be allocated in the buffer. However, the buffer can be as small as one line (depending on how fragment the heap is). So sometimes the allocation that is larger than one line can't fit into the normal buffer, then the large cursor/limit is used. But that is not in the fastpath path any more.

The actual code that is considered as Immix's fastpath is (which is as simple as a normal bump pointer allocation):

let result = align_allocation_no_fill::<VM>(self.cursor, align, offset);
let new_cursor = result + size;
if new_cursor > self.limit {

and
} else {
// Simple bump allocation.
fill_alignment_gap::<VM>(self.cursor, result);
self.cursor = new_cursor;
trace!(
"{:?}: Bump allocation size: {}, result: {}, new_cursor: {}, limit: {}",
self.tls,
size,
result,
self.cursor,
self.limit
);
result

Copy link
Collaborator

@k-sareen k-sareen Aug 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remembered @wenyuzhao mentioning something about this in-person to me (Re: limit for Immix allocator being 256 bytes). Maybe he can chime in and clarify expectations.

src/memory_manager.rs Outdated Show resolved Hide resolved
src/util/alloc/allocators.rs Outdated Show resolved Hide resolved
Comment on lines 21 to 23
pub(crate) cursor: Address,
/// Limit for bump pointer
limit: Address,
pub(crate) limit: Address,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can make a #[repr(C)] struct for these two fields since it appears so often. Then we only need to return one offset for those two fields.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be done in this PR as well?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please. This is the best chance to do it.

Copy link
Contributor Author

@playXE playXE Aug 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How this structure should be named? And also, where should I put it?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. I think we should discuss on Zulip and let everyone vote.

It should be defined in allocator.rs because it is common to many concrete allocators.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This PR seems a step in the right direction. Thank you!
  2. Placing cursor and limit in a struct seems sensible.
  3. The cursor and limit should be called a bump pointer, because that is literally what it is (edit: at least that's what I think you're doing, from my read). I teach people how GCs are built and this is literally how I describe a bump pointer: a cursor and a limit. Inventing a new term to describe this most basic of data structures is not a good idea.

Meta point: I don't think "voting" on conceptual points like this on Zulip is a great idea in general.

src/memory_manager.rs Outdated Show resolved Hide resolved
@playXE
Copy link
Contributor Author

playXE commented Aug 14, 2023

So far what would be the next proper steps to get this PR merged? I am actually now all in for idea of bindings storing bump-pointers/free-lists on their side and syncing with MMTk when necessary. BDWGC works this way by providing support for inline allocation by allowing user-code to create free-lists.

cc @steveblackburn @qinsoon

@qinsoon
Copy link
Member

qinsoon commented Aug 14, 2023

So far what would be the next proper steps to get this PR merged? I am actually now all in for idea of bindings storing bump-pointers/free-lists on their side and syncing with MMTk when necessary. BDWGC works this way by providing support for inline allocation by allowing user-code to create free-lists.

cc @steveblackburn @qinsoon

It seems there are two options:

  1. Expose the offset of cursor/limit (and similar fields for other allocators), or
  2. Expose the values of cursor/limit.

My preference is Option 1. It covers what Option2 does, and is more flexible for the bindings. Option 2 enforces the binding to create their own fastpath data structures, and sync values with MMTk. I am not sure what others think about. @steveblackburn @wks

We will get this resolved no later than tomorrow (we have a meeting tomorrow and I will raise this if necessary).

@qinsoon
Copy link
Member

qinsoon commented Aug 16, 2023

So far what would be the next proper steps to get this PR merged? I am actually now all in for idea of bindings storing bump-pointers/free-lists on their side and syncing with MMTk when necessary. BDWGC works this way by providing support for inline allocation by allowing user-code to create free-lists.
cc @steveblackburn @qinsoon

It seems there are two options:

  1. Expose the offset of cursor/limit (and similar fields for other allocators), or
  2. Expose the values of cursor/limit.

My preference is Option 1. It covers what Option2 does, and is more flexible for the bindings. Option 2 enforces the binding to create their own fastpath data structures, and sync values with MMTk. I am not sure what others think about. @steveblackburn @wks

We will get this resolved no later than tomorrow (we have a meeting tomorrow and I will raise this if necessary).

@playXE

We discussed this. Exposing field offsets to the binding is a good idea. It allows the JIT compiler to generate code, and allows the runtime to load/store the values.

A refinement on the current PR we plan to do is that we could have public fastpath structs with #[repr(C)], and expose the offset to the struct instead of exposing offsets to separate fields. Such as

#[repr(C)]
pub struct BumpPointer {
  pub cursor: Address,
  pub limit: Address,
}

struct BumpAllocator {
  bump_pointer: BumpPointer
  ...
}

pub enum AllocatorInfo {
    BumpPointer(usize), // offset from mutator to the BumpPointer struct
    // FIXME: Add free-list fast-path
    Unimplemented,
    None,
}

This change does not have to be included in the PR. Just FYI, as we may change the actual interface in the future. But we will follow the general idea of exposing offsets to fields for bindings.

If this sounds good to you, you can make the PR ready, and we can proceed from there. Thanks for the PR.

@playXE
Copy link
Contributor Author

playXE commented Aug 17, 2023

@qinsoon I see, I'll implement BumpPointer in this PR as well, I need to get fast-path allocations in my runtime working now. Will do that on weekends probably, right now busy with getting into new job.

@playXE playXE marked this pull request as ready for review August 20, 2023 08:12
@playXE playXE requested a review from qinsoon August 20, 2023 08:12
Cargo.toml Outdated Show resolved Hide resolved
src/util/alloc/allocators.rs Outdated Show resolved Hide resolved
src/util/alloc/immix_allocator.rs Outdated Show resolved Hide resolved
@qinsoon
Copy link
Member

qinsoon commented Aug 21, 2023

I am trying to push some changes to the PR. Mainly about the new method BumpPointer::alloc. Though it is better to provide such a method that can be reused, it introduce an extra conditional check in the fastpath that the Rust compiler does not optimize away. I think it would be a better idea to revert that part.

@qinsoon qinsoon added the PR-testing Run binding tests for the pull request (deprecated: use PR-extended-testing instead) label Aug 21, 2023
Copy link
Member

@qinsoon qinsoon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@qinsoon qinsoon merged commit 9175e68 into mmtk:master Aug 22, 2023
21 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR-testing Run binding tests for the pull request (deprecated: use PR-extended-testing instead)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants