-
Notifications
You must be signed in to change notification settings - Fork 733
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
HCR Redefinition of empty constructors gets ignored #19883
Comments
I think this is because with extended HCR the redefinition will unresolve constant pool entries related to the redefined class |
I suspect this issue is not limited to constructors - we use the forwarding option for all invokespecial targets. While it would be foolish to have forwarder methods in general (the forwarding constructors are added by the compiler, I believe), it's certainly not illegal. Two obvious options occur:
|
(1) would fix the problem for both the interpreter and the JIT (2) would fix the interpreter only, but the JIT would be straightforward. We'd just have to avoid I don't really have a preference. Either way, the JIT can't correctly go on making use of this forwarding, at least under the defaults. So the difference is mainly re-resolution implementation effort vs. interpreter performance impact |
I don't think your suggestion for (2) would work - there's no guarantee who resolves a CP entry (interp or JIT) so changing the resolve behaviour likely won't work reliably. I think we should remove the optimization and do some perf testing. The JIT will presumably naturally optimize the chain of forwarder constructors, so this should only affect the interpreter. |
I see the JIT currently uses the forwarder bit in the ROM method. If that can be removed in favour of general inlining of trivial methods, we can get rid of a bunch of code and reclaim the bit. |
Good plan
The JIT won't be able to use the forwarder bit at all, at least in HCR mode. Since HCR is on by default, I think from a JIT point of view it would be fine to remove the entire forwarding mechanism |
Hopefully this is irrelevant, but I do think that (2) might work, and if not it could probably be made to work without too much trouble. The JIT calls |
If no one else picks this up, I'll remove the entire mechanism in the next week or so and get some builds for perf testing. |
Fixes: eclipse-openj9#19883 Signed-off-by: Graham Chapman <[email protected]>
@jdmpapin Please review the JIT changes above to make sure I haven't removed something important. |
The commit deletes the beginning of a conditional:
I think we need to delete that entire case, all the way to
and then make that The first conditional is trying to analyze the bytecode to see when a method just forwards to the corresponding method in the base class. It's trying to avoid setting the bit that says that the base method is overridden and avoid invalidating nonoverridden runtime assumptions for it. But if we do that, then a later redefinition of the subclass could change the bytecode for this method and the JIT-compiled code would continue running the base implementation. The HCR assumptions would only guard against redefinition of the base class |
Fixes: eclipse-openj9#19883 Signed-off-by: Graham Chapman <[email protected]>
Fixes: eclipse-openj9#19883 Signed-off-by: Graham Chapman <[email protected]>
Fixes: eclipse-openj9#19883 Signed-off-by: Graham Chapman <[email protected]>
Fixes: eclipse-openj9#19883 Signed-off-by: Graham Chapman <[email protected]>
Fixes: eclipse-openj9#19883 Signed-off-by: Graham Chapman <[email protected]>
This is the current version of the change: https://github.com/gacholio/openj9/tree/forwarder |
The JIT changes LGTM, though the comment on |
Fixes: eclipse-openj9#19883 Signed-off-by: Graham Chapman <[email protected]>
Done. |
@IBMJimmyk Before sending this off for performance testing, can you please verify that this fixes the reported problem? |
With the latest changes, my test now passes. Both
|
Thanks, I'll get this out for perf testing ASAP. |
Fixes: eclipse-openj9#19883 Signed-off-by: Graham Chapman <[email protected]>
Fixes: eclipse-openj9#19883 Signed-off-by: Graham Chapman <[email protected]>
Fixes: eclipse-openj9#19883 Signed-off-by: Graham Chapman <[email protected]>
If an object has an empty constructor, it gets skipped over and its super constructor is called instead. This is a problem if HCR kicks in and replaces the empty constructor with a non-empty constructor. I talked to @jdmpapin and he helped me track down this problem.
The test case looks like this:
runTest
creates a new object of typeInitObject
, reads and returns the value ofintField
.With the line commented out, the constructor is empty and the error will occur. If it is uncommented, the error with not happen. Either way, the value of
intField
is 0.The redefined version looks like this:
The value of
intField
is now 1 after the redefinition.What the test does is create an object of type
InitObject
and check that the value ofintField
is 0. It then redefines theInitObject
class so thatintField
is now 1. It then creates a new object to confirm that.A failed result looks like this:
Both Xint and JIT enabled fail to pick up the redefined class so after the redefinition it still reads
intField
as 0.In the JIT'd code, the compiled method looks like this:
Note how the constructor is a call to
java/lang/Object.<init>()V
with no guard to check for redefinition.If the line is uncommented in the pre-redefined InitObject class, the test will pick up the redefinition and pass:
The cause of the problem appears to be forwarder methods.
openj9/runtime/vm/resolvesupport.cpp
Line 1307 in 881038d
If
J9_LOOK_ALLOW_FWD
is removed there, the test will also pass.Enabling extended HCR will cause the test to pass under Xint but not with the JIT:
Running instructions:
Download: RedefEmptyInit.zip
It contains 5 files:
Commands:
This was run on ppcle JDK11 but the problem should be common.
The text was updated successfully, but these errors were encountered: