From a628c7796b8b9d9721ecdbd88c0ecfaa35690d87 Mon Sep 17 00:00:00 2001 From: Devin Papineau Date: Thu, 9 Jun 2022 19:42:48 -0400 Subject: [PATCH] Be more confident about single interface implementer profiled guards These guards used to be nop guards. They no longer are, but only because certain kinds of bytecode are technically allowed to be loaded. Bytecode that is problematic in this way should be exceedingly rare though, so treat these guards more like the nop guards we used to have by marking the taken side cold and by making sure to allow privatized argument rematerialization. --- runtime/compiler/optimizer/InlinerTempForJ9.cpp | 10 +++++++--- runtime/compiler/optimizer/J9Inliner.cpp | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/runtime/compiler/optimizer/InlinerTempForJ9.cpp b/runtime/compiler/optimizer/InlinerTempForJ9.cpp index 8934b0c7365..3699e3629d1 100644 --- a/runtime/compiler/optimizer/InlinerTempForJ9.cpp +++ b/runtime/compiler/optimizer/InlinerTempForJ9.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corp. and others + * Copyright (c) 2000, 2022 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -2847,7 +2847,7 @@ TR_MultipleCallTargetInliner::eliminateTailRecursion( backEdge = TR::CFGEdge::createEdge(gotoBlock, branchDestination, trMemory()); callerCFG->addEdge(backEdge); callerCFG->removeEdge(origEdge); - if (guard->_kind == TR_ProfiledGuard) + if (guard->_kind == TR_ProfiledGuard && !guard->_forceTakenSideCold) { if (block->getFrequency() < 0) block2->setFrequency(block->getFrequency()); @@ -6784,7 +6784,11 @@ TR_J9InlinerPolicy::suitableForRemat(TR::Compilation *comp, TR::Node *callNode, bool suitableForRemat = true; TR_AddressInfo *valueInfo = static_cast(TR_ValueProfileInfoManager::getProfiledValueInfo(callNode, comp, AddressInfo)); - if (guard->isHighProbablityProfiledGuard()) + if (guard->_forceTakenSideCold) + { + // remat ok + } + else if (guard->isHighProbablityProfiledGuard()) { if (comp->getMethodHotness() <= warm && comp->getPersistentInfo()->getJitState() == STARTUP_STATE) { diff --git a/runtime/compiler/optimizer/J9Inliner.cpp b/runtime/compiler/optimizer/J9Inliner.cpp index 63dd336104c..787c23c397d 100644 --- a/runtime/compiler/optimizer/J9Inliner.cpp +++ b/runtime/compiler/optimizer/J9Inliner.cpp @@ -944,6 +944,20 @@ bool TR_J9InterfaceCallSite::findCallSiteTargetImpl(TR_CallStack *callStack, TR_ new (comp()->trHeapMemory()) TR_VirtualGuardSelection( kind, testType, thisClass); + if (kind == TR_ProfiledGuard) + { + // Almost all bytecode would pass type checking even including + // interface types. So even though this can't be a nop guard + // (because verification doesn't check interface types), treat it + // as much like a nop guard as possible. In particular, this will + // ensure that the block containing the cold call is actually + // marked cold, and ensure that priv. arg remat is allowed. + guard->_forceTakenSideCold = true; + + // It is still a high-probability profiled guard... + guard->setIsHighProbablityProfiledGuard(); + } + addTarget( comp()->trMemory(), inliner,