Path: blob/master/runtime/compiler/control/CompilationRuntime.hpp
6000 views
/*******************************************************************************1* Copyright (c) 2000, 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#ifndef COMPILATION_RUNTIME_HPP23#define COMPILATION_RUNTIME_HPP2425#pragma once2627#include "AtomicSupport.hpp"28#include "compile/CompilationTypes.hpp"29#include "control/CompilationPriority.hpp"30#include "control/ClassHolder.hpp"31#include "control/MethodToBeCompiled.hpp"32#include "env/CpuUtilization.hpp"33#include "env/Processors.hpp"34#include "env/ProcessorInfo.hpp"35#include "env/TRMemory.hpp"36#include "env/jittypes.h"37#include "infra/Flags.hpp"38#include "infra/Statistics.hpp"39#include "control/rossa.h"40#include "runtime/RelocationRuntime.hpp"41#if defined(J9VM_OPT_JITSERVER)42#include "control/JITServerHelpers.hpp"43#include "env/PersistentCollections.hpp"44#include "net/ServerStream.hpp"45#endif /* defined(J9VM_OPT_JITSERVER) */4647extern "C" {48struct J9Method;49struct J9JITConfig;50struct J9VMThread;51struct J9ROMMethod;52struct J9ClassLoader;53struct J9SharedClassJavacoreDataDescriptor;54}5556class CpuUtilization;57namespace TR { class CompilationInfoPerThread; }58namespace TR { class CompilationInfoPerThreadBase; }59class TR_FilterBST;60class TR_FrontEnd;61class TR_HWProfiler;62class TR_J9VMBase;63class TR_LowPriorityCompQueue;64class TR_OptimizationPlan;65class TR_PersistentMethodInfo;66class TR_RelocationRuntime;67class TR_ResolvedMethod;68namespace TR { class MonitorTable; }69namespace TR { class IlGeneratorMethodDetails; }70namespace TR { class Options; }71namespace J9 { class RWMonitor; }72struct TR_JitPrivateConfig;73struct TR_MethodToBeCompiled;74template <typename T> class TR_PersistentArray;75typedef J9JITExceptionTable TR_MethodMetaData;76#if defined(J9VM_OPT_JITSERVER)77class ClientSessionHT;78class JITServerAOTCacheMap;79class JITServerAOTDeserializer;80class JITServerSharedROMClassCache;81#endif /* defined(J9VM_OPT_JITSERVER) */8283struct TR_SignatureCountPair84{85TR_PERSISTENT_ALLOC(TR_Memory::OptimizationPlan)86TR_SignatureCountPair(char *string, int32_t c)87{88count = c;8990for(int32_t i=0 ; i < 4000 ; i++)91{92signature[i] = string[i];93if(string[i] == '\0')94break;95}9697};98char signature[4000];99int32_t count;100};101102103class TR_LowPriorityCompQueue104{105public:106TR_PERSISTENT_ALLOC(TR_Memory::PersistentInfo); // TODO: define its own category107static const uint32_t HT_SIZE = (1 << 13); // power of two for cheap modulo108TR_LowPriorityCompQueue();109~TR_LowPriorityCompQueue();110111void setCompInfo(TR::CompilationInfo *compInfo) { _compInfo = compInfo; }112bool hasLowPriorityRequest() const { return (_firstLPQentry != NULL); }113TR_MethodToBeCompiled *getFirstLPQRequest() const { return _firstLPQentry; }114TR_MethodToBeCompiled *extractFirstLPQRequest();115TR_MethodToBeCompiled *findAndDequeueFromLPQ(TR::IlGeneratorMethodDetails &details,116uint8_t reason, TR_J9VMBase *fe, bool & dequeued);117void enqueueCompReqToLPQ(TR_MethodToBeCompiled *compReq);118bool createLowPriorityCompReqAndQueueIt(TR::IlGeneratorMethodDetails &details, void *startPC, uint8_t reason);119bool addFirstTimeCompReqToLPQ(J9Method *j9method, uint8_t reason);120bool addUpgradeReqToLPQ(TR_MethodToBeCompiled*, uint8_t reason = TR_MethodToBeCompiled::REASON_UPGRADE);121int32_t getLowPriorityQueueSize() const { return _sizeLPQ; }122int32_t getLPQWeight() const { return _LPQWeight; }123void increaseLPQWeightBy(uint8_t weight) { _LPQWeight += (int32_t)weight; }124void decreaseLPQWeightBy(uint8_t weight) { _LPQWeight -= (int32_t)weight; }125void invalidateRequestsForUnloadedMethods(J9Class * unloadedClass);126void purgeLPQ();127128// The following refer to the mechanism that schedules low priority129// compilation requests based on the Iprofiler130static uint32_t hash(J9Method *j9method) { return ((uintptr_t)j9method >> 3) & (HT_SIZE - 1); }131bool isTrackingEnabled() const { return _trackingEnabled; }132void startTrackingIProfiledCalls(int32_t threshold);133bool isTrackableMethod(J9Method *j9method) const;134void stopTrackingMethod(J9Method *j9method); // Executed by the compilation thread when a low pri req is processed135void tryToScheduleCompilation(J9VMThread *vmThread, J9Method *j9method); // Executed by the IProfiler thread136void purgeEntriesOnClassLoaderUnloading(J9ClassLoader *j9classLoader);137void purgeEntriesOnClassRedefinition(J9Class *j9class);138void printStats() const;139void incStatsBypass() { _STAT_bypass++; } // Done by comp threads140void incStatsCompFromLPQ(uint8_t reason); // Done by JIT141void incStatsReqQueuedToLPQ(uint8_t reason);142void incNumFailuresToEnqueue() { _STAT_numFailedToEnqueueInLPQ++; }143144struct Entry145{146uintptr_t _j9method; // this is the key; Initialized by IProfiler thread; reset by compilation thread147uint32_t _count; // updated by IProfiler thread148bool _queuedForCompilation; // used to avoid duplicates in the queue; set by IProfiler thread149bool isInvalid() const { return !_j9method; }150void setInvalid() { _j9method = 0; }151void initialize(J9Method *m, uint32_t c) { _j9method = (uintptr_t)m; _count = c; _queuedForCompilation = false; }152};153private:154TR::CompilationInfo* _compInfo;155TR_MethodToBeCompiled* _firstLPQentry; // first entry of low priority queue156TR_MethodToBeCompiled* _lastLPQentry; // last entry of low priority queue157int32_t _sizeLPQ; // size of low priority queue158int32_t _LPQWeight; // weight of low priority queue159uint32_t _threshold;160bool _trackingEnabled;161// Direct mapped hashtable that records j9methods and "counts"162Entry *_spine; // my hashtable163// stats written by IProfiler thread164uint32_t _STAT_compReqQueuedByIProfiler;165uint32_t _STAT_conflict;166uint32_t _STAT_staleScrubbed;167// stats written by comp thread168uint32_t _STAT_bypass; // an LPQ compilation was overtaken by a normal compilation169uint32_t _STAT_compReqQueuedByJIT;170uint32_t _STAT_LPQcompFromIprofiler; // first time compilations coming from LPQ171uint32_t _STAT_LPQcompFromInterpreter;172uint32_t _STAT_LPQcompUpgrade;173// stats written by application threads174uint32_t _STAT_compReqQueuedByInterpreter;175uint32_t _STAT_numFailedToEnqueueInLPQ;176}; // TR_LowPriorityCompQueue177178179// Definition of compilation queue to hold JProfiling candidates180class TR_JProfilingQueue181{182public:183TR_PERSISTENT_ALLOC(TR_Memory::PersistentInfo); // TODO: define its own category184TR_JProfilingQueue() : _firstQentry(NULL), _lastQentry(NULL), _size(0), _weight(0), _allowProcessing(false) {};185void setCompInfo(TR::CompilationInfo *compInfo) { _compInfo = compInfo; }186bool isEmpty() const { return (_firstQentry == NULL); }187TR_MethodToBeCompiled *getFirstCompRequest() const { return _firstQentry; }188TR_MethodToBeCompiled *extractFirstCompRequest();189bool createCompReqAndQueueIt(TR::IlGeneratorMethodDetails &details, void *startPC);190int32_t getQSize() const { return _size; }191int32_t getQWeight() const { return _weight; }192bool getAllowProcessing() const { return _allowProcessing; }193void setAllowProcessing() { _allowProcessing = true; }194static bool isJProfilingCandidate(TR_MethodToBeCompiled *entry, TR::Options *options, TR_J9VMBase* fej9);195void invalidateRequestsForUnloadedMethods(J9Class * unloadedClass);196void purge();197private:198void increaseQWeightBy(uint8_t weight) { _weight += (int32_t)weight; }199void decreaseQWeightBy(uint8_t weight) { _weight -= (int32_t)weight; }200void enqueueCompReq(TR_MethodToBeCompiled *compReq);201202TR::CompilationInfo* _compInfo;203TR_MethodToBeCompiled* _firstQentry; // first entry of JProfiling queue204TR_MethodToBeCompiled* _lastQentry; // last entry of JProfiling queue205int32_t _size; // size of JProfiling queue206int32_t _weight; // weight of JProfiling queue207bool _allowProcessing;208};209210211// Supporting class for getting information on density of samples212class TR_JitSampleInfo213{214public:215void init()216{217_maxSamplesPerSecond = 0;218_samplesPerSecondDuringLastInterval = 0;219_sizeOfLastInterval = 1; // avoid check for divide by 0220_globalSampleCounterInLastInterval = 0;221_timestampOfLastInterval = 0;222_increaseFactor = 1;223}224TR_JitSampleInfo() { init(); }225uint32_t getMaxSamplesPerSecond() const { return _maxSamplesPerSecond; }226uint32_t getSamplesPerSecondDuringLastInterval() const { return _samplesPerSecondDuringLastInterval; }227uint32_t getCurrentSamplesPerSecond(uint64_t crtTime, uint32_t crtGlobalSampleCounter) const228{229uint64_t diffTime = crtTime - _timestampOfLastInterval;230return diffTime > 0 ? (crtGlobalSampleCounter - _globalSampleCounterInLastInterval) * 1000 / diffTime : 0;231}232void update(uint64_t crtTime, uint32_t crtGlobalSampleCounter);233uint32_t getIncreaseFactor() const { return _increaseFactor; }234private:235uint32_t _maxSamplesPerSecond;236uint32_t _samplesPerSecondDuringLastInterval;237uint32_t _sizeOfLastInterval; // ms238uint32_t _globalSampleCounterInLastInterval;239uint64_t _timestampOfLastInterval;240uint32_t _increaseFactor;241}; // class TR_JitSampleInfo242243// The following class is used for tracking methods that have their invocation244// count decremented due to a sample in interpreted code. When that happens245// we add the method to a list. When a method needs to be compiled we check246// the list and if the method is in the list we delete it and schedule a247// SamplingJprofiling compilation for the count that has been skipped248class TR_InterpreterSamplingTracking249{250public:251TR_PERSISTENT_ALLOC(TR_MemoryBase::CompilationInfo);252class TR_MethodCnt253{254friend class TR_InterpreterSamplingTracking;255TR_MethodCnt(J9Method *m, int32_t c) : _next(NULL), _method(m), _skippedCount(c) {}256257TR_MethodCnt *_next;258J9Method * _method;259int32_t _skippedCount;260};261262TR_InterpreterSamplingTracking(TR::CompilationInfo *compInfo) :263_container(NULL), _compInfo(compInfo), _maxElements(0), _size(0) {}264// both these methods need the compilation monitor in hand265void addOrUpdate(J9Method *method, int32_t cnt);266int32_t findAndDelete(J9Method *method);267void onClassUnloading() {/* TODO: prune list when classes change or get unloaded */}268uint32_t getMaxElements() const { return _maxElements; }269private:270TR_MethodCnt *_container;271TR::CompilationInfo *_compInfo; // cache value of compInfo272uint32_t _maxElements;273uint32_t _size;274};275276277class J9Method_HT278{279public:280TR_PERSISTENT_ALLOC(TR_MemoryBase::CompilationInfo);281static const size_t LOG_HT_SIZE = 6;282static const size_t HT_SIZE = 1 << LOG_HT_SIZE;283static const size_t MASK = HT_SIZE - 1;284struct HT_Entry285{286HT_Entry *_next; // for linking entries together287J9Method *_j9method;288volatile int32_t _count; // invocation count when last visited289uint32_t _seqID;290uint64_t _timestamp;291HT_Entry(J9Method *j9method, uint64_t timestamp);292uint64_t getTimestamp() const { return _timestamp; }293};294J9Method_HT(TR::PersistentInfo *persistentInfo);295size_t getNumEntries() const { return _numEntries; }296// method used by various hooks that perform class unloading297void onClassUnloading();298299protected:300TR::PersistentInfo *getPersistentInfo() const { return _persistentInfo; }301size_t hash(J9Method *j9method) const302{ return (size_t)(((uintptr_t)j9method >> 3) ^ ((uintptr_t)j9method >> (3 + LOG_HT_SIZE))); }303HT_Entry *find(J9Method *j9method) const;304bool addNewEntry(J9Method *j9method, uint64_t timestamp);305private:306// Backbone of the hashtable307struct HT_Entry *_spine[HT_SIZE];308TR::PersistentInfo *_persistentInfo;309int32_t _numEntries; // for stats; may be imprecise due to multithreading issues310};311312class DLTTracking : public J9Method_HT313{314public:315DLTTracking(TR::PersistentInfo *persistentInfo) : J9Method_HT(persistentInfo) {}316// Method used by application threads when a DLT decision needs to be taken317// Need to have VMaccess in hand318bool shouldIssueDLTCompilation(J9Method *j9method, int32_t numHitsInDLTBuffer);319320// Method used by application threads whenever invocation count321// for a method is changed abruptly (e.g. interpreter sampling)322// Need to have VMaccess in hand323void adjustStoredCounterForMethod(J9Method *j9method, int32_t countDiff);324};325326327328//--------------------------------- TR::CompilationInfo -----------------------329namespace TR330{331332class CompilationInfo333{334public:335friend class TR::CompilationInfoPerThreadBase;336friend class TR::CompilationInfoPerThread;337friend class ::TR_LowPriorityCompQueue;338friend class ::TR_JProfilingQueue;339340TR_PERSISTENT_ALLOC(TR_MemoryBase::CompilationInfo);341342enum hotnessWeights343{344AOT_LOAD_WEIGHT = 1, // actually AOT loads have their own parameter345THUNKS_WEIGHT = 1,346NOOPT_WEIGHT = 1,347COLD_WEIGHT = 2,348WARM_LOOPLESS_WEIGHT = 6,349WARM_LOOPY_WEIGHT = 12,350JSR292_WEIGHT = 20,351HOT_WEIGHT = 30,352VERY_HOT_WEIGHT = 100,353MAX_WEIGHT = 255354};355356enum TR_SamplerStates357{358SAMPLER_NOT_INITIALIZED = 0,359SAMPLER_DEFAULT,360SAMPLER_IDLE,361SAMPLER_DEEPIDLE,362SAMPLER_SUSPENDED,363SAMPLER_STOPPED,364SAMPLER_LAST_STATE, // must be the last one365// If adding new state, one must add a new name as well in samplerThreadStateNames array366// and a frequency in samplerThreadStateFrequencies array367};368369enum TR_SamplingThreadLifetimeStates370{371SAMPLE_THR_NOT_CREATED = 0,372SAMPLE_THR_FAILED_TO_ATTACH,373SAMPLE_THR_ATTACHED,374SAMPLE_THR_INITIALIZED,375SAMPLE_THR_STOPPING,376SAMPLE_THR_DESTROYED,377SAMPLE_THR_LAST_STATE // must be the last one378};379380enum TR_CompThreadActions381{382PROCESS_ENTRY,383GO_TO_SLEEP_EMPTY_QUEUE,384GO_TO_SLEEP_CONCURRENT_EXPENSIVE_REQUESTS,385SUSPEND_COMP_THREAD_EXCEED_CPU_ENTITLEMENT,386THROTTLE_COMP_THREAD_EXCEED_CPU_ENTITLEMENT,387SUSPEND_COMP_THREAD_EMPTY_QUEUE,388UNDEFINED_ACTION389};390391struct DLT_record392{393DLT_record *_next;394J9Method *_method;395void *_dltEntry;396int32_t _bcIndex;397};398399struct CompilationStatistics400{401// perhaps not the greatest way to do this, but TR_Stats classes weren't an exact match402uint32_t _heartbeatWindowCount;403uint32_t _windowStartTick;404uint32_t _sampleMessagesSent;405uint32_t _sampleMessagesReceived;406uint32_t _interpretedMethodSamples;407uint32_t _compiledMethodSamples;408uint32_t _compiledMethodSamplesIgnored;409uint32_t _ticksInIdleMode;410uint32_t _methodsCompiledOnCount;411uint32_t _methodsReachingSampleInterval;412uint32_t _methodsSelectedToRecompile;413uint32_t _methodsSampleWindowReset;414}; // CompilationStatistics415416struct CompilationStatsPerInterval417{418uint32_t _interpretedMethodSamples;419uint32_t _compiledMethodSamples;420uint32_t _numFirstTimeCompilationsInInterval;421uint32_t _numRecompilationsInInterval;422uint32_t _numRecompPrevInterval;423uint32_t _samplesSentInInterval;424void reset()425{426_interpretedMethodSamples = _compiledMethodSamples = 0;427_numFirstTimeCompilationsInInterval = _numRecompilationsInInterval = 0;428_numRecompPrevInterval = 0; _samplesSentInInterval = 0;429}430void decay()431{432_interpretedMethodSamples >>= 1;433_compiledMethodSamples >>= 1;434_numFirstTimeCompilationsInInterval >>= 1;435_numRecompPrevInterval = _numRecompilationsInInterval; // remember the previous value436_numRecompilationsInInterval = (_numRecompilationsInInterval*2)/3;437_samplesSentInInterval = 0;438}439}; // CompilationStatsPerInterval440441static bool createCompilationInfo(J9JITConfig * jitConfig);442static void freeCompilationInfo(J9JITConfig *jitConfig);443static TR::CompilationInfo *get(J9JITConfig * = 0) { return _compilationRuntime; }444static bool shouldRetryCompilation(TR_MethodToBeCompiled *entry, TR::Compilation *comp);445static bool shouldAbortCompilation(TR_MethodToBeCompiled *entry, TR::PersistentInfo *persistentInfo);446static bool canRelocateMethod(TR::Compilation * comp);447static int computeCompilationThreadPriority(J9JavaVM *vm);448static void *compilationEnd(J9VMThread *context, TR::IlGeneratorMethodDetails & details, J9JITConfig *jitConfig, void * startPC,449void *oldStartPC, TR_FrontEnd *vm=0, TR_MethodToBeCompiled *entry=NULL, TR::Compilation *comp=NULL);450#if defined(J9VM_OPT_JITSERVER)451static JITServer::ServerStream *getStream();452#endif /* defined(J9VM_OPT_JITSERVER) */453static bool isInterpreted(J9Method *method) { return !isCompiled(method); }454455/**456* @brief Determines if a J9Method is compiled457*458* @param method pointer to the J9Method459*460* @return true if compiled, false otherwise461*/462static bool isCompiled(J9Method *method)463{464#if defined(J9VM_OPT_JITSERVER)465if (auto stream = getStream())466{467stream->write(JITServer::MessageType::CompInfo_isCompiled, method);468return std::get<0>(stream->read<bool>());469}470#endif /* defined(J9VM_OPT_JITSERVER) */471472return (getPCIfCompiled(method) != NULL);473}474475/**476* @brief Returns the PC of a method that is compiled477*478* @param method pointer to the J9Method479*480* @return The start PC if compiled, NULL otherwise481*/482static void* getPCIfCompiled(J9Method *method)483{484#if defined(J9VM_OPT_JITSERVER)485if (auto stream = getStream())486{487stream->write(JITServer::MessageType::CompInfo_getPCIfCompiled, method);488return std::get<0>(stream->read<void *>());489}490#endif /* defined(J9VM_OPT_JITSERVER) */491492/* Read extra field only once */493void *extra = method->extra;494495/* Return extra field if compiled, NULL otherwise */496return ((uintptr_t)extra & J9_STARTPC_NOT_TRANSLATED) == 0 ? extra : NULL;497}498499static bool isJNINative(J9Method *method)500{501#if defined(J9VM_OPT_JITSERVER)502if (auto stream = getStream())503{504stream->write(JITServer::MessageType::CompInfo_isJNINative, method);505return std::get<0>(stream->read<bool>());506}507#endif /* defined(J9VM_OPT_JITSERVER) */508// Note: This query is only concerned with the method to be compiled509// and so we don't have to care if the VM has a FastJNI version510return (((uintptr_t)method->constantPool) & J9_STARTPC_JNI_NATIVE) != 0;511}512513static const intptr_t J9_INVOCATION_COUNT_MASK = 0xffffffff;514515static int32_t getInvocationCount(J9Method *method)516{517#if defined(J9VM_OPT_JITSERVER)518if (auto stream = getStream())519{520stream->write(JITServer::MessageType::CompInfo_getInvocationCount, method);521return std::get<0>(stream->read<int32_t>());522}523#endif /* defined(J9VM_OPT_JITSERVER) */524if (((intptr_t)method->extra & J9_STARTPC_NOT_TRANSLATED) == 0)525return -1;526int32_t count = getJ9MethodVMExtra(method);527if (count < 0)528return count;529return count >> 1;530}531static intptr_t getJ9MethodExtra(J9Method *method)532{533#if defined(J9VM_OPT_JITSERVER)534if (auto stream = getStream())535{536stream->write(JITServer::MessageType::CompInfo_getJ9MethodExtra, method);537return (intptr_t) std::get<0>(stream->read<uint64_t>());538}539#endif /* defined(J9VM_OPT_JITSERVER) */540return (intptr_t)method->extra;541}542static int32_t getJ9MethodVMExtra(J9Method *method)543{544#if defined(J9VM_OPT_JITSERVER)545TR_ASSERT_FATAL(!TR::CompilationInfo::getStream(), "not yet implemented for JITServer");546#endif /* defined(J9VM_OPT_JITSERVER) */547return (int32_t)((intptr_t)method->extra);548}549static void * getJ9MethodStartPC(J9Method *method)550{551#if defined(J9VM_OPT_JITSERVER)552if (auto stream = getStream())553{554stream->write(JITServer::MessageType::CompInfo_getJ9MethodStartPC, method);555return std::get<0>(stream->read<void*>());556}557else558#endif /* defined(J9VM_OPT_JITSERVER) */559{560/* Read extra field only once */561void *extra = method->extra;562TR_ASSERT(!((intptr_t)extra & J9_STARTPC_NOT_TRANSLATED), "Method NOT Jitted!");563return extra;564}565}566static void setJ9MethodExtra(J9Method *method, intptr_t newValue)567{568#if defined(J9VM_OPT_JITSERVER)569if (auto stream = getStream())570{571stream->write(JITServer::MessageType::CompInfo_setJ9MethodExtra, method, (uint64_t) newValue);572std::get<0>(stream->read<JITServer::Void>());573}574else575#endif /* defined(J9VM_OPT_JITSERVER) */576{577method->extra = (void *)newValue;578}579}580static bool setJ9MethodExtraAtomic(J9Method *method, intptr_t oldValue, intptr_t newValue)581{582#if defined(J9VM_OPT_JITSERVER)583TR_ASSERT_FATAL(!TR::CompilationInfo::getStream(), "not yet implemented for JITServer");584#endif /* defined(J9VM_OPT_JITSERVER) */585return oldValue == VM_AtomicSupport::lockCompareExchange((UDATA*)&method->extra, oldValue, newValue);586}587static bool setJ9MethodExtraAtomic(J9Method *method, intptr_t newValue)588{589#if defined(J9VM_OPT_JITSERVER)590TR_ASSERT_FATAL(!TR::CompilationInfo::getStream(), "not yet implemented for JITServer");591#endif /* defined(J9VM_OPT_JITSERVER) */592intptr_t oldValue = (intptr_t)method->extra;593return setJ9MethodExtraAtomic(method, oldValue, newValue);594}595static bool setJ9MethodVMExtra(J9Method *method, int32_t value)596{597#if defined(J9VM_OPT_JITSERVER)598TR_ASSERT_FATAL(!TR::CompilationInfo::getStream(), "not yet implemented for JITServer");599#endif /* defined(J9VM_OPT_JITSERVER) */600intptr_t oldValue = (intptr_t)method->extra;601intptr_t newValue = (intptr_t)value;602return setJ9MethodExtraAtomic(method, oldValue, newValue);603}604static bool setInvocationCount(J9Method *method, int32_t newCount)605{606#if defined(J9VM_OPT_JITSERVER)607if (auto stream = getStream())608{609stream->write(JITServer::MessageType::CompInfo_setInvocationCount, method, newCount);610return std::get<0>(stream->read<bool>());611}612#endif /* defined(J9VM_OPT_JITSERVER) */613newCount = (newCount << 1) | J9_STARTPC_NOT_TRANSLATED;614if (newCount < 1)615return false;616return setJ9MethodVMExtra(method, newCount);617}618static bool setInvocationCount(J9Method *method, int32_t oldCount, int32_t newCount)619{620#if defined(J9VM_OPT_JITSERVER)621if (auto stream = getStream())622{623stream->write(JITServer::MessageType::CompInfo_setInvocationCountAtomic, method, oldCount, newCount);624return std::get<0>(stream->read<bool>());625}626#endif /* defined(J9VM_OPT_JITSERVER) */627newCount = (newCount << 1) | J9_STARTPC_NOT_TRANSLATED;628oldCount = (oldCount << 1) | J9_STARTPC_NOT_TRANSLATED;629if (newCount < 0)630return false;631intptr_t oldMethodExtra = (intptr_t) method->extra & (intptr_t)(~J9_INVOCATION_COUNT_MASK);632intptr_t newMethodExtra = oldMethodExtra | newCount;633oldMethodExtra = oldMethodExtra | oldCount;634bool success = setJ9MethodExtraAtomic(method, oldMethodExtra, newMethodExtra);635if (success)636{637DLTTracking *dltHT = _compilationRuntime->getDLT_HT();638if (dltHT)639dltHT->adjustStoredCounterForMethod(method, oldCount - newCount);640}641return success;642}643// If the invocation count is 0, set it to the value indicated by newCount644static bool replenishInvocationCountIfExpired(J9Method *method, int32_t newCount)645{646intptr_t oldMethodExtra = (intptr_t) method->extra;647if ((oldMethodExtra & J9_STARTPC_NOT_TRANSLATED) == 0)648return false; // Do not touch compiled methods649650int32_t oldCount = (int32_t)oldMethodExtra;651if (oldCount < 0)652return false; // Do not touch uncountable methods653oldCount >>= 1; // Eliminate the J9_STARTPC_NOT_TRANSLATED bit654if (oldCount != 0)655return false; // Only replenish invocation count if it expired656// Prepare the new method->extra657intptr_t oldMethodExtraUpperPart = oldMethodExtra & (~J9_INVOCATION_COUNT_MASK);658newCount = (newCount << 1) | J9_STARTPC_NOT_TRANSLATED;659intptr_t newMethodExtra = oldMethodExtraUpperPart | newCount;660return setJ9MethodExtraAtomic(method, oldMethodExtra, newMethodExtra);661}662static void setInitialInvocationCountUnsynchronized(J9Method *method, int32_t value)663{664#if defined(J9VM_OPT_JITSERVER)665TR_ASSERT_FATAL(!TR::CompilationInfo::getStream(), "not yet implemented for JITServer");666#endif /* defined(J9VM_OPT_JITSERVER) */667value = (value << 1) | J9_STARTPC_NOT_TRANSLATED;668if (value < 0)669value = INT_MAX;670method->extra = reinterpret_cast<void *>(static_cast<intptr_t>(value));671}672673static uint32_t getMethodBytecodeSize(const J9ROMMethod * romMethod);674static uint32_t getMethodBytecodeSize(J9Method* method);675676// Check to see if the J9AccMethodHasMethodHandleInvokes flag is set677static bool isJSR292(const J9ROMMethod *romMethod);678static bool isJSR292(J9Method *j9method);679680#if defined(J9VM_INTERP_AOT_COMPILE_SUPPORT) && defined(J9VM_OPT_SHARED_CLASSES) && (defined(TR_HOST_X86) || defined(TR_HOST_POWER) || defined(TR_HOST_S390) || defined(TR_HOST_ARM) || defined(TR_HOST_ARM64))681static void disableAOTCompilations();682#endif683684void * operator new(size_t s, void * p) throw() { return p; }685void operator delete (void *, void * p) {}686CompilationInfo (J9JITConfig *jitConfig);687TR::Monitor *getCompilationMonitor() {return _compilationMonitor;}688void acquireCompMonitor(J9VMThread *vmThread); // used when we know we have a compilation monitor689void releaseCompMonitor(J9VMThread *vmThread); // used when we know we have a compilation monitor690void waitOnCompMonitor(J9VMThread *vmThread);691intptr_t waitOnCompMonitorTimed(J9VMThread *vmThread, int64_t millis, int32_t nanos);692693TR_PersistentMemory * persistentMemory() { return _persistentMemory; }694695TR::PersistentInfo * getPersistentInfo() { return persistentMemory()->getPersistentInfo(); }696TR_MethodToBeCompiled *requestExistsInCompilationQueue(TR::IlGeneratorMethodDetails & details, TR_FrontEnd *fe);697698TR_MethodToBeCompiled *addMethodToBeCompiled(TR::IlGeneratorMethodDetails &details, void *pc, CompilationPriority priority,699bool async, TR_OptimizationPlan *optPlan, bool *queued, TR_YesNoMaybe methodIsInSharedCache);700#if defined(J9VM_OPT_JITSERVER)701TR_MethodToBeCompiled *addOutOfProcessMethodToBeCompiled(JITServer::ServerStream *stream);702#endif /* defined(J9VM_OPT_JITSERVER) */703void queueEntry(TR_MethodToBeCompiled *entry);704void recycleCompilationEntry(TR_MethodToBeCompiled *cur);705#if defined(J9VM_OPT_JITSERVER)706void requeueOutOfProcessEntry(TR_MethodToBeCompiled *entry);707#endif /* defined(J9VM_OPT_JITSERVER) */708TR_MethodToBeCompiled *adjustCompilationEntryAndRequeue(TR::IlGeneratorMethodDetails &details,709TR_PersistentMethodInfo *methodInfo,710TR_Hotness newOptLevel, bool useProfiling,711CompilationPriority priority, TR_J9VMBase *fe);712void changeCompReqFromAsyncToSync(J9Method * method);713int32_t promoteMethodInAsyncQueue(J9Method * method, void *pc);714TR_MethodToBeCompiled *getNextMethodToBeCompiled(TR::CompilationInfoPerThread *compInfoPT, bool compThreadCameOutOfSleep, TR_CompThreadActions*);715TR_MethodToBeCompiled *peekNextMethodToBeCompiled();716TR_MethodToBeCompiled *getMethodQueue() { return _methodQueue; }717int32_t getOverallCompCpuUtilization() const { return _overallCompCpuUtilization; } // -1 in case of error. 0 if feature is not enabled718void setOverallCompCpuUtilization(int32_t c) { _overallCompCpuUtilization = c; }719TR_YesNoMaybe exceedsCompCpuEntitlement() const { return _exceedsCompCpuEntitlement; }720void setExceedsCompCpuEntitlement(TR_YesNoMaybe value) { _exceedsCompCpuEntitlement = value; }721int32_t computeCompThreadSleepTime(int32_t compilationTimeMs);722bool isQueuedForCompilation(J9Method *, void *oldStartPC);723void * startPCIfAlreadyCompiled(J9VMThread *, TR::IlGeneratorMethodDetails & details, void *oldStartPC);724725static int32_t getCompThreadSuspensionThreshold(int32_t threadID) { return _compThreadSuspensionThresholds[threadID]; }726727// updateNumUsableCompThreads() is called before startCompilationThread() to update TR::Options::_numUsableCompilationThreads.728// It makes sure the number of usable compilation threads is within allowed bounds.729// If not, set it to the upper bound based on the mode: JITClient/non-JITServer or JITServer.730void updateNumUsableCompThreads(int32_t &numUsableCompThreads);731bool allocateCompilationThreads(int32_t numUsableCompThreads);732void freeAllCompilationThreads();733void freeAllResources();734735uintptr_t startCompilationThread(int32_t priority, int32_t id, bool isDiagnosticThread);736bool asynchronousCompilation();737void stopCompilationThreads();738739/**740* \brief741* Stops a compilation thread by issuing an interruption request at the threads next yield point and by changing742* its state to signal termination. Note that there can be a delay between making this request and the thread743* state changing to `COMPTHREAD_STOPPED`.744*745* \param compInfoPT746* The thread to be stopped.747*/748void stopCompilationThread(CompilationInfoPerThread* compInfoPT);749750void suspendCompilationThread();751void resumeCompilationThread();752void purgeMethodQueue(TR_CompilationErrorCode errorCode);753void *compileMethod(J9VMThread * context, TR::IlGeneratorMethodDetails &details, void *oldStartPC,754TR_YesNoMaybe async, TR_CompilationErrorCode *, bool *queued, TR_OptimizationPlan *optPlan);755756void *compileOnSeparateThread(J9VMThread * context, TR::IlGeneratorMethodDetails &details, void *oldStartPC,757TR_YesNoMaybe async, TR_CompilationErrorCode*,758bool *queued, TR_OptimizationPlan *optPlan);759void invalidateRequestsForUnloadedMethods(TR_OpaqueClassBlock *unloadedClass, J9VMThread * vmThread, bool hotCodeReplacement);760void invalidateRequestsForNativeMethods(J9Class * clazz, J9VMThread * vmThread);761#if defined(J9VM_JIT_DYNAMIC_LOOP_TRANSFER)762void *searchForDLTRecord(J9Method *method, int32_t bcIndex);763void insertDLTRecord(J9Method *method, int32_t bcIndex, void *dltEntry);764void cleanDLTRecordOnUnload();765DLTTracking *getDLT_HT() const { return _dltHT; }766void setDLT_HT(DLTTracking *dltHT) { _dltHT = dltHT; }767#else768DLTTracking *getDLT_HT() const { return NULL; }769#endif // J9VM_JIT_DYNAMIC_LOOP_TRANSFER770771J9::RWMonitor *getClassUnloadMonitor() { return _classUnloadMonitor; }772773// Synchronize output to the vlog file (or stdout if there is no file)774//775void vlogAcquire();776void vlogRelease();777778// Synchronize output to the rtlog file (or stdout if there is no file)779//780void rtlogAcquire();781void rtlogRelease();782783// Synchronize updates to J9Method objects784//785void acquireCompilationLock();786void releaseCompilationLock();787788TR::Monitor *createLogMonitor();789void acquireLogMonitor();790void releaseLogMonitor();791792int32_t getQueueWeight() const { return _queueWeight; }793void increaseQueueWeightBy(uint8_t w) { _queueWeight += (int32_t)w; }794int32_t decreaseQueueWeightBy(uint8_t w) { TR_ASSERT((int32_t)w <= _queueWeight, "assertion failure"); return _queueWeight -= (int32_t)w; }795int32_t getOverallQueueWeight() const { return _queueWeight; /*+ (_LPQWeight >> 1);*/ } // make secondary queue count only half as much796int32_t getMethodQueueSize() const { return _numQueuedMethods; }797void incrementMethodQueueSize();798int32_t getPeakMethodQueueSize() const { return _maxQueueSize; }799int32_t getNumQueuedFirstTimeCompilations() const { return _numQueuedFirstTimeCompilations; }800void decNumGCRReqestsQueued(TR_MethodToBeCompiled *entry);801void incNumGCRRequestsQueued(TR_MethodToBeCompiled *entry);802int32_t getNumGCRRequestsQueued() const { return _numGCRQueued; }803void decNumInvReqestsQueued(TR_MethodToBeCompiled *entry);804void incNumInvRequestsQueued(TR_MethodToBeCompiled *entry);805void updateCompQueueAccountingOnDequeue(TR_MethodToBeCompiled *entry);806int32_t getNumCompThreadsActive() const { return _numCompThreadsActive; }807void incNumCompThreadsActive() { _numCompThreadsActive++; }808void decNumCompThreadsActive() { _numCompThreadsActive--; }809void setNumCompThreadsActive(int32_t n) { _numCompThreadsActive = n; }810int32_t getNumCompThreadsJobless() const { return _numCompThreadsJobless; }811void incNumCompThreadsJobless() { _numCompThreadsJobless++; }812void decNumCompThreadsJobless() { _numCompThreadsJobless--; }813void setNumCompThreadsJobless(int32_t n) { _numCompThreadsJobless = n; }814int32_t getNumCompThreadsCompilingHotterMethods() const { return _numCompThreadsCompilingHotterMethods; }815void incNumCompThreadsCompilingHotterMethods() { _numCompThreadsCompilingHotterMethods++; }816void decNumCompThreadsCompilingHotterMethods() { _numCompThreadsCompilingHotterMethods--; TR_ASSERT(_numCompThreadsCompilingHotterMethods>=0, "assertion failure");}817void setNumCompThreadsCompilingHotterMethods(int32_t n) { _numCompThreadsCompilingHotterMethods = n; }818int32_t getNumAppThreadsActive() const { return _numAppThreadsActive; }819uint64_t getElapsedTimeNumAppThreadsActiveWasSet() const { return _elapsedTimeNumAppThreadsActiveWasSet; }820void setNumAppThreadsActive(int32_t n, uint64_t t) { _numAppThreadsActive = n; _elapsedTimeNumAppThreadsActiveWasSet = t; }821bool useOptLevelAdjustment();822823824bool getHasResumableTrapHandler() {return _flags.testAny(HasResumableTrapHandler);}825void setHasResumableTrapHandler(bool t=true)826{827if (t)828_flags.set(HasResumableTrapHandler);829else830_flags.reset(HasResumableTrapHandler);831}832833bool getHasFixedFrameC_CallingConvention() {return _flags.testAny(HasFixedFrameC_CallingConvention);}834void setHasFixedFrameC_CallingConvention() { _flags.set(HasFixedFrameC_CallingConvention);}835836uint32_t getNumberBytesReadInaccessible() {return _numberBytesReadInaccessible;}837uint32_t setNumberBytesReadInaccessible(int32_t r) { return (_numberBytesReadInaccessible = r); }838839uint32_t getNumberBytesWriteInaccessible() {return _numberBytesWriteInaccessible;}840uint32_t setNumberBytesWriteInaccessible(int32_t w) { return (_numberBytesWriteInaccessible = w); }841842bool getSupportsScaledIndexAddressing() {return _flags.testAny(SupportsScaledIndexAddressing);}843void setSupportsScaledIndexAddressing() { _flags.set(SupportsScaledIndexAddressing);}844845bool isInZOSSupervisorState() {return _flags.testAny(IsInZOSSupervisorState);}846void setIsInZOSSupervisorState() { _flags.set(IsInZOSSupervisorState);}847848TR_LinkHead0<TR_ClassHolder> *getListOfClassesToCompile() { return &_classesToCompileList; }849int32_t getCompilationLag();850int32_t getCompilationLagUnlocked() { return getCompilationLag(); } // will go away851bool dynamicThreadPriority();852853void updateCompilationErrorStats(TR_CompilationErrorCode errorCode) { statCompErrors.update(errorCode); }854bool SmoothCompilation(TR_MethodToBeCompiled *entry, int32_t *optLevelAdjustment);855bool compBudgetSupport() const {return _compBudgetSupport;}856void setCompBudgetSupport(bool val) {_compBudgetSupport = val;}857int32_t getCompBudget() const;858void setCompBudget(int32_t budget) {_compilationBudget = budget;}859int32_t idleThreshold() const {return _idleThreshold;}860void setIdleThreshold(int32_t threshold) {_idleThreshold = threshold;}861int64_t getCpuTimeSpentInCompilation();862int32_t changeCompThreadPriority(int32_t priority, int32_t locationCode);863TR_MethodToBeCompiled *getFirstDowngradedMethod();864uint64_t getLastReqStartTime() const {return _lastReqStartTime;}865void setLastReqStartTime(uint64_t t) { _lastReqStartTime = t; }866CpuUtilization * getCpuUtil() const { return _cpuUtil;}867void setCpuUtil(CpuUtilization *cpuUtil){ _cpuUtil = cpuUtil; }868UDATA getVMStateOfCrashedThread() { return _vmStateOfCrashedThread; }869void setVMStateOfCrashedThread(UDATA vmState) { _vmStateOfCrashedThread = vmState; }870void printCompQueue();871TR::CompilationInfoPerThread *getCompilationInfoForDiagnosticThread() const { return _compInfoForDiagnosticCompilationThread; }872TR::CompilationInfoPerThread * const *getArrayOfCompilationInfoPerThread() const { return _arrayOfCompilationInfoPerThread; }873uint32_t getAotQueryTime() { return _statTotalAotQueryTime; }874void setAotQueryTime(uint32_t queryTime) { _statTotalAotQueryTime = queryTime; }875uint32_t getAotRelocationTime() { return _statTotalAotRelocationTime; }876void setAotRelocationTime(uint32_t reloTime) { _statTotalAotRelocationTime = reloTime; }877void incrementNumMethodsFoundInSharedCache() { _numMethodsFoundInSharedCache++; }878int32_t numMethodsFoundInSharedCache() { return _numMethodsFoundInSharedCache; }879int32_t getNumInvRequestsInCompQueue() const { return _numInvRequestsInCompQueue; }880J9JITConfig *getJITConfig() { return _jitConfig; }881TR::CompilationInfoPerThread *getCompInfoForThread(J9VMThread *vmThread);882int32_t getNumUsableCompilationThreads() const { return _numCompThreads; }883int32_t getNumTotalCompilationThreads() const { return _numCompThreads + _numDiagnosticThreads; }884TR::CompilationInfoPerThreadBase *getCompInfoWithID(int32_t ID);885TR::Compilation *getCompilationWithID(int32_t ID);886TR::CompilationInfoPerThread *getFirstSuspendedCompilationThread();887bool useMultipleCompilationThreads() { return (getNumUsableCompilationThreads() + _numDiagnosticThreads) > 1; }888bool getRampDownMCT() const { return _rampDownMCT; }889void setRampDownMCT() { _rampDownMCT = true; } // cannot be reset890static void printMethodNameToVlog(J9Method *method);891static void printMethodNameToVlog(const J9ROMClass* romClass, const J9ROMMethod* romMethod);892893void queueForcedAOTUpgrade(TR_MethodToBeCompiled *originalEntry);894895void queueForcedAOTUpgrade(TR_MethodToBeCompiled *originalEntry, uint16_t hints, TR_FrontEnd *fe);896897uint32_t getNumTargetCPUs() const { return _cpuEntitlement.getNumTargetCPUs(); }898899bool isHypervisorPresent() { return _cpuEntitlement.isHypervisorPresent(); }900double getGuestCpuEntitlement() const { return _cpuEntitlement.getGuestCpuEntitlement(); }901void computeAndCacheCpuEntitlement() { _cpuEntitlement.computeAndCacheCpuEntitlement(); }902double getJvmCpuEntitlement() const { return _cpuEntitlement.getJvmCpuEntitlement(); }903904bool importantMethodForStartup(J9Method *method);905bool shouldDowngradeCompReq(TR_MethodToBeCompiled *entry);906907908int32_t computeDynamicDumbInlinerBytecodeSizeCutoff(TR::Options *options);909TR_YesNoMaybe shouldActivateNewCompThread();910#if DEBUG911void debugPrint(char *debugString);912void debugPrint(J9VMThread *, char *);913void debugPrint(char *, intptr_t);914void debugPrint(J9VMThread *, char *, IDATA);915void debugPrint(J9Method*);916void debugPrint(char *, J9Method *);917void debugPrint(J9VMThread *, char *, TR_MethodToBeCompiled *);918void debugPrint(char * debugString, TR::IlGeneratorMethodDetails & details, J9VMThread * vmThread);919void printQueue();920#else // !DEBUG921void debugPrint(char *debugString) {}922void debugPrint(J9VMThread *, char *) {}923void debugPrint(char *, intptr_t) {}924void debugPrint(J9VMThread *, char *, IDATA) {}925void debugPrint(J9Method*) {}926void debugPrint(char *, J9Method *) {}927void debugPrint(J9VMThread *, char *, TR_MethodToBeCompiled *) {}928void debugPrint(char * debugString, TR::IlGeneratorMethodDetails & details, J9VMThread * vmThread) { }929void printQueue() {}930#endif // DEBUG931void debugPrint(TR_OpaqueMethodBlock *omb){ debugPrint((J9Method*)omb); }932933enum {SMALL_LAG=1, MEDIUM_LAG, LARGE_LAG};934bool methodCanBeCompiled(TR_FrontEnd *, TR_ResolvedMethod *compilee, TR_FilterBST *&filter);935936void setAllCompilationsShouldBeInterrupted();937938int32_t getIprofilerMaxCount() const { return _iprofilerMaxCount; }939void setIprofilerMaxCount(int32_t n) { _iprofilerMaxCount = n; }940941TR_SharedCacheRelocationRuntime *reloRuntime() { return &_sharedCacheReloRuntime; }942943int32_t incNumSeriousFailures() { return ++_numSeriousFailures; } // no atomicity guarantees for the increment944945TR_SamplerStates getSamplerState() const { return _samplerState; }946void setSamplerState(TR_SamplerStates s) { _prevSamplerState = _samplerState; _samplerState = s; }947TR_SamplerStates getPrevSamplerState() const { return _prevSamplerState; }948949950J9VMThread *getSamplerThread() const { return _samplerThread; }951void setSamplerThread(J9VMThread *thr) { _samplerThread = thr; }952// use jitConfig->samplerMonitor for the following two routines953TR_SamplingThreadLifetimeStates getSamplingThreadLifetimeState() const { return _samplingThreadLifetimeState; }954void setSamplingThreadLifetimeState(TR_SamplingThreadLifetimeStates s) { _samplingThreadLifetimeState = s; }955int32_t getSamplingThreadWaitTimeInDeepIdleToNotifyVM() const { return _samplingThreadWaitTimeInDeepIdleToNotifyVM; }956void setSamplingThreadWaitTimeInDeepIdleToNotifyVM()957{958int32_t minIdleWaitTimeToNotifyVM = _jitConfig->javaVM->internalVMFunctions->getVMMinIdleWaitTime(_jitConfig->javaVM);959960if (minIdleWaitTimeToNotifyVM == 0)961_samplingThreadWaitTimeInDeepIdleToNotifyVM = -1;962else963{964if (minIdleWaitTimeToNotifyVM <= TR::Options::_waitTimeToEnterDeepIdleMode)965_samplingThreadWaitTimeInDeepIdleToNotifyVM = 0;966else967_samplingThreadWaitTimeInDeepIdleToNotifyVM = minIdleWaitTimeToNotifyVM - TR::Options::_waitTimeToEnterDeepIdleMode;968}969}970971TR::CompilationInfoPerThread * findFirstLowPriorityCompilationInProgress(CompilationPriority priority); // needs compilationQueueMonitor in hand972973TR_YesNoMaybe isWarmSCC() const { return _warmSCC; }974void setIsWarmSCC(TR_YesNoMaybe param) { _warmSCC = param; }975#if defined(J9VM_OPT_SHARED_CLASSES)976J9SharedClassJavacoreDataDescriptor* getAddrOfJavacoreData() { return &_javacoreData; }977#endif978TR::Monitor *getIProfilerBufferArrivalMonitor() const { return _iprofilerBufferArrivalMonitor; }979980TR_HWProfiler *getHWProfiler() const;981982TR_JProfilerThread *getJProfilerThread() const;983984int32_t calculateCodeSize(TR_MethodMetaData *metaData);985void increaseUnstoredBytes(U_32 aotBytes, U_32 jitBytes);986987/**988* @brief Compute free physical memory taking into account container limits989*990* @param incompleteInfo [OUTPUT] Boolean indicating that cached/buffered memory couldn't be read991* @return A value representing the free physicalMemory992or OMRPORT_MEMINFO_NOT_AVAILABLE in case of error993*/994uint64_t computeFreePhysicalMemory(bool &incompleteInfo);995996/**997* @brief Compute free physical memory taking into account container limits and caches it for later use998*999* To limit overhead, this function caches the computed value and1000* only refreshes it if more than "updatePeriodMs" have passed since the last update1001* If updatePeriodMs==-1, then updatePeriodMs uses a default value of 500 ms1002*1003* @param incompleteInfo [OUTPUT] Boolean indicating that cached/buffered memory couldn't be read1004* @param updatePeriodMs Indicates how often the cached values are refreshed1005* @return A value representing the free physicalMemory1006or OMRPORT_MEMINFO_NOT_AVAILABLE in case of error1007*/1008uint64_t computeAndCacheFreePhysicalMemory(bool &incompleteInfo, int64_t updatePeriodMs=-1);1009uint64_t computeFreePhysicalLimitAndAbortCompilationIfLow(TR::Compilation *comp, bool &incompleteInfo, size_t sizeToAllocate);10101011TR_LowPriorityCompQueue &getLowPriorityCompQueue() { return _lowPriorityCompilationScheduler; }1012bool canProcessLowPriorityRequest();1013TR_CompilationErrorCode scheduleLPQAndBumpCount(TR::IlGeneratorMethodDetails &details, TR_J9VMBase *fe);10141015TR_JProfilingQueue &getJProfilingCompQueue() { return _JProfilingQueue; }10161017TR_JitSampleInfo &getJitSampleInfoRef() { return _jitSampleInfo; }1018TR_InterpreterSamplingTracking *getInterpSamplTrackingInfo() const { return _interpSamplTrackingInfo; }10191020int32_t getAppSleepNano() const { return _appSleepNano; }1021void setAppSleepNano(int32_t t) { _appSleepNano = t; }1022int32_t computeAppSleepNano() const;1023TR_YesNoMaybe detectCompThreadStarvation();1024bool getStarvationDetected() const { return _starvationDetected; }1025void setStarvationDetected(bool b) { _starvationDetected = b; }1026int32_t getTotalCompThreadCpuUtilWhenStarvationComputed() const { return _totalCompThreadCpuUtilWhenStarvationComputed; }1027int32_t getNumActiveCompThreadsWhenStarvationComputed() const { return _numActiveCompThreadsWhenStarvationComputed; }1028bool canProcessJProfilingRequest();1029bool getSuspendThreadDueToLowPhysicalMemory() const { return _suspendThreadDueToLowPhysicalMemory; }1030void setSuspendThreadDueToLowPhysicalMemory(bool b) { _suspendThreadDueToLowPhysicalMemory = b; }10311032#if defined(J9VM_OPT_JITSERVER)1033ClientSessionHT *getClientSessionHT() const { return _clientSessionHT; }1034void setClientSessionHT(ClientSessionHT *ht) { _clientSessionHT = ht; }10351036PersistentVector<TR_OpaqueClassBlock*> *getUnloadedClassesTempList() const { return _unloadedClassesTempList; }1037void setUnloadedClassesTempList(PersistentVector<TR_OpaqueClassBlock*> *it) { _unloadedClassesTempList = it; }1038PersistentVector<TR_OpaqueClassBlock*> *getIllegalFinalFieldModificationList() const { return _illegalFinalFieldModificationList; }1039void setIllegalFinalFieldModificationList(PersistentVector<TR_OpaqueClassBlock*> *it) { _illegalFinalFieldModificationList = it; }1040PersistentUnorderedMap<TR_OpaqueClassBlock*, uint8_t> *getNewlyExtendedClasses() const { return _newlyExtendedClasses; }1041void classGotNewlyExtended(TR_OpaqueClassBlock* clazz)1042{1043auto &newlyExtendedClasses = *getNewlyExtendedClasses();1044uint8_t inProgress = getCHTableUpdateDone();1045if (inProgress)1046newlyExtendedClasses[clazz] |= inProgress;1047}1048void setNewlyExtendedClasses(PersistentUnorderedMap<TR_OpaqueClassBlock*, uint8_t> *it) { _newlyExtendedClasses = it; }10491050TR::Monitor *getclassesCachedAtServerMonitor() const { return _classesCachedAtServerMonitor; }1051TR::Monitor *getSequencingMonitor() const { return _sequencingMonitor; }1052uint32_t getCompReqSeqNo() const { return _compReqSeqNo; }1053uint32_t incCompReqSeqNo() { return ++_compReqSeqNo; }1054uint32_t getLastCriticalSeqNo() const { return _lastCriticalCompReqSeqNo; }1055void setLastCriticalSeqNo(uint32_t seqNo) { _lastCriticalCompReqSeqNo = seqNo; }10561057void markCHTableUpdateDone(int32_t threadId) { _chTableUpdateFlags |= (1 << threadId); }1058void resetCHTableUpdateDone(int32_t threadId) { _chTableUpdateFlags &= ~(1 << threadId); }1059uint8_t getCHTableUpdateDone() const { return _chTableUpdateFlags; }10601061const PersistentVector<std::string> &getJITServerSslKeys() const { return _sslKeys; }1062PersistentUnorderedSet<J9Class*> & getclassesCachedAtServer() { return _classesCachedAtServer; }1063void addJITServerSslKey(const std::string &key) { _sslKeys.push_back(key); }1064const PersistentVector<std::string> &getJITServerSslCerts() const { return _sslCerts; }1065void addJITServerSslCert(const std::string &cert) { _sslCerts.push_back(cert); }1066const std::string &getJITServerSslRootCerts() const { return _sslRootCerts; }1067void setJITServerSslRootCerts(const std::string &cert) { _sslRootCerts = cert; }10681069void setCompThreadActivationPolicy(JITServer::CompThreadActivationPolicy newPolicy) { _activationPolicy = newPolicy; }1070JITServer::CompThreadActivationPolicy getCompThreadActivationPolicy() const { return _activationPolicy; }1071uint64_t getCachedFreePhysicalMemoryB() const { return _cachedFreePhysicalMemoryB; }10721073JITServerSharedROMClassCache *getJITServerSharedROMClassCache() const { return _sharedROMClassCache; }1074void setJITServerSharedROMClassCache(JITServerSharedROMClassCache *cache) { _sharedROMClassCache = cache; }10751076JITServerAOTCacheMap *getJITServerAOTCacheMap() const { return _JITServerAOTCacheMap; }1077void setJITServerAOTCacheMap(JITServerAOTCacheMap *map) { _JITServerAOTCacheMap = map; }10781079JITServerAOTDeserializer *getJITServerAOTDeserializer() const { return _JITServerAOTDeserializer; }1080void setJITServerAOTDeserializer(JITServerAOTDeserializer *deserializer) { _JITServerAOTDeserializer = deserializer; }1081#endif /* defined(J9VM_OPT_JITSERVER) */10821083static void replenishInvocationCount(J9Method* method, TR::Compilation* comp);10841085static void addJ9HookVMDynamicCodeLoadForAOT(J9VMThread * vmThread, J9Method * method, J9JITConfig *jitConfig, TR_MethodMetaData* relocatedMetaData);10861087#if defined(J9VM_INTERP_AOT_COMPILE_SUPPORT) && defined(J9VM_OPT_SHARED_CLASSES) && (defined(TR_HOST_X86) || defined(TR_HOST_POWER) || defined(TR_HOST_S390) || defined(TR_HOST_ARM) || defined(TR_HOST_ARM64))1088static void storeAOTInSharedCache(J9VMThread *vmThread, J9ROMMethod *romMethod, const U_8 *dataStart, UDATA dataSize, const U_8 *codeStart, UDATA codeSize, TR::Compilation *comp, J9JITConfig *jitConfig, TR_MethodToBeCompiled *entry);1089#endif10901091static int32_t VERY_SMALL_QUEUE;1092static int32_t SMALL_QUEUE;1093static int32_t MEDIUM_LARGE_QUEUE;1094static int32_t LARGE_QUEUE;1095static int32_t VERY_LARGE_QUEUE;10961097struct CompilationStatistics _stats;1098struct CompilationStatsPerInterval _intervalStats;1099TR_PersistentArray<TR_SignatureCountPair *> *_persistedMethods;11001101// Must be less than 16 at the JITClient or non-JITServer mode because1102// in some parts of the code (CHTable) we keep flags on a 2-byte variable.1103static const uint32_t MAX_CLIENT_USABLE_COMP_THREADS = 15; // For JITClient and non-JITServer mode1104static const uint32_t DEFAULT_CLIENT_USABLE_COMP_THREADS = 7; // For JITClient and non-JITServer mode1105#if defined(J9VM_OPT_JITSERVER)1106static const uint32_t MAX_SERVER_USABLE_COMP_THREADS = 999; // JITServer1107static const uint32_t DEFAULT_SERVER_USABLE_COMP_THREADS = 63; // JITServer1108#endif /* defined(J9VM_OPT_JITSERVER) */1109static const uint32_t MAX_DIAGNOSTIC_COMP_THREADS = 1;11101111private:11121113enum1114{1115JITA2N_EXTENDED_DATA_EYE_CATCHER = 0xCCCCCCCC,1116JITA2N_EXTENDED_DATA_LINENUM = 0xBEEFCAFE, // Picked early and used... so we'll leave it1117JITA2N_EXTENDED_DATA_CALLSITES = 0xCAFE0002,1118JITA2N_EXTENDED_DATA_INLINETABLE = 0xCAFE0003,1119JITA2N_EXTENDED_DATA_COMPILATION_DESC = 0xCAFE00041120};11211122/**1123* @brief getCompilationQueueEntry gets a TR_MethodToBeCompiled for use in queuing compilations1124* @return Returns an unused queue entry if available, or NULL otherwise.1125*/1126TR_MethodToBeCompiled * getCompilationQueueEntry();11271128J9Method *getRamMethod(TR_FrontEnd *vm, char *className, char *methodName, char *signature);1129//char *buildMethodString(TR_ResolvedMethod *method);11301131static const size_t DLT_HASHSIZE = 123;11321133static TR::CompilationInfo * _compilationRuntime;11341135static int32_t *_compThreadActivationThresholds;1136static int32_t *_compThreadSuspensionThresholds;1137static int32_t *_compThreadActivationThresholdsonStarvation;11381139TR::CompilationInfoPerThread **_arrayOfCompilationInfoPerThread; // First NULL entry means end of the array1140TR::CompilationInfoPerThread *_compInfoForDiagnosticCompilationThread; // compinfo for dump compilation thread1141TR_MethodToBeCompiled *_methodQueue;1142TR_MethodToBeCompiled *_methodPool;1143int32_t _methodPoolSize; // shouldn't this and _methodPool be static?11441145J9JITConfig *_jitConfig;1146TR_PersistentMemory *_persistentMemory; // memorize the persistentMemory1147TR::Monitor *_compilationMonitor;1148J9::RWMonitor *_classUnloadMonitor;1149TR::Monitor *_logMonitor; // only used if multiple compilation threads1150TR::Monitor *_schedulingMonitor;1151#if defined(J9VM_JIT_DYNAMIC_LOOP_TRANSFER)1152TR::Monitor *_dltMonitor;1153struct DLT_record *_freeDLTRecord;1154struct DLT_record *_dltHash[DLT_HASHSIZE];1155#endif1156DLTTracking *_dltHT;11571158TR::Monitor *_vlogMonitor;1159TR::Monitor *_rtlogMonitor;1160TR::Monitor *_iprofilerBufferArrivalMonitor;1161TR::MonitorTable *_j9MonitorTable; // used only for RAS (debuggerExtensions); no accessor; use TR_J9MonitorTable::get() everywhere else1162TR_LinkHead0<TR_ClassHolder> _classesToCompileList; // used by compileClasses; adjusted by unload hooks1163intptr_t _numSyncCompilations;1164intptr_t _numAsyncCompilations;1165int32_t _numCompThreadsActive;1166int32_t _numCompThreadsJobless; // threads are not suspended, but have no work to do1167int32_t _numCompThreadsCompilingHotterMethods; // allow only one at a time; use compQmonitor to change1168int32_t _numAppThreadsActive; // updated by sampling thread once in a while1169uint64_t _elapsedTimeNumAppThreadsActiveWasSet; // ms; maintained by sampling thread1170int32_t _numQueuedMethods;1171int32_t _maxQueueSize;1172int32_t _numQueuedFirstTimeCompilations; // these have oldStartPC==01173int32_t _queueWeight; // approximation on overhead to process the entire queue1174CpuUtilization* _cpuUtil; // object to compute cpu utilization1175int32_t _overallCompCpuUtilization; // In percentage points. Valid only if TR::Options::_compThreadCPUEntitlement has a positive value1176int32_t _idleThreshold; // % of entire machine CPU1177int32_t _compilationBudget;1178TR_YesNoMaybe _warmSCC; // shared class cache has methods, so this could be second run1179bool _compBudgetSupport;1180bool _rampDownMCT; // flag that from now on we should not activate more than one compilation thread1181// Once set, the flag is never reset1182TR_YesNoMaybe _exceedsCompCpuEntitlement;1183J9VMThread *_samplerThread; // The Os thread for this VM attached thread is stored at jitConfig->samplerThread1184TR_SamplerStates _samplerState; // access is guarded by J9JavaVM->vmThreadListMutex1185TR_SamplerStates _prevSamplerState; // previous state of the sampler thread1186volatile TR_SamplingThreadLifetimeStates _samplingThreadLifetimeState; // access guarded by jitConfig->samplerMonitor (most of the time)1187int32_t _samplingThreadWaitTimeInDeepIdleToNotifyVM;1188int32_t _numMethodsFoundInSharedCache;1189int32_t _numInvRequestsInCompQueue; // number of invalidation requests present in the compilation queue1190uint64_t _lastReqStartTime; // time (ms) when processing the last request started1191uint64_t _lastCompilationsShouldBeInterruptedTime; // RAS1192// statistics1193int32_t _statsOptLevels[numHotnessLevels]; // will be zeroed with memset1194#if defined(J9VM_OPT_JITSERVER)1195int32_t _statsRemoteOptLevels[numHotnessLevels];1196#endif /* defined(J9VM_OPT_JITSERVER) */1197uint32_t _statNumAotedMethods;1198uint32_t _statNumMethodsFromSharedCache; // methods whose body was taken from shared cache1199uint32_t _statNumAotedMethodsRecompiled;1200uint32_t _statNumForcedAotUpgrades;1201uint32_t _statNumJNIMethodsCompiled;1202TR_StatsEvents<compilationMaxError> statCompErrors;1203uint32_t _statNumPriorityChanges; // statistics1204uint32_t _statNumYields;1205uint32_t _statNumUpgradeInterpretedMethod;1206uint32_t _statNumDowngradeInterpretedMethod;1207uint32_t _statNumUpgradeJittedMethod;1208uint32_t _statNumQueuePromotions;1209uint32_t _statNumGCRInducedCompilations;1210uint32_t _statNumSamplingJProfilingBodies;1211uint32_t _statNumJProfilingBodies;1212uint32_t _statNumRecompilationForBodiesWithJProfiling;1213uint32_t _statNumMethodsFromJProfilingQueue;1214uint32_t _statTotalAotQueryTime;1215uint32_t _statTotalAotRelocationTime;12161217uint32_t _numberBytesReadInaccessible;1218uint32_t _numberBytesWriteInaccessible;1219flags32_t _flags;1220int32_t _numSeriousFailures; // count failures where method needs to continue interpreted12211222TR::Monitor *_gpuInitMonitor;12231224enum // flags1225{1226// = 0x00000001, // AVAILABLE FOR USE !!1227HasResumableTrapHandler = 0x00000002,1228HasFixedFrameC_CallingConvention = 0x00000004,1229SupportsScaledIndexAddressing = 0x00000080,1230S390SupportsDFP = 0x00000100,1231S390SupportsFPE = 0x00000200,1232IsInZOSSupervisorState = 0x00008000,1233S390SupportsTM = 0x00010000,1234S390SupportsRI = 0x00020000,1235S390SupportsVectorFacility = 0x00040000,1236DummyLastFlag1237};12381239#ifdef DEBUG1240bool _traceCompiling;1241#endif1242int32_t _numCompThreads; // Number of usable compilation threads that does not include the diagnostic thread1243int32_t _numDiagnosticThreads;1244int32_t _iprofilerMaxCount;1245int32_t _numGCRQueued; // how many GCR requests are in the queue1246// We should disable GCR counting if too many1247// GCR requests because GCR counting has a large1248// negative effect on performance1249//----------------1250int32_t _appSleepNano; // make app threads sleep when sampling12511252bool _starvationDetected;1253int32_t _totalCompThreadCpuUtilWhenStarvationComputed; // for RAS purposes1254int32_t _numActiveCompThreadsWhenStarvationComputed; // for RAS purposes1255//--------------1256TR_LowPriorityCompQueue _lowPriorityCompilationScheduler;1257TR_JProfilingQueue _JProfilingQueue;12581259TR_CpuEntitlement _cpuEntitlement;1260TR_JitSampleInfo _jitSampleInfo;1261TR_SharedCacheRelocationRuntime _sharedCacheReloRuntime;1262uintptr_t _vmStateOfCrashedThread; // Set by Jit Dump; used by diagnostic thread1263#if defined(J9VM_OPT_SHARED_CLASSES)1264J9SharedClassJavacoreDataDescriptor _javacoreData;1265#endif1266uint64_t _cachedFreePhysicalMemoryB;1267bool _cachedIncompleteFreePhysicalMemory;1268bool _cgroupMemorySubsystemEnabled; // true when running in container and the memory subsystem is enabled1269// The following flag is set when the JIT is not allowed to allocate1270// a scratch segment due to low physical memory.1271// It is reset when a compilation thread is suspended, thus possibly1272// freeing scratch segments it holds to1273bool _suspendThreadDueToLowPhysicalMemory;1274TR_InterpreterSamplingTracking *_interpSamplTrackingInfo;12751276#if defined(J9VM_OPT_JITSERVER)1277ClientSessionHT *_clientSessionHT; // JITServer hashtable that holds session information about JITClients1278PersistentUnorderedSet<J9Class*> _classesCachedAtServer;1279TR::Monitor *_classesCachedAtServerMonitor;1280PersistentVector<TR_OpaqueClassBlock*> *_unloadedClassesTempList; // JITServer list of classes unloaded1281PersistentVector<TR_OpaqueClassBlock*> *_illegalFinalFieldModificationList; // JITServer list of classes that have J9ClassHasIllegalFinalFieldModifications is set1282TR::Monitor *_sequencingMonitor; // Used for ordering outgoing messages at the client1283uint32_t _compReqSeqNo; // seqNo for outgoing messages at the client1284uint32_t _lastCriticalCompReqSeqNo; // seqNo for last request that carried information that needs to be processed in order1285PersistentUnorderedMap<TR_OpaqueClassBlock*, uint8_t> *_newlyExtendedClasses; // JITServer table of newly extended classes1286uint8_t _chTableUpdateFlags;1287uint32_t _localGCCounter; // Number of local gc cycles done1288std::string _sslRootCerts;1289PersistentVector<std::string> _sslKeys;1290PersistentVector<std::string> _sslCerts;1291JITServer::CompThreadActivationPolicy _activationPolicy;1292JITServerSharedROMClassCache *_sharedROMClassCache;1293JITServerAOTCacheMap *_JITServerAOTCacheMap;1294JITServerAOTDeserializer *_JITServerAOTDeserializer;1295#endif /* defined(J9VM_OPT_JITSERVER) */1296}; // CompilationInfo1297}129812991300#endif // COMPILATIONRUNTIME_HPP1301130213031304