-
Notifications
You must be signed in to change notification settings - Fork 775
Description
Questions around this confusing and poorly documented API come up every so often and we are left to return to first principles to figure out what the semantics are. Another question was raised recently.
Let's use this issue to get the semantics straight and either document or alter the code to make this clear.
I sanitized some of the questions and replies from internal Slack discussions on this API for this issue so they don't get lost.
Developer 0
I think I found an odd bug re arraylets…?
bool OMR::Compilation::generateArraylets()
{
if (TR::Compiler->om.canGenerateArraylets())
{
return TR::Compiler->om.useHybridArraylets() ? false : true;
}
else
{
return false;
}
}
In OMR ObjectModel:
bool canGenerateArraylets() { return false; }
bool useHybridArraylets() { return false; }
In OpenJ9 ObjectModel:
bool canGenerateArraylets() { return usesDiscontiguousArraylets(); }
bool useHybridArraylets() { return usesDiscontiguousArraylets(); }
Regardless if usesDiscontiguousArraylets will return true or false, given that the two methods canGenerateArraylets and useHybridArraylets will always return the same answer, generateArraylets() will always return false. Or am I missing something?
Developer 1
Can anybody explain the intention of OMR::Compilation::generateArraylets(), please? If I understand it correctly, it never returns true.
The function depends on canGenerateArraylets() and useHybridArraylets() in ObjectModel, and both of them are defined by usesDiscontiguousArraylets() in OpenJ9. [1][2]
- When
usesDiscontiguousArraylets()is false,canGenerateArraylets()is also false, and generateArraylets() simply returns false. - When
usesDiscontiguousArraylets()is true,generateArraylets()checksuseHybridArraylets()aftercanGenerateArraylets(). Both of them are true, andgenerateArraylets()returns false as the result.
SogenerateArraylets()always returns false, regardless of the value fromusesDiscontiguousArraylets().
Do I overlook anything?
[1] https://github.com/eclipse/omr/blob/92b485082a75459b1ccbc209ab6360f31b04d4f8/compiler/compile/OMRCompilation.cpp#L1662-L1672
[2] https://github.com/eclipse/openj9/blob/61c3a700129045c0cc7819942a0a0c7412c14682/runtime/compiler/env/J9ObjectModel.hpp#L92-L93
Replies
Daryl
One question to simplify all of this is, are there any build specs or GC policies that don’t use hybrid arraylets? I remember years and years ago that the realtime policy did not, but balanced did. Is that still true?
Aleks
Balanced can use hybrid. Can't remember for Metronome ATM.
Developer 2
Recently, I was investigating the method generateArraylets() and noticed something odd. The method checks to see if TR::Compiler->om.canGenerateArraylets() is true and follows it up with a check to TR::Compiler->om.useHybridArraylets(). If the latter returns false, generateArraylets() returns true and vice versa.
This is a strange because both useHybridArraylets() and canGenerateArraylets() have the same method body, and therefore would return identical results. This leads me to believe that generateArraylets() never returns true. I find this a bit surprising because a significant amount of code is guarded by calls to generateArraylets() which may be missing out on generating.
To make absolutely sure, I replaced the return true branch on generateArraylets() with a fatal assert and kick started a personal build, which reported no failures, confirming that the method seems to be returning false at all times.
My question is if I’m missing something obvious here? Is there a reason we overlap API calls and miss out on generating code guarded by generateArraylets()?
Replies
Developer 3
FYI as it seems optimizer and x86 codegen are the primary consumers of the generateArraylets() API. There are mixed uses on Power, and on Z we only seem to use the om.canGenerateArraylets() API. It is worrisome if we are not generating proper checks under balanced and the delta between gencon and balanced could be larger than we measure if this is fixed.
Developer 4
So the two checks are not identical in spirit from my understanding historically (I agree they have been fused now and we'd need to check with the GC team on what the status of the implementation is). Under arraylets, there is a question of what do you do with short arrays that would normally fit in the spine of the array
One option is to allocate an arraylet, put the data in the arraylet and away you go - it is just like any other discontriguous array. The other option is to put the data in the spine, unless the spine is too small, in which case you put the data in arraylets. But what do you with the leftover? e.g., if you don't have enough to fill the final arraylet. Again, you could put that data in the spine or you could allocate an arraylet for it. So we have traditionally had a mode where the spine will hold the data and if the data doesn't fit then we'll go to the arraylets and, I think but will need to check, that we would put the left over data from the part filled arraylet in the spine to save allocating another arraylet. But I believe the two queries did exist to determine which of those different versions of arraylets we were supporting - e.g., is the extra data in the spine or in a final arraylet?
Developer 3
The hybrid arraylets is what I think you may be referring to which are explained in [1]. I beleve they are slated for deprecation but haven't been yet? I'm not sure what the generateArraylets() API is supposed to model though.
[1] https://eclipse-omr.org/double-map-arraylets/
Developer 4
When we do enable double mapping there won’t be such thing as hybrid arraylets anymore. But balanced and metronome still make use of both hybrid and discontiguous arraylets which is the default behaviour. If an arraylet leftover data fits in the spine then the arraylet becomes hybrid. But if all data fits in spine then arraylet is contiguous. And the last layout is discontiguous where all arraylet data resides in their leaves.
Developer 3
In it’s current form, shouldn’t we expect generateArraylets() to return true for both hybrid and discontiguous though? Or in other words, anytime the array doesn’t have a contiguous layout.
Developer 4
Yes, I was about to say that, OMR::Compilation::generateArraylets() checks seems very odd since looking at it it is impossible to return true
Daryl
Was a final disposition reached on this discussion? I’m just trying to understand the semantics of these APIs and whether some Doxygen comments should be added to the code.
Developer ?
For me it seems that many if not all of the methods in compiler/env/OMRObjectModel.hpp are unimplemented. Which brings back to the behavior of OMR::Compilation::generateArraylets() always returning false.
The OMR version is overridden in OpenJ9 and it is there that it is hooked up - that is not unusual for the compiler component. So I think the historical intent of the APIs is as stated - generateArraylets means the arrays are not guaranteed to be contiguous while hybrid arraylets tells us whether data can be in the spine. Looking in history r14 says the APIs had been merged in their current form where they had been modified to return the same result. Given the difference in the double mapping model vs existing these differences may become more important again, but the API usages will need to be audited as part of any change to allow them to vary since the difference has probably not been well understood for some time and they have been synonyms for a number of years
Developer ?
When it comes to double mapping we don’t really have hybrid arraylets, but just discontiguous ones, hence the difference. And in the future, once the off-heap part is implemented these differences might become even more important like you mentioned