-
Notifications
You must be signed in to change notification settings - Fork 720
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
Modify ROMclass packing to normalize more #18848
Conversation
0ef43bb
to
8a0aa38
Compare
Attn @mpirvu. This code is exercised by the normal operation of the JITServer, in that |
Maybe I should add that this will add a bit of overhead to ROM class packing that isn't strictly necessary at the moment. I could preserve the old implementation for shared ROM classes and have this new one on the side. Then the main PR can switch to this new one. Also, while I skip fixing the bytecodes when the ROM class is shared, I do the debug info stripping even on shared ROM classes. That might not be totally necessary. I'll have to double-check if a shared ROM class can ever have a mix of inline and out-of-line debug info, but even then we could skip stripping the debug info in that case and and worst suffer a cache miss as a result. If that sounds all right then we can switch entirely to the new implementation right now and I'll just skip all the extra normalization if the ROM class is shared. |
Looking at the ROM class creation code, it does seem like there are only two scenarios:
(Debug info (source code line numbers and things) will be totally out-of-line in a non-shared ROM class if the ROM class writer is instructed to throw away all debug info. That is actually a valid solution to this problem, but presumably we don't want to throw away all debug info just because we're running with I was worried that a shared ROM class might have a mix, but I think the only time that the debug info will switch from out-of-line to inline in that case is if the SCC fills up, and if that happens then it looks like the ROM class will fail to be stored in the SCC and it will be rewritten to be non-shared. |
I've changed the implementation so we only strip debug info and fix the return bytecodes for non-shared classes, and otherwise use the older method. |
8a0aa38
to
a131639
Compare
_segments.push_back({debugOffset + debugInfoSegmentSize, _accumulatedShift}); | ||
} | ||
|
||
size_t |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments would be nice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this a request for documentation for newOffsetFromOld
, actually? I'll add it if so.
// Calculate the size of the portion of a ROM class that occurs before its UTF8 string section (the pre-string section), | ||
// without any padding that may have been added during initial ROM class writing. | ||
// | ||
// Why is this necessary? The sections inside a ROMClass before the UTF8 string section are 32-bit aligned, but the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice comment!
if (ctx->isInline(sectionPtr, romClass)) | ||
{ | ||
size_t endOffset = ((uint8_t *)sectionPtr - (uint8_t *)romClass) + sectionSize; | ||
ctx->_preStringSize = std::max(ctx->_preStringSize, endOffset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand how taking the max ensures alignment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't ensure alignment. We need to get the unaligned (unpadded) size of the ROM class before the string section, so that when we calculate the aligned (padded) size of the packed version of the ROM class here:
we don't introduce unnecessary padding.
I'll clarify that in the comment, and I should probably add that
- The "pre-string section" isn't a real section that the ROM class walk visits (neither is the UTF8 string section)
- The ROM class walker visits sections that are either entirely within the pre-string section or are entirely outside the ROM class. In particular, it doesn't visit anything in the UTF8 string section or the intermediate class data section.
- The ROM class walker visits every section before the UTF8 string section.
That's why taking the max actually gives you the size of the pre-string section, and why going through the trouble of taking the max is necessary in the first place. (Maybe "pre-string area" is a better term for it).
The assert here:
should hopefully catch any case where someone changes the ROM class format or walker significantly enough that those properties are violated.
a131639
to
3f3a82b
Compare
Force-pushed to bring in latest merges and hopefully address the existing review comments. |
jenkins test sanity plinuxjit,xlinuxjit,zlinuxjit,alinux64jit jdk17 |
It's not clear to me why aarch64 build failed. The SDK was actually built. |
jenkins test sanity alinux64jit jdk17 |
Crash for xlinux:
|
P and Z have crashes too |
Oh, the xlinux crash is:
and that comes from my new fatal assert here: The ROM class name is blank as well, which is strange. Is there some odd interaction here with shutting down the local SCC? |
The assert isn't technically necessary. I could keep the old behaviour ("if out of line, then zero out the SRP"). I just had it in there to validate my assumption that shared ROM classes only have out-of-line debug info. If that assumption is violated nothing bad should happen. It would just cause a hash mismatch, maybe. |
I'm pretty sure that the romClass had to have been considered shared by
so we'd only be in the body of that loop if we considered the romClass in question to be shared. |
I see, that test was run with |
I understand, I think. With I'm pretty sure, based on the reading of the ROM class writer code, that Okay, so if I preserve the old behaviour then we won't be able to share code between these two types of clients:
Is that all right for now? There might be an SCC property that I can query to see if we're in situation (1) and need to use the new packing implementation, to allow sharing between (1) and (2) in future. |
When ROM classes are packed to be sent to the JITServer, we now perform two additional transformations, in addition to the existing string inlining: 1. The return bytecodes in the ROM class are fixed up if the class is not shared 2. Any inlined debug info is stripped from the ROM class Both of these are necessary to ensure that the packed representations of shared and non-shared versions of the same ROM class are identical. Signed-off-by: Christian Despres <despresc@ibm.com>
3f3a82b
to
ee51c7d
Compare
Force-pushed to fix the issue discussed above. Based on our discussion, instead of a single This is (to summarize) necessary because a class being shared does not necessarily mean that its methods have only out-of-line debug info, so it being shared can't be used as a proxy to determine if we can skip debug info stripping. This way also has the small benefit that we will now skip the more elaborate debug info stripping if we're packing a ROM class that isn't shared and has zero inline debug info. |
jenkins test sanity all jdk21 |
Signed-off-by: Christian Despres <despresc@ibm.com>
Sorry, I was working on the main PR and realized that this had two issues. Neither were functional, but did affect hashing:
I decided to push a new commit in this PR rather than wait, because without it we were double-fixing the bytecodes of shared classes. That's not incorrect, just a waste of time. |
jenkins test sanity all jdk21 |
jenkins test sanity plinuxjit,xlinuxjit,zlinuxjit,alinux64jit jdk17 |
jenkins test extended,sanity.system,extended.system plinuxjit,xlinuxjit,zlinuxjit jdk17 |
A bunch of tests fail on |
CryptoTests_0 timeout for extended.functional_x86-64_linux_jit |
There were timeouts in |
CrytoTest had a timeout even in the grinder, but given that this is a known issue I am going to say that this PR is good to be merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One nitpick (see inline) for future cleanup. Good work figuring out all the intricacies of ROMClass layout @cjjdespres!
packedSize = getArrayROMClassPackedSize(romClass); | ||
} | ||
else if (needsDebugInfoStripping) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the code in this branch and the next one seems identical. The next time we need to make any changes to this function, it would be nice to factor out duplicated code. I guess something to add to the list in #18990.
When ROM classes are packed to be sent to the JITServer, we now perform two additional transformations, in addition to the existing string inlining:
Both of these are necessary to ensure that the packed representations of shared and non-shared versions of the same ROM class are identical. Otherwise, the difference in representations will cause them to have different hashes, and that will effectively prevent us from sharing code between JITServer clients that have different mixes of shared and non-shared classes.