Path: blob/master/runtime/compiler/optimizer/HotFieldMarking.cpp
6000 views
/*******************************************************************************1* Copyright (c) 2020, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#include "optimizer/HotFieldMarking.hpp"23#include "env/j9method.h"24#include "il/Block.hpp"25#include "il/Node.hpp"26#include "il/Node_inlines.hpp"27#include "il/SymbolReference.hpp"28#include "il/TreeTop.hpp"29#include "infra/ILWalk.hpp"30#include "optimizer/Optimizer.hpp"31#include "optimizer/Optimization.hpp"32#include "optimizer/Optimization_inlines.hpp"33#include "optimizer/OptimizationManager.hpp"3435#include <map>3637/**38* @struct that represents the statistics related to each field during a compilation39* Member '_count' contains the number of blocks within the compilation that contributes to the frequency score value of the field40* Member '_score' contains the combined block frequency score of the field for the compilation41* Member '_clazz' contains the class of the field42*/43struct SymStats44{45int32_t _count;46int32_t _score;47int32_t _fieldNameLength;48char* _fieldName;49int32_t _fieldSigLength;50char* _fieldSig;51TR_OpaqueClassBlock *_clazz;52SymStats(int32_t count, int32_t score, int32_t fieldNameLength, char* fieldName, int32_t fieldSigLength, char* fieldSig, TR_OpaqueClassBlock *clazz) :53_count(count), _score(score), _fieldNameLength(fieldNameLength), _fieldName(fieldName), _fieldSigLength(fieldSigLength), _fieldSig(fieldSig), _clazz(clazz) {}54};5556typedef TR::typed_allocator<std::pair<TR::Symbol* const, SymStats *>, TR::Region&> SymAggMapAllocator;57typedef std::less<TR::Symbol *> SymAggMapComparator;58typedef std::map<TR::Symbol *, SymStats *, SymAggMapComparator, SymAggMapAllocator> SymAggMap;59typedef int32_t(*BlockFrequencyReducer)(int32_t, int32_t, int32_t);6061static int32_t getReducedFrequencySum(int32_t currentValue, int32_t count, int32_t newFrequency)62{63return (currentValue + newFrequency);64}6566static int32_t getReducedFrequencyAverage(int32_t currentValue, int32_t count, int32_t newFrequency)67{68return ((currentValue * count) + newFrequency) / (count + 1);69}7071static int32_t getReducedFrequencyMax(int32_t currentValue, int32_t count, int32_t newFrequency)72{73return (currentValue < newFrequency) ? newFrequency : currentValue;74}7576int32_t TR_HotFieldMarking::perform()77{78if (!TR::Compiler->om.isHotReferenceFieldRequired())79{80if (trace())81traceMsg(comp(), "Skipping hot field marking since dynamic breadth first scan ordering is disabled\n");82return 0;83}8485SymAggMap stats((SymAggMapComparator()), SymAggMapAllocator(comp()->trMemory()->currentStackRegion()));86TR::Block *block = NULL;8788static BlockFrequencyReducer getReducedFrequency;89if(TR::Options::getReductionAlgorithm(TR_HotFieldReductionAlgorithmSum))90{91getReducedFrequency = getReducedFrequencySum;92}93else if(TR::Options::getReductionAlgorithm(TR_HotFieldReductionAlgorithmMax))94{95getReducedFrequency = getReducedFrequencyMax;96}97else98{99getReducedFrequency = getReducedFrequencyAverage;100}101102for (TR::PostorderNodeIterator it(comp()->getStartTree(), comp()); it != NULL; ++it)103{104TR::Node * const node = it.currentNode();105if (node->getOpCodeValue() == TR::BBStart)106{107block = node->getBlock();108}109else if ((node->getOpCode().isLoadIndirect() || node->getOpCode().isStoreIndirect())110&& node->getOpCode().hasSymbolReference()111&& !node->getSymbolReference()->isUnresolved()112&& node->getSymbolReference()->getSymbol()->isShadow()113&& !node->isInternalPointer()114&& !node->getOpCode().isArrayLength()115&& node->getSymbolReference()->getSymbol()->isCollectedReference()116)117{118TR::SymbolReference *symRef = node->getSymbolReference();119if (symRef->getCPIndex() >= 0 && !symRef->getSymbol()->isArrayShadowSymbol())120{121auto itr = stats.find(symRef->getSymbol());122if (itr != stats.end())123{124itr->second->_score = getReducedFrequency(itr->second->_score, itr->second->_count, block->getFrequency());125itr->second->_count += 1;126continue;127}128129TR::ResolvedMethodSymbol *rms = comp()->getOwningMethodSymbol(symRef->getOwningMethodIndex());130TR_ResolvedMethod *method = rms->getResolvedMethod();131132int32_t fieldNameLength = 0;133char *fieldName = method->fieldNameChars(symRef->getCPIndex(), fieldNameLength);134int32_t fieldSigLength = 0;135char *fieldSig = method->fieldSignatureChars(symRef->getCPIndex(), fieldSigLength);136bool isStatic = false;137TR_OpaqueClassBlock *containingClass = static_cast<TR_ResolvedJ9Method*>(method)->definingClassFromCPFieldRef(comp(), symRef->getCPIndex(), isStatic);138if (isStatic)139continue;140141stats[symRef->getSymbol()] = new (trStackMemory()) SymStats(1, block->getFrequency(), fieldNameLength, fieldName, fieldSigLength, fieldSig, containingClass);142}143}144}145146for (auto itr = stats.begin(), end = stats.end(); itr != end; ++itr)147{148if (itr->second->_score >= TR::Options::_hotFieldThreshold)149{150uint32_t fieldOffset = (comp()->fej9()->getInstanceFieldOffset(itr->second->_clazz, itr->second->_fieldName, itr->second->_fieldNameLength, itr->second->_fieldSig, itr->second->_fieldSigLength) + TR::Compiler->om.objectHeaderSizeInBytes()) / TR::Compiler->om.sizeofReferenceField();151152if (!comp()->fej9()->isAnonymousClass(itr->second->_clazz) && performTransformation(comp(), "%sUpdate hot field info for hot field. fieldSignature: %s; fieldName: %s; frequencyScore = %d\n", optDetailString(), itr->second->_fieldSig, itr->second->_fieldName, itr->second->_score) && (fieldOffset < U_8_MAX))153{154comp()->fej9()->reportHotField(getUtilization(), TR::Compiler->cls.convertClassOffsetToClassPtr(itr->second->_clazz), (uint8_t)fieldOffset, itr->second->_score);155if (comp()->getOption(TR_TraceMarkingOfHotFields))156{157int32_t classNameLength = 0;158char *className = comp()->fej9()->getClassNameChars(itr->second->_clazz, classNameLength);159traceMsg(comp(), "<traceMarkingOfHotFields\n"160"\tmethodSignature=\"%s\"\n"161"\tmethodHotness=\"%s\"\n"162"\tclassName=\"%s\"\n"163"\tfieldName=\"%s\""164"\tfieldSig=\"%s\""165"\tfrequencyScore=%d"166"\tfieldOffset=%d>\n",167comp()->signature(), comp()->getHotnessName(comp()->getMethodHotness()), className, itr->second->_fieldName, itr->second->_fieldSig, itr->second->_score, fieldOffset);168}169}170}171}172return 1;173}174175int32_t TR_HotFieldMarking::getUtilization()176{177static const char *hotFieldMarkingUtilizationWarmAndBelow;178static int32_t hotFieldMarkingUtilizationWarmAndBelowValue = (hotFieldMarkingUtilizationWarmAndBelow = feGetEnv("TR_hotFieldMarkingUtilizationWarmAndBelow")) ? atoi(hotFieldMarkingUtilizationWarmAndBelow) : 1;179180static const char *hotFieldMarkingUtilizationHot;181static int32_t hotFieldMarkingUtilizationHotValue = (hotFieldMarkingUtilizationHot = feGetEnv("TR_hotFieldMarkingUtilizationHot")) ? atoi(hotFieldMarkingUtilizationHot) : 10;182183static const char *hotFieldMarkingUtilizationScorching;184static int32_t hotFieldMarkingUtilizationScorchingValue = (hotFieldMarkingUtilizationScorching = feGetEnv("TR_hotFieldMarkingUtilizationScorching")) ? atoi(hotFieldMarkingUtilizationScorching) : 100;185186switch (comp()->getMethodHotness())187{188case noOpt:189case cold:190case warm:191return hotFieldMarkingUtilizationWarmAndBelowValue;192case hot:193return hotFieldMarkingUtilizationHotValue;194case veryHot:195case scorching:196return hotFieldMarkingUtilizationScorchingValue;197default:198TR_ASSERT(false, "Unable handled hotness for utilization calculation");199}200return 0;201}202203const char *204TR_HotFieldMarking::optDetailString() const throw()205{206return "O^O HOT FIELD MARKING: ";207}208209210