-
Notifications
You must be signed in to change notification settings - Fork 396
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
Re-architect Compiler Memory Infrastructure #4783
Comments
Note that the |
To spur some discussion on this topic I would like to add this to the agenda of the Feb. 13 OMR Architecture Meeting. Would one of @dsouzai @Leonardo2718 @jdmpapin like to lead the discussion on it? |
I'm fine leading the discussion. |
A few points from my earlier travels through this topic, most of which I mentioned on the call but due to our audio troubles maybe not all of it came across well:
|
Thanks for summarizing your feedback in the issue @mstoodle. What we decided during the meeting was that @dsouzai will spend some timeboxed amount of time exploring some of the issues @mstoodle raised to see if they are actually problems in the solution proposed. If not, the work sizing that was discussed during the meeting was on the order of 2 weeks, but that may be refined depending on the outcome of the investigations. Unfortunately, we only have about 10 minutes of usable audio at the beginning of the call and then a few minutes at the end. I'm not sure if this was a phone issue in the main meeting room or a Webex call-in issue. Regardless, I regret that we were unable to fix the audio issues satisfactorily during the call and I apologize for the inconvenience for the remote (or absent) participants. I may still edit the recording to include just the first 10 minutes of @dsouzai's presentation and post that. It is incomplete but may fill in some of the background for those that don't have it. |
I managed to get the POC working both with OpenJ9 and OMR. You can find the branches here: https://github.com/dsouzai/omr/commits/memory All the new code is guarded with the Macro After going through this process, here's some smaller tasks that should be done as a precursor to this work:
These will still allow the old memory infrastructure to run, but it will make life a lot easier should the switch to the new infrastructure happen. Additionally, using references does provide the nice guarantee of non-NULLness. Some unfortunate decisions:
These decisions were made because the point of my efforts was to show that the new memory infrastructure can work; if we go forward with making this effort real, then we need to address these decisions. As it turns out though, all of these complexities are found in OpenJ9; the OMR side of things was surprisingly simple (except for changing the existing allocators to not be passed by value...). fyi @mstoodle @jdmpapin @Leonardo2718 @aviansie-ben [1] dsouzai/openj9@dea02bd#diff-c4d0c52b4c192efe63c8d8bc683d6dc1R80 |
@Leonardo2718, @aviansie-ben, and I met up and discussed the roadmap @0xdaryl requested in the architecture meeting. The general plan should go as follows:
Once these are implemented, both memory infrastructures can co-exist. Once the new infrastructure is sufficiently tested, we can make the switch to use the new infrastructure and the old one can be deleted.
|
Could someone articulate the scenario that motivates the "stashed segment allocator" please? I realize this was inspired from the |
In OpenJ9, this is what the lifetimes looks like:
You can think of the This one segment that is held on to is the cache. Originally, when the current memory infra was put into place to replace the previous one, there was no The reason not caching some memory causes a problem is because most compilations during startup in OpenJ9 don't take more than ~30 MB of scratch memory (and often less), so the increased system calls to acquire memory before the start of every compilation added up. |
The current architecture of the memory manager in OMR is quite complex and non-trivial to understand [1]. When you look at an extending project, the story can get even more complicated [2]. As a prerequisite to implement eclipse-openj9/openj9#5836, @mstoodle went about refactoring the memory infrastructure. His efforts led to a discussion and eventual design by @jdmpapin, @Leonardo2718, and (to a much lesser extent) myself. Attached is a PDF [3] of a visual depiction of the design; the rest of the issue will be a description of the design. It is important to note that this redesign only involves the
TR::RawAllocator
and the various segment providers; it does not involveTR::Region
orTR::PersistentAllocator
. The attached PDF shows how OpenJ9 fits into this new design as a real example, but it also shows how other projects might fit in.The design starts with two API classes.
TR::RawAllocator
andTR::SegmentAllocator
. These two are abstract classes that other classes will implement. The attached PDF shows how various the various classes will implement this API.Regarding
TR::RawAllocator
:TR::RawAllocator
does currentlyTR::RawAllocator
.TR::RawAllocator
by providing their own function pointers.Regarding
TR::SegmentAllocator
:TR::RawAllocator
TR::SegmentAllocator
is allowed to allocateAll of these might seem like an odd set of implementers. However, the way all of these fit in is via nested composition. The full visual depiction of this is in the attached PDF. However, to give a concrete example in code of how the "OMR Default Segment Allocator" might look:
Then in
compileMethodFromDetails
:Note, the code above glosses over some details like what the default segment size should be.
This design doesn't deviate from the philosophy of the existing memory infrastructure, namely "Try to fulfill the request yourself or delegate". In the example above,
LimitingRA
will try to fulfill the request itself; however, since it doesn't have the means to do so, it delegates to_nextSA
.The benefit of this design though is every implementer of the APIs has a very specific purpose and is well named. The reason for composing the various
TR::SegmentAllocator
implementers is to maintain the invariant of "Try to fulfill the request yourself or delegate". A given class does not need to know the exact type of the class it delegates to; it knows it's aTR::SegmentAllocator
and so has a well-defined API. This also makes the code much easier to modify.For example, if we wanted to add something between
LimitingSA
andTrivialSA
, sayPaintingSA
, then all we'd have to do is add thePaintingSA
class definition and then incompileMethodFromDetails
:The majority of the classes described in the attached PDF can live in OMR, including implementers like the "Stashing SA" which only exists in OpenJ9 (currently implemented as the
J9::SegmentCache
).We're opening this issue as a place where this design can be discussed.
FYI @mstoodle @lmaisons.
[1] https://github.com/eclipse/omr/blob/master/doc/compiler/memory/MemoryManager.md
[2] https://github.com/eclipse/openj9/blob/master/doc/compiler/memory/MemoryManager.md
[3] https://github.com/eclipse/omr/files/4124860/CompilerMemoryInfrastructureDesign.pdf
The text was updated successfully, but these errors were encountered: