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
Stop devirtualizing interface calls in preexistence #6773
Conversation
Previously, it was possible for the JIT to devirtualize an interface call, and for execution to reach the call (whether inlined or not) with a receiver that is not an instance of the class expected by the implementing method. The callee could then access fields of the receiver as though it were of the expected type. The conditionals added in this commit still allow (on their own) for an interface call to be devirtualized when preexistence has already proven that the receiver is an instance of some particular class that implements the expected interface. However, preexistence currently fails to devirtualize in that situation. It passes the class to TR_PersistentCHTable::findSingleInterfaceImplementer(), which needs the interface. This can be improved in the future by having preexistence treat the call in the same way as a non-interface call, but with the added requirement that the devirtualized callee must be public.
| @@ -7411,8 +7465,16 @@ void TR_InvariantArgumentPreexistence::processIndirectCall(TR::Node *node, TR::T | |||
| { | |||
| if (comp()->getPersistentInfo()->getRuntimeAssumptionTable()->getAssumptionCount(RuntimeAssumptionOnClassExtend) < 100000) | |||
| method = chTable->findSingleInterfaceImplementer(receiverInfo->getClass(), node->getSymbolReference()->getCPIndex(), node->getSymbolReference()->getOwningMethod(comp()), comp()); | |||
| //if (method) | |||
| // fprintf(stderr, "%s assumptios=%d\n", comp()->signature(), comp()->getPersistentInfo()->getRuntimeAssumptionTable()->getAssumptionCount(RuntimeAssumptionOnClassExtend)); | |||
| if (method == NULL) | |||
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.
This is just an early return I guess, in that nothing could be done with a null method anyway.
|
Jenkins build all |
|
Checks have passed except for known infra issues. The changes are quite safe in that we simply avoid optimizing in some cases where we cannot rely on signatures. Merging. |
Previously, it was possible for the JIT to devirtualize an interface call, and for execution to reach the call (whether inlined or not) with a receiver that is not an instance of the class expected by the implementing method. The callee could then access fields of the receiver as though it were of the expected type.
The conditionals added in this commit still allow (on their own) for an interface call to be devirtualized when preexistence has already proven that the receiver is an instance of some particular class that implements the expected interface. However, preexistence currently fails to devirtualize in that situation. It passes the class to
TR_PersistentCHTable::findSingleInterfaceImplementer(), which needs the interface. This can be improved in the future by having preexistence treat the call in the same way as a non-interface call, but with the added requirement that the devirtualized callee must be public.