Skip to content

Commit 1e2c4c0

Browse files
authored
Merge pull request #6773 from jdmpapin/iface-prex
Stop devirtualizing interface calls in preexistence
2 parents 7720454 + f5ab765 commit 1e2c4c0

File tree

1 file changed

+65
-3
lines changed

1 file changed

+65
-3
lines changed

compiler/optimizer/LocalOpts.cpp

+65-3
Original file line numberDiff line numberDiff line change
@@ -7291,7 +7291,62 @@ void TR_InvariantArgumentPreexistence::processIndirectCall(TR::Node *node, TR::T
72917291

72927292
// Quit if class is not compatible with the method
72937293
if (resolvedMethod && receiverInfo->getClass() && !classIsCompatibleWithMethod(receiverInfo->getClass(), resolvedMethod))
7294+
{
7295+
if (trace())
7296+
traceMsg(comp(), "PREX: - Receiver type incompatible with method \n");
7297+
72947298
return;
7299+
}
7300+
7301+
TR::MethodSymbol *methSymbol = node->getSymbol()->getMethodSymbol();
7302+
if (methSymbol->isInterface())
7303+
{
7304+
// Interface type signatures can't be trusted most places in bytecode, so
7305+
// only transform interface calls when we have a class bound for the
7306+
// receiver.
7307+
TR_OpaqueClassBlock *klass = receiverInfo->getClass();
7308+
if (klass == NULL || TR::Compiler->cls.isInterfaceClass(comp(), klass))
7309+
{
7310+
if (trace())
7311+
{
7312+
traceMsg(
7313+
comp(),
7314+
"PREX: - No class type bound for interface call receiver\n");
7315+
}
7316+
7317+
return;
7318+
}
7319+
7320+
TR_ResolvedMethod *caller = node->getSymbolReference()->getOwningMethod(comp());
7321+
TR::Method *callee = methSymbol->getMethod();
7322+
bool aotOk = true;
7323+
TR_OpaqueClassBlock *iface = fe()->getClassFromSignature(
7324+
callee->classNameChars(), callee->classNameLength(), caller, aotOk);
7325+
7326+
if (iface == NULL)
7327+
{
7328+
if (trace())
7329+
{
7330+
traceMsg(
7331+
comp(),
7332+
"PREX: - Failed to identify interface for interface call\n");
7333+
}
7334+
7335+
return;
7336+
}
7337+
7338+
if (fe()->isInstanceOf(klass, iface, true, true, true) != TR_yes)
7339+
{
7340+
if (trace())
7341+
{
7342+
traceMsg(
7343+
comp(),
7344+
"PREX: - Insufficient class type bound for interface call receiver\n");
7345+
}
7346+
7347+
return;
7348+
}
7349+
}
72957350

72967351
//
72977352
// Step 2: Transform
@@ -7395,7 +7450,6 @@ void TR_InvariantArgumentPreexistence::processIndirectCall(TR::Node *node, TR::T
73957450
TR::ClassTableCriticalSection processIndirectCall(comp()->fe());
73967451
TR::SymbolReference *symRef = node->getSymbolReference();
73977452
TR_PersistentCHTable * chTable = comp()->getPersistentInfo()->getPersistentCHTable();
7398-
TR::MethodSymbol *methSymbol = node->getSymbol()->getMethodSymbol();
73997453
if (methSymbol->isInterface() || methodSymbol)
74007454
{
74017455
TR_ResolvedMethod * method = NULL;
@@ -7414,8 +7468,16 @@ void TR_InvariantArgumentPreexistence::processIndirectCall(TR::Node *node, TR::T
74147468
{
74157469
if (comp()->getPersistentInfo()->getRuntimeAssumptionTable()->getAssumptionCount(RuntimeAssumptionOnClassExtend) < 100000)
74167470
method = chTable->findSingleInterfaceImplementer(receiverInfo->getClass(), node->getSymbolReference()->getCPIndex(), node->getSymbolReference()->getOwningMethod(comp()), comp());
7417-
//if (method)
7418-
// fprintf(stderr, "%s assumptios=%d\n", comp()->signature(), comp()->getPersistentInfo()->getRuntimeAssumptionTable()->getAssumptionCount(RuntimeAssumptionOnClassExtend));
7471+
if (method == NULL)
7472+
{
7473+
if (trace())
7474+
{
7475+
traceMsg(
7476+
comp(),
7477+
"PREX: - Failed to find interface callee\n");
7478+
}
7479+
return;
7480+
}
74197481
}
74207482
else
74217483
{

0 commit comments

Comments
 (0)