Path: blob/master/runtime/compiler/control/rossa.cpp
6000 views
/*******************************************************************************1* Copyright (c) 2000, 2022 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 <stdio.h>23#include <stdlib.h>24#include <string.h>2526#ifdef WINDOWS27// Undefine the winsockapi because winsock2 defines it. Removes warnings.28#if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)29#undef _WINSOCKAPI_30#endif31#include <winsock2.h>32#include <process.h>33#else34#include <sys/types.h>35#include <sys/socket.h>36#include <netinet/in.h>37#include <netdb.h>38#include <unistd.h>39#include <pthread.h>40#ifdef J9ZOS39041#include <arpa/inet.h>42#endif43#endif44#ifdef J9ZTPF45#include <tpf/c_eb0eb.h>46#include <tpf/sysapi.h>47#include <tpf/tpfapi.h>48#include <tpf/c_cinfc.h>49#endif5051#include "env/annotations/AnnotationBase.hpp"5253#define J9_EXTERNAL_TO_VM54#include "codegen/PrivateLinkage.hpp"55#include "control/CompilationRuntime.hpp"56#include "control/CompilationThread.hpp"57#include "control/JitDump.hpp"58#include "control/Recompilation.hpp"59#include "control/RecompilationInfo.hpp"60#include "runtime/ArtifactManager.hpp"61#include "runtime/CodeCache.hpp"62#include "runtime/CodeCacheManager.hpp"63#include "runtime/CodeCacheReclamation.h"64#include "runtime/codertinit.hpp"65#include "runtime/IProfiler.hpp"66#include "runtime/HWProfiler.hpp"67#include "runtime/RelocationRuntime.hpp"68#include "env/PersistentInfo.hpp"69#include "env/ClassLoaderTable.hpp"70#include "env/J2IThunk.hpp"71#include "env/PersistentCHTable.hpp"72#include "env/CompilerEnv.hpp"73#include "env/jittypes.h"74#include "env/ClassTableCriticalSection.hpp"75#include "env/VerboseLog.hpp"7677#include "ilgen/IlGeneratorMethodDetails_inlines.hpp"7879/* Hardware Profiling */80#if defined(TR_HOST_S390) && defined(BUILD_Z_RUNTIME_INSTRUMENTATION)81#include "z/runtime/ZHWProfiler.hpp"82#elif defined(TR_HOST_POWER)83#include "p/runtime/PPCHWProfiler.hpp"84#endif8586#include "control/rossa.h"87#include "control/OptimizationPlan.hpp"88#include "control/CompilationController.hpp"89#include "runtime/IProfiler.hpp"9091#define _UTE_STATIC_92#include "env/ut_j9jit.h"9394#include "jitprotos.h"95#if defined(J9VM_OPT_SHARED_CLASSES)96#include "j9jitnls.h"97#endif98#include "env/J9SharedCache.hpp"99100#ifdef J9VM_OPT_JAVA_CRYPTO_ACCELERATION101#include "runtime/Crypto.hpp"102#endif103104#include "infra/Monitor.hpp"105106#include "j9.h"107#include "j9cfg.h"108#include "vmaccess.h"109#include "jvminit.h"110#include "j9port.h"111#include "env/exports.h"112#if defined(J9VM_OPT_JITSERVER)113#include "env/JITServerPersistentCHTable.hpp"114#include "net/CommunicationStream.hpp"115#include "net/ClientStream.hpp"116#include "net/LoadSSLLibs.hpp"117#include "runtime/JITClientSession.hpp"118#include "runtime/JITServerAOTCache.hpp"119#include "runtime/JITServerAOTDeserializer.hpp"120#include "runtime/JITServerIProfiler.hpp"121#include "runtime/JITServerSharedROMClassCache.hpp"122#include "runtime/JITServerStatisticsThread.hpp"123#include "runtime/Listener.hpp"124#endif /* defined(J9VM_OPT_JITSERVER) */125126extern "C" int32_t encodeCount(int32_t count);127128extern "C" {129struct J9RASdumpContext;130}131132#if defined(TR_TARGET_X86) && defined(TR_HOST_32BIT)133extern TR_X86CPUIDBuffer *queryX86TargetCPUID(void * javaVM);134#endif135136extern void setupCodeCacheParameters(int32_t *, OMR::CodeCacheCodeGenCallbacks *callBacks, int32_t *numHelpers, int32_t *CCPreLoadedCodeSize);137extern "C" void stopInterpreterProfiling(J9JITConfig *jitConfig);138extern "C" void restartInterpreterProfiling();139140#ifdef J9VM_JIT_RUNTIME_INSTRUMENTATION141// extern until these functions are added to oti/jitprotos.h142extern "C" UDATA initializeJITRuntimeInstrumentation(J9JavaVM *vm);143#endif144145extern void *ppcPicTrampInit(TR_FrontEnd *, TR::PersistentInfo *);146extern TR_Debug *createDebugObject(TR::Compilation *);147148149bool isQuickstart = false;150151#define TRANSLATE_METHODHANDLE_TAKES_FLAGS152153TR::Monitor *vpMonitor = 0;154155156char *compilationErrorNames[]={157"compilationOK", // 0158"compilationFailure", // 1159"compilationRestrictionILNodes", // 2160"compilationRestrictionRecDepth", // 3161"compilationRestrictedMethod", // 4162"compilationExcessiveComplexity", // 5163"compilationNotNeeded", // 6164"compilationSuspended", // 7165"compilationExcessiveSize", // 8166"compilationInterrupted", // 9167"compilationMetaDataFailure", //10168"compilationInProgress", //11169"compilationCHTableCommitFailure",//12170"compilationMaxCallerIndexExceeded",//13171"compilationKilledByClassReplacement",//14172"compilationHeapLimitExceeded", //15173"compilationNeededAtHigherLevel", //16174"compilationAotValidateFieldFailure", //17175"compilationAotStaticFieldReloFailure", //18176"compilationAotClassReloFailure", //19177"compilationAotThunkReloFailure", //20178"compilationAotTrampolineReloFailure", //21179"compilationAotPicTrampolineReloFailure", //22180"compilationAotCacheFullReloFailure", //23181"compilationAotUnknownReloTypeFailure", //24182"compilationCodeReservationFailure", //25183"compilationAotHasInvokehandle", //26184"compilationTrampolineFailure", //27185"compilationRecoverableTrampolineFailure", // 28186"compilationIlGenFailure", // 29187"compilationIllegalCodeCacheSwitch", // 30188"compilationNullSubstituteCodeCache", // 31189"compilationCodeMemoryExhausted", // 32190"compilationGCRPatchFailure", // 33191"compilationAotValidateMethodExitFailure", // 34192"compilationAotValidateMethodEnterFailure", // 35193"compilationAotArrayClassReloFailure", // 36194"compilationLambdaEnforceScorching", // 37195"compilationInternalPointerExceedLimit", // 38196"compilationAotRelocationInterrupted", // 39197"compilationAotClassChainPersistenceFailure", // 40198"compilationLowPhysicalMemory", // 41199"compilationDataCacheError", // 42200"compilationCodeCacheError", // 43201"compilationRecoverableCodeCacheError", // 44202"compilationAotHasInvokeVarHandle", //45203"compilationAotValidateStringCompressionFailure", // 46204"compilationFSDHasInvokeHandle", //47205"compilationVirtualAddressExhaustion", //48206"compilationEnforceProfiling", //49207"compilationSymbolValidationManagerFailure", //50208"compilationAOTNoSupportForAOTFailure", //51209"compilationAOTValidateTMFailure", //52210"compilationILGenUnsupportedValueTypeOperationFailure", //53211"compilationAOTRelocationRecordGenerationFailure", //54212"compilationAotPatchedCPConstant", //55213"compilationAotHasInvokeSpecialInterface", //56214"compilationAotValidateExceptionHookFailure", //57215"compilationAotBlockFrequencyReloFailure", //58216"compilationAotRecompQueuedFlagReloFailure", //59217"compilationAOTValidateOSRFailure", //60218#if defined(J9VM_OPT_JITSERVER)219"compilationStreamFailure", // compilationFirstJITServerFailure = 61220"compilationStreamLostMessage", // 62221"compilationStreamMessageTypeMismatch", // 63222"compilationStreamVersionIncompatible", // 64223"compilationStreamInterrupted", // 65224"aotCacheDeserializationFailure", // 66225#endif /* defined(J9VM_OPT_JITSERVER) */226"compilationMaxError",227};228229int32_t aggressiveOption = 0;230231232// Tells the sampler thread whether it is being interrupted to resume it or to233// shut it down.234//235volatile bool shutdownSamplerThread = false; // only set once236237238extern "C" void *compileMethodHandleThunk(j9object_t methodHandle, j9object_t arg, J9VMThread *vmThread, U_32 flags);239extern "C" J9NameAndSignature newInstancePrototypeNameAndSig;240241extern "C" void getOutOfIdleStates(TR::CompilationInfo::TR_SamplerStates expectedState, TR::CompilationInfo *compInfo, const char* reason);242243244extern "C" IDATA245launchGPU(J9VMThread *vmThread, jobject invokeObject,246J9Method *method, int deviceId,247I_32 gridDimX, I_32 gridDimY, I_32 gridDimZ,248I_32 blockDimX, I_32 blockDimY, I_32 blockDimZ,249void **args);250251extern "C" void promoteGPUCompile(J9VMThread *vmThread);252253extern "C" int32_t setUpHooks(J9JavaVM * javaVM, J9JITConfig * jitConfig, TR_FrontEnd * vm);254extern "C" int32_t startJITServer(J9JITConfig *jitConfig);255extern "C" int32_t waitJITServerTermination(J9JITConfig *jitConfig);256257char *AOTcgDiagOn="1";258259260261// -----------------------------------------------------------------------------262// Method translation263// -----------------------------------------------------------------------------264265extern "C" IDATA j9jit_testarossa(struct J9JITConfig * jitConfig, J9VMThread * vmThread, J9Method * method, void * oldStartPC)266{267return j9jit_testarossa_err(jitConfig, vmThread, method, oldStartPC, NULL);268}269270271extern "C" IDATA272j9jit_testarossa_err(273struct J9JITConfig *jitConfig,274J9VMThread *vmThread,275J9Method *method,276void *oldStartPC,277TR_CompilationErrorCode *compErrCode)278{279// The method is called by the interpreter when a method's invocation count has reached zero.280// Rather than just compiling blindly, pass the controller an event, and let it decide what to do.281//282bool queued = false;283TR_YesNoMaybe async = TR_maybe;284TR_MethodEvent event;285if (oldStartPC)286{287// any recompilation attempt using fixUpMethodCode would go here288J9::PrivateLinkage::LinkageInfo *linkageInfo = J9::PrivateLinkage::LinkageInfo::get(oldStartPC);289TR_PersistentJittedBodyInfo* jbi = TR::Recompilation::getJittedBodyInfoFromPC(oldStartPC);290291if (!jbi)292{293return 0;294}295296TR_PersistentMethodInfo *pmi = jbi->getMethodInfo();297298if (pmi && pmi->hasBeenReplaced()) // HCR299{300// Obsolete method bodies are invalid.301//302TR::Recompilation::fixUpMethodCode(oldStartPC);303jbi->setIsInvalidated();304}305306if (jbi->getIsInvalidated())307{308event._eventType = TR_MethodEvent::MethodBodyInvalidated;309async = TR_no;310}311else312{313// Async compilation is disabled or recompilations triggered from jitted code314//315// Check if the method has already been scheduled for compilation and return316// abruptly if so. This will reduce contention on the optimizationPlanMonitor317// when a profiled compilation is followed by a very slow recompilation318// (until the recompilation is over, the java threads will try to trigger319// recompilations again and again. See defect 193193)320//321if (linkageInfo->isBeingCompiled())322{323TR_J9VMBase *fe = TR_J9VMBase::get(jitConfig, vmThread);324if (fe->isAsyncCompilation())325return 0; // early return because the method is queued for compilation326}327// If PersistentJittedBody contains the profile Info and has BlockFrequencyInfo, it will set the328// isQueuedForRecompilation field which can be used by the jitted code at runtime to skip the profiling329// code if it has made request to recompile this method.330if (jbi->getProfileInfo() != NULL && jbi->getProfileInfo()->getBlockFrequencyInfo() != NULL)331jbi->getProfileInfo()->getBlockFrequencyInfo()->setIsQueuedForRecompilation();332333event._eventType = TR_MethodEvent::OtherRecompilationTrigger;334}335}336else337{338event._eventType = TR_MethodEvent::InterpreterCounterTripped;339// Experimental code: user may want to artificially delay the compilation340// of methods to gather more IProfiler info341TR::CompilationInfo * compInfo = getCompilationInfo(jitConfig);342if (TR::Options::_compilationDelayTime > 0)343{344if (!TR::CompilationInfo::isJNINative(method))345{346if (compInfo->getPersistentInfo()->getElapsedTime() < 1000 * TR::Options::_compilationDelayTime)347{348// Add 2 to the invocationCount349int32_t count = TR::CompilationInfo::getInvocationCount(method);350if (count >= 0)351{352TR::CompilationInfo::setInvocationCount(method, 2);353return 0;354}355}356}357}358#if defined(J9VM_OPT_JITSERVER)359// Do not allow local compilations in JITServer server mode360if (compInfo->getPersistentInfo()->getRemoteCompilationMode() == JITServer::SERVER)361return 0;362#endif363}364365event._j9method = method;366event._oldStartPC = oldStartPC;367event._vmThread = vmThread;368event._classNeedingThunk = 0;369bool newPlanCreated;370IDATA result = 0;371TR_OptimizationPlan *plan = TR::CompilationController::getCompilationStrategy()->processEvent(&event, &newPlanCreated);372373// if the controller decides to compile this method, trigger the compilation374if (plan)375{376TR::CompilationInfo * compInfo = getCompilationInfo(jitConfig);377378// Check to see if we need to wake up the sampling thread should it be in DEEPIDLE state379if (compInfo->getSamplerState() == TR::CompilationInfo::SAMPLER_DEEPIDLE &&380compInfo->_intervalStats._numFirstTimeCompilationsInInterval >= 1)381getOutOfIdleStates(TR::CompilationInfo::SAMPLER_DEEPIDLE, compInfo, "comp req");382else if (compInfo->getSamplerState() == TR::CompilationInfo::SAMPLER_IDLE &&383compInfo->_intervalStats._numFirstTimeCompilationsInInterval >= TR::Options::_numFirstTimeCompilationsToExitIdleMode)384getOutOfIdleStates(TR::CompilationInfo::SAMPLER_IDLE, compInfo, "comp req");385386{ // scope for details387TR::IlGeneratorMethodDetails details(method);388result = (IDATA)compInfo->compileMethod(vmThread, details, oldStartPC, async, compErrCode, &queued, plan);389}390391if (!queued && newPlanCreated)392TR_OptimizationPlan::freeOptimizationPlan(plan);393}394else // OOM; Very rare case395{396// Invalidation requests MUST not be ignored even if OOM397if (event._eventType == TR_MethodEvent::MethodBodyInvalidated)398{399// Allocate a plan on the stack and force a synchronous compilation400// so that we wait until the compilation finishes401TR_OptimizationPlan plan;402plan.init(noOpt); // use the cheapest compilation; It's unlikely the compilation will403// succeed because we are running low on native memory404plan.setIsStackAllocated(); // mark that this plan is not dynamically allocated405TR::CompilationInfo * compInfo = getCompilationInfo(jitConfig);406407{ // scope for details408TR::IlGeneratorMethodDetails details(method);409result = (IDATA)compInfo->compileMethod(vmThread, details, oldStartPC, async, compErrCode, &queued, &plan);410}411412// We should probably prevent any future non-essential compilation413compInfo->getPersistentInfo()->setDisableFurtherCompilation(true);414if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerbosePerformance))415{416TR_VerboseLog::writeLineLocked(TR_Vlog_PERF,"t=%6u Disable further compilation due to OOM while creating an optimization plan", (uint32_t)compInfo->getPersistentInfo()->getElapsedTime());417}418}419}420return result;421}422423extern "C" IDATA424retranslateWithPreparationForMethodRedefinition(425struct J9JITConfig *jitConfig,426J9VMThread *vmThread,427J9Method *method,428void *oldStartPC)429{430return retranslateWithPreparation(jitConfig, vmThread, method, oldStartPC, TR_PersistentMethodInfo::RecompDueToInlinedMethodRedefinition);431}432433extern "C" IDATA434retranslateWithPreparation(435struct J9JITConfig *jitConfig,436J9VMThread *vmThread,437J9Method *method,438void *oldStartPC,439UDATA reason)440{441if (!TR::CompilationInfo::get()->asynchronousCompilation() && !J9::PrivateLinkage::LinkageInfo::get(oldStartPC)->recompilationAttempted())442{443TR::Recompilation::fixUpMethodCode(oldStartPC);444}445446TR_PersistentJittedBodyInfo* jbi = TR::Recompilation::getJittedBodyInfoFromPC(oldStartPC);447if (jbi)448{449TR_PersistentMethodInfo *pmi = jbi->getMethodInfo();450if (pmi)451pmi->setReasonForRecompilation(reason);452}453return j9jit_testarossa(jitConfig, vmThread, method, oldStartPC);454}455456457extern "C" void *458old_translateMethodHandle(J9VMThread *currentThread, j9object_t methodHandle)459{460void *result = compileMethodHandleThunk(methodHandle, NULL, currentThread, 0);461if (result)462{463static char *returnNullFromTranslateMethodHandle = feGetEnv("TR_returnNullFromTranslateMethodHandle");464if (returnNullFromTranslateMethodHandle)465result = NULL;466}467468return result;469}470471472extern "C" void *473translateMethodHandle(J9VMThread *currentThread, j9object_t methodHandle, j9object_t arg, U_32 flags)474{475void *result = compileMethodHandleThunk(methodHandle, arg, currentThread, flags);476if (result)477{478static char *returnNullFromTranslateMethodHandle = feGetEnv("TR_returnNullFromTranslateMethodHandle");479if (returnNullFromTranslateMethodHandle)480result = NULL;481}482483return result;484}485486487// -----------------------------------------------------------------------------488// NewInstanceImpl Thunks489// -----------------------------------------------------------------------------490491extern "C" J9Method *492getNewInstancePrototype(J9VMThread * context)493{494J9Method *newInstanceProto = 0;495J9InternalVMFunctions *intFunc = context->javaVM->internalVMFunctions;496497J9Class * jlClass = intFunc->internalFindKnownClass(context, J9VMCONSTANTPOOL_JAVALANGCLASS, J9_FINDKNOWNCLASS_FLAG_EXISTING_ONLY);498if (jlClass)499{500newInstanceProto = (J9Method *) intFunc->javaLookupMethod(501context,502jlClass,503(J9ROMNameAndSignature *) &newInstancePrototypeNameAndSig,5040,505J9_LOOK_DIRECT_NAS | J9_LOOK_VIRTUAL | J9_LOOK_NO_JAVA);506}507508return newInstanceProto;509}510511512extern "C" UDATA513j9jit_createNewInstanceThunk_err(514struct J9JITConfig *jitConfig,515J9VMThread *vmThread,516J9Class *classNeedingThunk,517TR_CompilationErrorCode *compErrCode)518{519TR::CompilationInfo * compInfo = getCompilationInfo(jitConfig);520J9Method *method = getNewInstancePrototype(vmThread);521if (!method)522{523*compErrCode = compilationFailure;524return 0;525}526527#if defined(J9VM_OPT_JITSERVER)528// Do not allow local compilations in JITServer server mode529if (compInfo->getPersistentInfo()->getRemoteCompilationMode() == JITServer::SERVER)530return 0;531#endif532533bool queued = false;534535TR_MethodEvent event;536event._eventType = TR_MethodEvent::NewInstanceImpl;537event._j9method = method;538event._oldStartPC = 0;539event._vmThread = vmThread;540bool newPlanCreated;541TR_OptimizationPlan *plan = TR::CompilationController::getCompilationStrategy()->processEvent(&event, &newPlanCreated);542UDATA result = 0;543if (plan)544{545// if the controller decides to compile this method, trigger the compilation and wait here546547{ // scope for details548J9::NewInstanceThunkDetails details(method, classNeedingThunk);549result = (UDATA)compInfo->compileMethod(vmThread, details, 0, TR_maybe, compErrCode, &queued, plan);550}551552if (!queued && newPlanCreated)553TR_OptimizationPlan::freeOptimizationPlan(plan);554}555556return result;557}558559560extern "C" UDATA561j9jit_createNewInstanceThunk(struct J9JITConfig * jitConfig, J9VMThread * vmThread, J9Class * classNeedingThunk)562{563return j9jit_createNewInstanceThunk_err(jitConfig, vmThread, classNeedingThunk, NULL);564}565566567// -----------------------------------------------------------------------------568// JIT shutdown569// -----------------------------------------------------------------------------570571extern "C" void572stopSamplingThread(J9JITConfig * jitConfig)573{574// Was the samplerThread even created?575if (jitConfig->samplerThread)576{577// TODO: add a trace point in this routine578//Trc_JIT_stopSamplingThread_Entry();579TR::CompilationInfo *compInfo = getCompilationInfo(jitConfig);580j9thread_monitor_enter(jitConfig->samplerMonitor);581// In most cases the state of the sampling thread should be SAMPLE_THR_INITIALIZED582// However, if an early error happens, stage 15 might not be run (this is where we initialize583// the thread) and so the thread could be in ATTACHED_STATE584TR_ASSERT(compInfo->getSamplingThreadLifetimeState() == TR::CompilationInfo::SAMPLE_THR_INITIALIZED ||585compInfo->getSamplingThreadLifetimeState() == TR::CompilationInfo::SAMPLE_THR_ATTACHED,586"sampling thread must be initialized or at least attached if we try to stop it");587// inform samplerThread to exit its loop588shutdownSamplerThread = true;589compInfo->setSamplingThreadLifetimeState(TR::CompilationInfo::SAMPLE_THR_STOPPING);590// interrupt possible nap time for the samplerThread591j9thread_interrupt(jitConfig->samplerThread);592// Wait for samplerThread to exit593while (compInfo->getSamplingThreadLifetimeState() != TR::CompilationInfo::SAMPLE_THR_DESTROYED)594j9thread_monitor_wait(jitConfig->samplerMonitor);595// At this point samplingThread has gone away596compInfo->setSamplerThread(NULL);597jitConfig->samplerThread = 0; // just in case we enter this routine again598j9thread_monitor_exit(jitConfig->samplerMonitor);599// sampleMonitor is no longer needed600j9thread_monitor_destroy(jitConfig->samplerMonitor);601jitConfig->samplerMonitor = 0;602//Trc_JIT_stopSamplingThread_Exit();603}604}605606607extern "C" void608freeJITConfig(J9JITConfig * jitConfig)609{610// This method must be called only when we are sure that there are no other java threads running611if (jitConfig)612{613// Do all JIT compiler present freeing.614//615J9JavaVM * javaVM = jitConfig->javaVM;616PORT_ACCESS_FROM_JAVAVM(javaVM);617618// stopSamplingThread(jitConfig); // done during JitShutdown below619620jitConfig->runtimeFlags &= ~J9JIT_JIT_ATTACHED;621622// If the jitConfig will be freed,623// there is no chance to do all te JIT cleanup.624// Do the JIT cleanup now, even if we tried it before625//626JitShutdown(jitConfig);627628// free the compilation info before freeing the frontend without thread info (jitConfig->compilationInfo)629// which is done on codert_OnUnload630TR::CompilationInfo::freeCompilationInfo(jitConfig);631632// Tell the runtime to unload.633//634codert_OnUnload(javaVM);635}636}637638639// exclusive shutdown. This normally occurs when System.exit() is called by640// the usercode. The VM needs to notify the compilation thread before going641// exclusive - otherwise we end up with a deadlock scenario upon exit642//643extern "C" void644jitExclusiveVMShutdownPending(J9VMThread * vmThread)645{646#ifndef SMALL_APPTHREAD647J9JavaVM *javaVM = vmThread->javaVM;648#if defined(J9VM_OPT_JITSERVER)649TR::CompilationInfo * compInfo = getCompilationInfo(javaVM->jitConfig);650if (compInfo->getPersistentInfo()->getRemoteCompilationMode() == JITServer::SERVER)651{652TR_Listener *listener = ((TR_JitPrivateConfig*)(javaVM->jitConfig->privateConfig))->listener;653if (listener)654{655listener->stop();656}657}658#endif /* defined(J9VM_OPT_JITSERVER) */659660getCompilationInfo(javaVM->jitConfig)->stopCompilationThreads();661#endif662}663664// Code cache callbacks to be used by the VM665//666extern "C" U_8*667getCodeCacheWarmAlloc(void *codeCache)668{669TR::CodeCache * cc = static_cast<TR::CodeCache*>(codeCache);670return cc->getWarmCodeAlloc();671}672673extern "C" U_8*674getCodeCacheColdAlloc(void *codeCache)675{676TR::CodeCache * cc = static_cast<TR::CodeCache*>(codeCache);677return cc->getColdCodeAlloc();678}679680681// -----------------------------------------------------------------------------682// JIT control683// -----------------------------------------------------------------------------684685// Temporarily disable the jit so that no more methods are compiled686extern "C" void687disableJit(J9JITConfig * jitConfig)688{689TR::CompilationInfo * compInfo = getCompilationInfo(jitConfig);690J9JavaVM * vm = jitConfig->javaVM;691if (compInfo && compInfo->getNumCompThreadsActive() > 0)692{693// Suspend compilation.694// This will also flush any methods waiting for compilation695//696compInfo->suspendCompilationThread();697// Generate a trace point698Trc_JIT_DisableJIT(vm->internalVMFunctions->currentVMThread(vm));699700// Turn off interpreter profiling701//702#if defined(J9VM_INTERP_PROFILING_BYTECODES)703stopInterpreterProfiling(jitConfig);704#endif705j9thread_monitor_enter(vm->vmThreadListMutex);706// Set the sampling frequency to a high value - this will send the sampling707// thread to sleep for a long time. If the jit is enabled later we will have708// to interrupt the sampling thread to get it going again.709//710TR::CompilationInfo::TR_SamplerStates samplerState = compInfo->getSamplerState();711if (samplerState != TR::CompilationInfo::SAMPLER_NOT_INITIALIZED && //jitConfig->samplerThread && // Must have a sampler thread712samplerState != TR::CompilationInfo::SAMPLER_SUSPENDED && // Nothing to do if sampler is already suspended713samplerState != TR::CompilationInfo::SAMPLER_STOPPED)714{715TR::PersistentInfo *persistentInfo = compInfo->getPersistentInfo();716compInfo->setSamplerState(TR::CompilationInfo::SAMPLER_SUSPENDED);717jitConfig->samplingFrequency = MAX_SAMPLING_FREQUENCY;718persistentInfo->setLastTimeSamplerThreadWasSuspended(persistentInfo->getElapsedTime());719if (TR::Options::getVerboseOption(TR_VerbosePerformance))720{721TR_VerboseLog::writeLineLocked(TR_Vlog_PERF,"t=%u\tSampling thread suspended and changed frequency to %d ms",722persistentInfo->getElapsedTime(), jitConfig->samplingFrequency);723}724}725// TODO: what are the implications of remaining in an appropriate JIT state?726// Should we change the state to STEADY just to be on the safe side?727// What if this happens during startup? We will kill the startup time?728729//set the countDelta730J9VMThread * currentThread = vm->mainThread;731do732{733currentThread->jitCountDelta = 0;734} while ((currentThread = currentThread->linkNext) != vm->mainThread);735736j9thread_monitor_exit(vm->vmThreadListMutex);737}738}739740741// Re-enable the jit after it has been disabled.742extern "C" void743enableJit(J9JITConfig * jitConfig)744{745TR::CompilationInfo * compInfo = getCompilationInfo(jitConfig);746J9JavaVM * vm = jitConfig->javaVM;747if (compInfo && compInfo->getNumCompThreadsActive() == 0)748{749// Re-enable interpreter profiling if needed750//751#if defined(J9VM_INTERP_PROFILING_BYTECODES)752restartInterpreterProfiling();753#endif754// Resume compilation.755//756compInfo->resumeCompilationThread();757// Generate a trace point758Trc_JIT_EnableJIT(vm->internalVMFunctions->currentVMThread(vm));759760j9thread_monitor_enter(vm->vmThreadListMutex);761762// Set the sampling frequency back to its proper value and kick the763// sampler thread back into life.764//765TR::CompilationInfo::TR_SamplerStates samplerState = compInfo->getSamplerState();766if (samplerState == TR::CompilationInfo::SAMPLER_SUSPENDED) // Nothing to do if sampler is not suspended767{768TR::PersistentInfo *persistentInfo = compInfo->getPersistentInfo();769compInfo->setSamplerState(TR::CompilationInfo::SAMPLER_DEFAULT);770jitConfig->samplingFrequency = TR::Options::getCmdLineOptions()->getSamplingFrequency();771// this wake up call counts as a tick, so mark that we have seen ticks active772// so that we need to wait another 5 seconds to enter idle773persistentInfo->setLastTimeThreadsWereActive(persistentInfo->getElapsedTime());774j9thread_interrupt(jitConfig->samplerThread); // interrupt the sampler to look at its new state775if (TR::Options::getVerboseOption(TR_VerbosePerformance))776{777TR_VerboseLog::writeLineLocked(TR_Vlog_SAMPLING,"t=%u\tSampling thread interrupted and changed frequency to %d ms",778persistentInfo->getElapsedTime(), jitConfig->samplingFrequency);779}780}781782// Set the countDelta783J9VMThread * currentThread = vm->mainThread;784do785{786currentThread->jitCountDelta = 2;787} while ((currentThread = currentThread->linkNext) != vm->mainThread);788789j9thread_monitor_exit(vm->vmThreadListMutex);790791}792} // enableJit793794795// -----------------------------------------------------------------------------796// Programmatic compile interface797// -----------------------------------------------------------------------------798799extern "C" I_32800command(J9VMThread * vmThread, const char * cmdString)801{802TR::CompilationInfo * compInfo = TR::CompilationInfo::get();803804if (strncmp(cmdString, "beginningOfStartup", 18) == 0)805{806TR::Options::getCmdLineOptions()->setOption(TR_AssumeStartupPhaseUntilToldNotTo); // let the JIT know it should wait for endOfStartup hint807if (compInfo)808{809TR::PersistentInfo *persistentInfo = compInfo->getPersistentInfo();810// If we trust the application completely, then set CLP right away811// Otherwise, let JIT heuristics decide at next decision point812if (TR::Options::getCmdLineOptions()->getOption(TR_UseStrictStartupHints))813persistentInfo->setClassLoadingPhase(true); // Enter CLP right away814if (TR::Options::isAnyVerboseOptionSet(TR_VerboseCLP, TR_VerbosePerformance))815{816TR_VerboseLog::writeLineLocked(TR_Vlog_INFO,"Compiler.command(beginningOfStartup)");817}818}819return 0;820}821if (strncmp(cmdString, "endOfStartup", 12) == 0)822{823if (TR::Options::getCmdLineOptions()->getOption(TR_AssumeStartupPhaseUntilToldNotTo)) // refuse to do anything if JIT option was not specified824{825if (compInfo)826{827TR::PersistentInfo *persistentInfo = compInfo->getPersistentInfo();828persistentInfo->setExternalStartupEndedSignal(true);829// If we trust the application completely, then set CLP right away830// Otherwise, let JIT heuristics decide at next decision point831if (TR::Options::getCmdLineOptions()->getOption(TR_UseStrictStartupHints))832persistentInfo->setClassLoadingPhase(false);833if (TR::Options::isAnyVerboseOptionSet(TR_VerboseCLP, TR_VerbosePerformance))834{835TR_VerboseLog::writeLineLocked(TR_Vlog_INFO,"Compiler.command(endOfStartup)");836}837}838}839return 0;840}841842return 0;843}844845static IDATA846internalCompileClass(J9VMThread * vmThread, J9Class * clazz)847{848J9JavaVM * javaVM = vmThread->javaVM;849J9JITConfig * jitConfg = javaVM->jitConfig;850TR::CompilationInfo * compInfo = getCompilationInfo(jitConfig);851TR_J9VMBase *fe = TR_J9VMBase::get(jitConfg, NULL);852853// To prevent class unloading we need VM access854bool threadHadNoVMAccess = (!(vmThread->publicFlags & J9_PUBLIC_FLAGS_VM_ACCESS));855if (threadHadNoVMAccess)856acquireVMAccess(vmThread);857858J9Method * newInstanceThunk = getNewInstancePrototype(vmThread);859860J9ROMMethod * romMethod = (J9ROMMethod *) J9ROMCLASS_ROMMETHODS(clazz->romClass);861J9Method * ramMethods = (J9Method *) (clazz->ramMethods);862for (uint32_t m = 0; m < clazz->romClass->romMethodCount; m++)863{864J9Method * method = &ramMethods[m];865if (!(romMethod->modifiers & (J9AccNative | J9AccAbstract))866&& method != newInstanceThunk867&& !TR::CompilationInfo::isCompiled(method)868&& !fe->isThunkArchetype(method))869{870bool queued = false;871TR_MethodEvent event;872event._eventType = TR_MethodEvent::InterpreterCounterTripped;873event._j9method = method;874event._oldStartPC = 0;875event._vmThread = vmThread;876event._classNeedingThunk = 0;877bool newPlanCreated;878TR_OptimizationPlan *plan = TR::CompilationController::getCompilationStrategy()->processEvent(&event, &newPlanCreated);879if (plan)880{881plan->setIsExplicitCompilation(true);882// If the controller decides to compile this method, trigger the compilation and wait here883884{ // scope for details885TR::IlGeneratorMethodDetails details(method);886compInfo->compileMethod(vmThread, details, 0, TR_no, NULL, &queued, plan);887}888889if (!queued && newPlanCreated)890TR_OptimizationPlan::freeOptimizationPlan(plan);891}892else // No memory to create an optimizationPlan893{894// There is no point to try to compile other methods if we cannot895// create an optimization plan. Bail out896break;897}898}899romMethod = nextROMMethod(romMethod);900}901902if (threadHadNoVMAccess)903releaseVMAccess(vmThread);904905return 1;906}907908909extern "C" IDATA910compileClass(J9VMThread * vmThread, jclass clazzParm)911{912J9JavaVM * javaVM = vmThread->javaVM;913J9Class * clazz;914IDATA rc;915916acquireVMAccess(vmThread);917clazz = J9VM_J9CLASS_FROM_JCLASS(vmThread, clazzParm);918rc = internalCompileClass(vmThread, clazz);919releaseVMAccess(vmThread);920921return rc;922}923924925extern "C" IDATA926compileClasses(J9VMThread * vmThread, const char * pattern)927{928IDATA foundClassToCompile = 0;929J9JavaVM * javaVM = vmThread->javaVM;930J9JITConfig * jitConfig = javaVM->jitConfig;931TR_FrontEnd * vm = TR_J9VMBase::get(jitConfig, vmThread);932TR::CompilationInfo * compInfo = TR::CompilationInfo::get(jitConfig);933if (!compInfo)934return foundClassToCompile;935PORT_ACCESS_FROM_JAVAVM(javaVM);936J9ClassWalkState classWalkState;937938#define PATTERN_BUFFER_LENGTH 256939char patternBuffer[PATTERN_BUFFER_LENGTH];940char * patternString = patternBuffer;941int32_t patternLength = strlen(pattern);942bool freePatternString = false;943944if (patternLength >= PATTERN_BUFFER_LENGTH)945{946patternString = (char*)j9mem_allocate_memory(patternLength + 1, J9MEM_CATEGORY_JIT);947if (!patternString)948return false;949freePatternString = true;950}951#undef PATTERN_BUFFER_LENGTH952953memcpy(patternString, (char *)pattern, patternLength + 1);954955/* Slashify the className */956for (int32_t i = 0; i < patternLength; ++i)957if (patternString[i] == '.')958patternString[i] = '/';959960bool threadHadNoVMAccess = (!(vmThread->publicFlags & J9_PUBLIC_FLAGS_VM_ACCESS));961if (threadHadNoVMAccess)962acquireVMAccess(vmThread);963964J9Class * clazz = javaVM->internalVMFunctions->allLiveClassesStartDo(&classWalkState, javaVM, NULL);965TR_LinkHead0<TR_ClassHolder> *classList = compInfo->getListOfClassesToCompile();966bool classListWasEmpty = classList ? false : true;967968bool abortFlag = false;969while (clazz && !abortFlag)970{971if (!J9ROMCLASS_IS_PRIMITIVE_OR_ARRAY(clazz->romClass))972{973J9UTF8 * clazzUTRF8 = J9ROMCLASS_CLASSNAME(clazz->romClass);974975// j9tty_printf(PORTLIB, "Class %.*s\n", J9UTF8_LENGTH(clazz), J9UTF8_DATA(clazz));976977#define CLASSNAME_BUFFER_LENGTH 1000978char classNameBuffer[CLASSNAME_BUFFER_LENGTH];979char * classNameString = classNameBuffer;980bool freeClassNameString = false;981if (J9UTF8_LENGTH(clazzUTRF8) >= CLASSNAME_BUFFER_LENGTH)982{983classNameString = (char*)j9mem_allocate_memory((J9UTF8_LENGTH(clazzUTRF8)+1)*sizeof(char), J9MEM_CATEGORY_JIT);984if (!classNameString)985{986clazz = javaVM->internalVMFunctions->allLiveClassesNextDo(&classWalkState);987continue;988}989freeClassNameString = true;990}991#undef CLASSNAME_BUFFER_LENGTH992993strncpy(classNameString, (char*)J9UTF8_DATA(clazzUTRF8), J9UTF8_LENGTH(clazzUTRF8));994995if (strstr(classNameString, patternString))996{997TR_ClassHolder * c = NULL;998if (!classListWasEmpty) // If the list was not empty we must search for duplicates999{1000for (c = classList->getFirst(); c; c = c->getNext())1001if (c->getClass() == clazz)1002break; // duplicate found1003}10041005if (!c) // no duplicate found1006{1007TR_ClassHolder *ch = new (PERSISTENT_NEW) TR_ClassHolder(clazz);1008if (ch)1009{1010classList->add(ch);1011foundClassToCompile = 1;1012}1013else1014{1015// cleanup after yourself1016abortFlag = true; // If we cannot allocate a small piece of persistent memory we must bail out1017}1018}1019}10201021if (freeClassNameString)1022j9mem_free_memory(classNameString);1023} // end if10241025clazz = javaVM->internalVMFunctions->allLiveClassesNextDo(&classWalkState);1026}10271028javaVM->internalVMFunctions->allLiveClassesEndDo(&classWalkState);10291030if (freePatternString)1031j9mem_free_memory(patternString);10321033// now compile all classes from the list1034TR_ClassHolder * trj9class;1035do {1036{1037TR::ClassTableCriticalSection compileClasses(vm);1038trj9class = classList->pop();1039}10401041if (trj9class)1042{1043// compile all methods from this class1044if (!abortFlag)1045internalCompileClass(vmThread, trj9class->getClass());1046// free the persistent memory1047TR_Memory::jitPersistentFree(trj9class);1048}1049} while (trj9class);10501051if (threadHadNoVMAccess)1052releaseVMAccess(vmThread);1053return foundClassToCompile;1054}105510561057// -----------------------------------------------------------------------------1058// JIT initialization1059// -----------------------------------------------------------------------------10601061TR_PersistentMemory * initializePersistentMemory(J9JITConfig * jitConfig);10621063extern "C" jint1064onLoadInternal(1065J9JavaVM *javaVM,1066J9JITConfig *jitConfig,1067char *xjitCommandLine,1068char *xaotCommandLine,1069UDATA flagsParm,1070void *reserved0,1071I_32 xnojit)1072{1073PORT_ACCESS_FROM_JAVAVM(javaVM);10741075jitConfig->javaVM = javaVM;1076jitConfig->jitLevelName = TR_BUILD_NAME;10771078TR::CodeCache *firstCodeCache;10791080/* Allocate the code and data cache lists */1081if (!(jitConfig->codeCacheList))1082{1083if ((jitConfig->codeCacheList = javaVM->internalVMFunctions->allocateMemorySegmentList(javaVM, 3, J9MEM_CATEGORY_JIT)) == NULL)1084return -1;1085}1086if (!(jitConfig->dataCacheList))1087{1088if ((jitConfig->dataCacheList = javaVM->internalVMFunctions->allocateMemorySegmentList(javaVM, 3, J9MEM_CATEGORY_JIT)) == NULL)1089return -1;1090}10911092// Callbacks for code cache allocation pointers1093jitConfig->codeCacheWarmAlloc = getCodeCacheWarmAlloc;1094jitConfig->codeCacheColdAlloc = getCodeCacheColdAlloc;10951096/* Allocate the privateConfig structure. Note that the AOTRT DLL does not allocate this structure */1097jitConfig->privateConfig = j9mem_allocate_memory(sizeof(TR_JitPrivateConfig), J9MEM_CATEGORY_JIT);1098if (jitConfig->privateConfig == NULL) // Memory Allocation Failure.1099return -1;11001101memset(jitConfig->privateConfig, 0, sizeof(TR_JitPrivateConfig));1102static_cast<TR_JitPrivateConfig *>(jitConfig->privateConfig)->aotValidHeader = TR_maybe;1103uintptr_t initialFlags = flagsParm;11041105// Force use of register maps1106//1107// todo: this has to be a runtime test for x-compilation1108//1109initialFlags |= J9JIT_CG_REGISTER_MAPS;11101111initialFlags |= J9JIT_GROW_CACHES;11121113jitConfig->runtimeFlags |= initialFlags; // assumes default of bestAvail if nothing set from cmdline11141115jitConfig->j9jit_printf = j9jit_printf;1116((TR_JitPrivateConfig*)jitConfig->privateConfig)->j9jitrt_printf = j9jitrt_printf;1117((TR_JitPrivateConfig*)jitConfig->privateConfig)->j9jitrt_lock_log = j9jitrt_lock_log;1118((TR_JitPrivateConfig*)jitConfig->privateConfig)->j9jitrt_unlock_log = j9jitrt_unlock_log;11191120// set up the entryPoints for compiling and for support of the1121// java.lang.Compiler class.1122jitConfig->entryPoint = j9jit_testarossa;1123jitConfig->retranslateWithPreparation = retranslateWithPreparation;1124jitConfig->retranslateWithPreparationForMethodRedefinition = retranslateWithPreparationForMethodRedefinition;1125jitConfig->entryPointForNewInstance = j9jit_createNewInstanceThunk;1126#if defined(TRANSLATE_METHODHANDLE_TAKES_FLAGS)1127jitConfig->translateMethodHandle = translateMethodHandle;1128#else1129jitConfig->translateMethodHandle = old_translateMethodHandle;1130#endif1131jitConfig->disableJit = disableJit;1132jitConfig->enableJit = enableJit;1133jitConfig->compileClass = compileClass;1134jitConfig->compileClasses = compileClasses;1135#ifdef ENABLE_GPU1136jitConfig->launchGPU = launchGPU;1137#endif1138jitConfig->promoteGPUCompile = promoteGPUCompile;1139jitConfig->command = command;1140jitConfig->bcSizeLimit = 0xFFFF;11411142#ifdef J9VM_OPT_JAVA_CRYPTO_ACCELERATION1143//Add support for AES methods.1144jitConfig->isAESSupportedByHardware = isAESSupportedByHardware;1145jitConfig->expandAESKeyInHardware = expandAESKeyInHardware;1146jitConfig->doAESInHardware = doAESInHardware;11471148//Add support for SHA methods.1149jitConfig->getCryptoHardwareFeatures = getCryptoHardwareFeatures;1150jitConfig->doSha256InHardware = doSha256InHardware;1151jitConfig->doSha512InHardware = doSha512InHardware;1152#endif11531154//set up our vlog Manager1155TR_VerboseLog::initialize(jitConfig);1156initializePersistentMemory(jitConfig);11571158// set up entry point for starting JITServer1159#if defined(J9VM_OPT_JITSERVER)1160jitConfig->startJITServer = startJITServer;1161jitConfig->waitJITServerTermination = waitJITServerTermination;1162#endif /* J9VM_OPT_JITSERVER */11631164TR_PersistentMemory * persistentMemory = (TR_PersistentMemory *)jitConfig->scratchSegment;1165if (persistentMemory == NULL)1166return -1;11671168// JITServer: persistentCHTable used to be inited here, but we have to move it after JITServer commandline opts1169// setting it to null here to catch anything that assumes it's set between here and the new init code.1170persistentMemory->getPersistentInfo()->setPersistentCHTable(NULL);11711172if (!TR::CompilationInfo::createCompilationInfo(jitConfig))1173return -1;11741175if (!TR_J9VMBase::createGlobalFrontEnd(jitConfig, TR::CompilationInfo::get()))1176return -1;11771178TR_J9VMBase * feWithoutThread(TR_J9VMBase::get(jitConfig, NULL));1179if (!feWithoutThread)1180return -1;11811182/*aotmcc-move it here from below !!!! this is after the jitConfig->runtimeFlags=AOT is set*/1183/*also jitConfig->javaVM = javaVM has to be set for the case we run j9.exe -Xnoaot ....*/1184J9VMThread *curThread = javaVM->internalVMFunctions->currentVMThread(javaVM);1185TR_J9VMBase * fe = TR_J9VMBase::get(jitConfig, curThread);11861187int32_t numCodeCachesToCreateAtStartup = 1;11881189#if defined(J9ZOS390) && !defined(TR_TARGET_64BIT)1190// zOS 31-bit1191J9JavaVM * vm = javaVM; //macro FIND_AND_CONSUME_ARG refers to javaVM as vm1192if (isQuickstart)1193{1194jitConfig->codeCacheKB = 1024;1195jitConfig->dataCacheKB = 1024;1196}1197else1198{1199jitConfig->codeCacheKB = 2048;1200jitConfig->dataCacheKB = 2048;1201}1202#else1203#if (defined(TR_HOST_POWER) || defined(TR_HOST_S390) || (defined(TR_HOST_X86) && defined(TR_HOST_64BIT)))1204jitConfig->codeCacheKB = 2048;1205jitConfig->dataCacheKB = 2048;12061207//zOS will set the code cache to create at startup after options are enabled below1208#if !defined(J9ZOS390)1209if (!isQuickstart) // for -Xquickstart start with one code cache1210numCodeCachesToCreateAtStartup = 4;1211#endif1212#else1213jitConfig->codeCacheKB = 2048; // WAS-throughput guided change1214//jitConfig->codeCacheKB = J9_JIT_CODE_CACHE_SIZE / 1024; // bytes -> k1215jitConfig->dataCacheKB = 512; // bytes -> k1216#endif1217#endif121812191220#if defined(J9VM_OPT_JITSERVER)1221if (javaVM->internalVMFunctions->isJITServerEnabled(javaVM))1222{1223// Use smaller caches on the server because1224// just one method's data is going to be stored there at a time1225jitConfig->codeCacheKB = 1024;1226jitConfig->dataCacheKB = 1024;1227}1228#endif12291230if (fe->isAOT_DEPRECATED_DO_NOT_USE())1231{1232jitConfig->codeCacheTotalKB = 128 * 1024; // default limit on amount of code that can be generated (128MB)1233jitConfig->dataCacheTotalKB = 64 * 1024; // default limit on amount of meta-data that can be generated (64MB)1234}1235else1236{1237#if defined(TR_TARGET_64BIT)1238jitConfig->codeCacheTotalKB = 256 * 1024;1239jitConfig->dataCacheTotalKB = 384 * 1024;1240#else1241jitConfig->codeCacheTotalKB = 64 * 1024;1242jitConfig->dataCacheTotalKB = 192 * 1024;1243#endif12441245#if defined(J9ZTPF)1246/*1247* The z/TPF OS does not have the ability to reserve memory. It allocates whatever it1248* is asked to allocate. Allocate the code cache based on a percentage (20%) of memory1249* the process is allowed to have; cap the maximum using the default 256m and use a 1m floor.1250* MAXXMMES is specified as the number of 1MB frames.1251* Use the default 2048 KB data cache. The default values for z/TPF can be1252* overridden via the command line interface.1253*/1254const uint16_t ZTPF_CODE_CACHE_DIVISOR = 5;12551256/* Retrieve the maximum number of 1MB frames that a z/TPF process can have and */1257/* then take 20% of that value to use for the code cache size. */1258const uint16_t physMemory = *(static_cast<uint16_t*>(cinfc_fast(CINFC_CMMMMES)) + 4) / ZTPF_CODE_CACHE_DIVISOR;12591260/* Provide a 1MB floor and 256MB ceiling for the code cache size */1261if (physMemory <= 1)1262{1263jitConfig->codeCacheKB = 1024;1264jitConfig->codeCacheTotalKB = 1024;1265}1266else if (physMemory < 256)1267{1268jitConfig->codeCacheKB = 2048;1269jitConfig->codeCacheTotalKB = physMemory * 1024;1270}1271else1272{1273jitConfig->codeCacheKB = 2048;1274jitConfig->codeCacheTotalKB = 256 * 1024;1275}12761277jitConfig->dataCacheKB = 2048;1278jitConfig->dataCacheTotalKB = 384 * 1024;1279#endif1280}12811282TR::Options::setScratchSpaceLimit(DEFAULT_SCRATCH_SPACE_LIMIT_KB * 1024);1283TR::Options::setScratchSpaceLowerBound(DEFAULT_SCRATCH_SPACE_LOWER_BOUND_KB * 1024);12841285jitConfig->samplingFrequency = TR::Options::getSamplingFrequency();12861287#if defined(DEBUG)1288static char * breakOnLoad = feGetEnv("TR_BreakOnLoad");1289if (breakOnLoad)1290TR::Compiler->debug.breakPoint();1291#endif12921293// Parse the command line options1294//1295if (xaotCommandLine)1296{1297char *endAOTOptions = TR::Options::processOptionsAOT(xaotCommandLine, jitConfig, feWithoutThread);1298if (*endAOTOptions)1299{1300// Generate AOT error message only if error occurs in -Xaot processing1301if (0 != (TR::Options::_processOptionsStatus & TR_AOTProcessErrorAOTOpts))1302{1303scan_failed(PORTLIB, "AOT", endAOTOptions);1304printf("<AOT: fatal error, invalid command line>\n");1305#ifdef DEBUG1306printf(" for help use -Xaot:help\n\n");1307#endif1308}1309return -1;1310}1311}13121313char *endJITOptions = TR::Options::processOptionsJIT(xjitCommandLine, jitConfig, feWithoutThread);13141315if (*endJITOptions)1316{1317// Generate JIT error message only if error occurs in -Xjit processing1318if (0 != (TR::Options::_processOptionsStatus & TR_JITProcessErrorJITOpts))1319{1320scan_failed(PORTLIB, "JIT", endJITOptions);1321printf("<JIT: fatal error, invalid command line>\n");1322#ifdef DEBUG1323printf(" for help use -Xjit:help\n\n");1324#endif1325}1326return -1;1327}13281329// Now that the options have been processed we can initialize the RuntimeAssumptionTables1330// If we cannot allocate various runtime assumption hash tables, fail the JVM13311332fe->initializeSystemProperties();13331334// Allocate trampolines for z/OS 64-bit1335#if defined(J9ZOS390)1336if (TR::Options::getCmdLineOptions()->getOption(TR_EnableRMODE64) && !isQuickstart)1337numCodeCachesToCreateAtStartup = 4;1338#endif133913401341#if defined(J9VM_OPT_JITSERVER)1342if (persistentMemory->getPersistentInfo()->getRemoteCompilationMode() != JITServer::SERVER)1343#endif1344{1345if (!persistentMemory->getPersistentInfo()->getRuntimeAssumptionTable()->init())1346return -1;1347}13481349TR_PersistentClassLoaderTable *loaderTable = new (PERSISTENT_NEW) TR_PersistentClassLoaderTable(persistentMemory);1350if (loaderTable == NULL)1351return -1;1352persistentMemory->getPersistentInfo()->setPersistentClassLoaderTable(loaderTable);13531354jitConfig->iprofilerBufferSize = TR::Options::_iprofilerBufferSize; //1024;13551356javaVM->minimumSuperclassArraySize = TR::Options::_minimumSuperclassArraySize;13571358if (!jitConfig->tracingHook && TR::Options::requiresDebugObject())1359{1360jitConfig->tracingHook = (void*) (TR_CreateDebug_t)createDebugObject;1361}13621363if (!jitConfig->tracingHook)1364TR::Options::suppressLogFileBecauseDebugObjectNotCreated();13651366TR_AOTStats *aotStats = (TR_AOTStats *)j9mem_allocate_memory(sizeof(TR_AOTStats), J9MEM_CATEGORY_JIT);1367memset(aotStats, 0, sizeof(TR_AOTStats));1368((TR_JitPrivateConfig*)jitConfig->privateConfig)->aotStats = aotStats;13691370TR::CodeCacheManager *codeCacheManager = (TR::CodeCacheManager *) j9mem_allocate_memory(sizeof(TR::CodeCacheManager), J9MEM_CATEGORY_JIT);1371if (codeCacheManager == NULL)1372return -1;1373memset(codeCacheManager, 0, sizeof(TR::CodeCacheManager));13741375// must initialize manager using the global (not thread specific) fe because current thread isn't guaranteed to live longer than the manager1376new (codeCacheManager) TR::CodeCacheManager(feWithoutThread, TR::Compiler->rawAllocator);13771378TR::CodeCacheConfig &codeCacheConfig = codeCacheManager->codeCacheConfig();13791380// Do not allow code caches smaller than 128KB1381if (jitConfig->codeCacheKB < 128)1382jitConfig->codeCacheKB = 128;1383if (!fe->isAOT_DEPRECATED_DO_NOT_USE())1384{1385if (jitConfig->codeCacheKB > 32768)1386jitConfig->codeCacheKB = 32768;1387}13881389if (jitConfig->codeCacheKB > jitConfig->codeCacheTotalKB)1390{1391/* Handle case where user has set codeCacheTotalKB smaller than codeCacheKB (e.g. -Xjit:codeTotal=256) by setting codeCacheKB = codeCacheTotalKB */1392jitConfig->codeCacheKB = jitConfig->codeCacheTotalKB;1393}13941395if (jitConfig->dataCacheKB > jitConfig->dataCacheTotalKB)1396{1397/* Handle case where user has set dataCacheTotalKB smaller than dataCacheKB (e.g. -Xjit:dataTotal=256) by setting dataCacheKB = dataCacheTotalKB */1398jitConfig->dataCacheKB = jitConfig->dataCacheTotalKB;1399}14001401I_32 maxNumberOfCodeCaches = jitConfig->codeCacheTotalKB / jitConfig->codeCacheKB;1402if (fe->isAOT_DEPRECATED_DO_NOT_USE())1403maxNumberOfCodeCaches = 1;14041405// setupCodeCacheParameters must stay before TR::CodeCacheManager::initialize() because it needs trampolineCodeSize1406setupCodeCacheParameters(&codeCacheConfig._trampolineCodeSize, &codeCacheConfig._mccCallbacks, &codeCacheConfig._numOfRuntimeHelpers, &codeCacheConfig._CCPreLoadedCodeSize);14071408if (!TR_TranslationArtifactManager::initializeGlobalArtifactManager(jitConfig->translationArtifacts, jitConfig->javaVM))1409return -1;14101411codeCacheConfig._allowedToGrowCache = (javaVM->jitConfig->runtimeFlags & J9JIT_GROW_CACHES) != 0;1412codeCacheConfig._lowCodeCacheThreshold = TR::Options::_lowCodeCacheThreshold;1413codeCacheConfig._verboseCodeCache = TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerboseCodeCache);1414codeCacheConfig._verbosePerformance = TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerbosePerformance);1415codeCacheConfig._verboseReclamation = TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerboseCodeCacheReclamation);1416codeCacheConfig._doSanityChecks = TR::Options::getCmdLineOptions()->getOption(TR_CodeCacheSanityCheck);1417codeCacheConfig._codeCacheTotalKB = jitConfig->codeCacheTotalKB;1418codeCacheConfig._codeCacheKB = jitConfig->codeCacheKB;1419codeCacheConfig._codeCachePadKB = jitConfig->codeCachePadKB;1420codeCacheConfig._codeCacheAlignment = jitConfig->codeCacheAlignment;1421codeCacheConfig._codeCacheFreeBlockRecylingEnabled = !TR::Options::getCmdLineOptions()->getOption(TR_DisableFreeCodeCacheBlockRecycling);1422codeCacheConfig._largeCodePageSize = jitConfig->largeCodePageSize;1423codeCacheConfig._largeCodePageFlags = jitConfig->largeCodePageFlags;1424codeCacheConfig._maxNumberOfCodeCaches = maxNumberOfCodeCaches;1425codeCacheConfig._canChangeNumCodeCaches = (TR::Options::getCmdLineOptions()->getNumCodeCachesToCreateAtStartup() <= 0);14261427UDATA totalCacheBytes = codeCacheConfig._codeCacheTotalKB << 10;1428codeCacheConfig._highCodeCacheOccupancyThresholdInBytes = TR::Options::_highCodeCacheOccupancyPercentage * (totalCacheBytes / 100);14291430static char * segmentCarving = feGetEnv("TR_CodeCacheConsolidation");1431bool useConsolidatedCodeCache = segmentCarving != NULL ||1432TR::Options::getCmdLineOptions()->getOption(TR_EnableCodeCacheConsolidation);14331434if (TR::Options::getCmdLineOptions()->getNumCodeCachesToCreateAtStartup() > 0) // user has specified option1435numCodeCachesToCreateAtStartup = TR::Options::getCmdLineOptions()->getNumCodeCachesToCreateAtStartup();1436// We cannot create at startup more code caches than the maximum1437if (numCodeCachesToCreateAtStartup > maxNumberOfCodeCaches)1438numCodeCachesToCreateAtStartup = maxNumberOfCodeCaches;14391440firstCodeCache = codeCacheManager->initialize(useConsolidatedCodeCache, numCodeCachesToCreateAtStartup);14411442// large code page size may have been updated by initialize(), so copy back to jitConfig1443jitConfig->largeCodePageSize = (UDATA) codeCacheConfig.largeCodePageSize();14441445if (firstCodeCache == NULL)1446return -1;1447jitConfig->codeCache = firstCodeCache->j9segment();1448((TR_JitPrivateConfig *) jitConfig->privateConfig)->codeCacheManager = codeCacheManager; // for kca's benefit14491450if (fe->isAOT_DEPRECATED_DO_NOT_USE())1451{1452jitConfig->codeCache->heapAlloc = firstCodeCache->getCodeTop();1453#if defined(TR_TARGET_X86) && defined(TR_HOST_32BIT)1454javaVM->jitConfig = (J9JITConfig *)jitConfig;1455queryX86TargetCPUID(javaVM);1456#endif1457}14581459if (!fe->isAOT_DEPRECATED_DO_NOT_USE())1460{1461J9VMThread *currentVMThread = javaVM->internalVMFunctions->currentVMThread(javaVM);14621463if (currentVMThread)1464{1465currentVMThread->maxProfilingCount = (UDATA)encodeCount(TR::Options::_maxIprofilingCountInStartupMode);1466}14671468#if defined(TR_TARGET_S390)1469// allocate 4K1470jitConfig->pseudoTOC = j9mem_allocate_memory(4096, J9MEM_CATEGORY_JIT);1471if (!jitConfig->pseudoTOC)1472return -1;14731474if (currentVMThread)1475currentVMThread->codertTOC = (void *)jitConfig->pseudoTOC;1476#endif14771478}14791480/* allocate the data cache */1481if (jitConfig->dataCacheKB < 1)1482{1483printf("<JIT: fatal error, data cache size must be at least 1 Kb>\n");1484return -1;1485}1486if (!TR_DataCacheManager::initialize(jitConfig))1487{1488printf("{JIT: fatal error, failed to allocate %" OMR_PRIuPTR " Kb data cache}\n", jitConfig->dataCacheKB);1489return -1;1490}14911492jitConfig->thunkLookUpNameAndSig = &j9ThunkLookupNameAndSig;14931494TR::CompilationInfo * compInfo = TR::CompilationInfo::get();14951496// Now that we have all options (and before starting the compilation thread) we1497// should initialize the compilationController1498//1499TR::CompilationController::init(compInfo);15001501if (!TR::CompilationController::useController()) // test if initialization succeeded1502return -1;15031504// Create the CpuUtilization object after options processing1505{1506PORT_ACCESS_FROM_JAVAVM(jitConfig->javaVM);1507CpuUtilization* cpuUtil = new (PERSISTENT_NEW) CpuUtilization(jitConfig);1508compInfo->setCpuUtil(cpuUtil);1509}15101511// disable CPU utilization monitoring if told to do so on command line1512if (TR::Options::getCmdLineOptions()->getOption(TR_DisableCPUUtilization))1513compInfo->getCpuUtil()->disable();1514else1515compInfo->getCpuUtil()->updateCpuUtil(jitConfig);15161517// Need to let VM know that we will be using a machines vector facility (so it can save/restore preserved regs),1518// early in JIT startup to prevent subtle FP bugs1519#ifdef TR_TARGET_S3901520if (TR::Compiler->target.cpu.supportsFeature(OMR_FEATURE_S390_VECTOR_FACILITY) && !TR::Options::getCmdLineOptions()->getOption(TR_DisableSIMD))1521{1522javaVM->extendedRuntimeFlags |= J9_EXTENDED_RUNTIME_USE_VECTOR_REGISTERS;1523}1524#elif defined(TR_TARGET_POWER) && defined(TR_TARGET_64BIT)1525if(TR::Compiler->target.cpu.isAtLeast(OMR_PROCESSOR_PPC_P8) && TR::Compiler->target.cpu.supportsFeature(OMR_FEATURE_PPC_HAS_VSX) && !TR::Options::getCmdLineOptions()->getOption(TR_DisableSIMD))1526{1527javaVM->extendedRuntimeFlags |= J9_EXTENDED_RUNTIME_USE_VECTOR_REGISTERS;1528}1529#endif15301531// Address the case where the number of compilation threads is higher than the1532// maximum number of code caches1533if (TR::Options::_numUsableCompilationThreads > maxNumberOfCodeCaches)1534{1535#if defined(J9VM_OPT_JITSERVER)1536if (persistentMemory->getPersistentInfo()->getRemoteCompilationMode() == JITServer::SERVER)1537{1538fprintf(stderr,1539"Requested number of compilation threads is larger than the maximum number of code caches: %d > %d.\n"1540"Use the -Xcodecachetotal option to increase the maximum total size of the code cache.",1541TR::Options::_numUsableCompilationThreads, maxNumberOfCodeCaches1542);1543return -1;1544}1545#endif /* defined(J9VM_OPT_JITSERVER) */1546TR::Options::_numUsableCompilationThreads = maxNumberOfCodeCaches;1547}15481549compInfo->updateNumUsableCompThreads(TR::Options::_numUsableCompilationThreads);15501551if (!compInfo->allocateCompilationThreads(TR::Options::_numUsableCompilationThreads))1552{1553fprintf(stderr, "onLoadInternal: Failed to set up %d compilation threads\n", TR::Options::_numUsableCompilationThreads);1554return -1;1555}15561557// create regular compilation threads1558int32_t highestThreadID = 0;1559for (; highestThreadID < TR::Options::_numUsableCompilationThreads; highestThreadID++)1560{1561if (compInfo->startCompilationThread(-1, highestThreadID, /* isDiagnosticThread */ false) != 0)1562{1563// Failed to start compilation thread.1564Trc_JIT_startCompThreadFailed(curThread);1565return -1;1566}1567}15681569// If more than one diagnostic compilation thread is created, MAX_DIAGNOSTIC_COMP_THREADS needs to be updated1570// create diagnostic compilation thread1571if (compInfo->startCompilationThread(-1, highestThreadID, /* isDiagnosticThread */ true) != 0)1572{1573// Failed to start compilation thread.1574Trc_JIT_startCompThreadFailed(curThread);1575highestThreadID++;1576return -1;1577}15781579// Create the monitor used for log handling in presence of multiple compilation threads1580// TODO: postpone this when we know that a log is actually used1581if (!compInfo->createLogMonitor())1582{1583fprintf(stderr, "cannot create log monitor\n");1584return -1;1585}15861587if (!fe->isAOT_DEPRECATED_DO_NOT_USE() && !(jitConfig->runtimeFlags & J9JIT_TOSS_CODE))1588{1589javaVM->runtimeFlags |= J9_RUNTIME_JIT_ACTIVE;1590jitConfig->jitExclusiveVMShutdownPending = jitExclusiveVMShutdownPending;1591}15921593// initialize the IProfiler15941595if (!TR::Options::getCmdLineOptions()->getOption(TR_DisableInterpreterProfiling))1596{1597#if defined(J9VM_OPT_JITSERVER)1598if (persistentMemory->getPersistentInfo()->getRemoteCompilationMode() == JITServer::SERVER)1599{1600((TR_JitPrivateConfig*)(jitConfig->privateConfig))->iProfiler = JITServerIProfiler::allocate(jitConfig);1601}1602else if (persistentMemory->getPersistentInfo()->getRemoteCompilationMode() == JITServer::CLIENT)1603{1604((TR_JitPrivateConfig*)(jitConfig->privateConfig))->iProfiler = JITClientIProfiler::allocate(jitConfig);1605}1606else1607#endif1608{1609((TR_JitPrivateConfig*)(jitConfig->privateConfig))->iProfiler = TR_IProfiler::allocate(jitConfig);1610}1611if (!(((TR_JitPrivateConfig*)(jitConfig->privateConfig))->iProfiler))1612{1613// Warn that IProfiler was not allocated1614TR::Options::getCmdLineOptions()->setOption(TR_DisableInterpreterProfiling);1615// Warn that Interpreter Profiling was disabled1616}1617}1618else1619{1620((TR_JitPrivateConfig*)(jitConfig->privateConfig))->iProfiler = NULL;1621}16221623if (!TR::Options::getCmdLineOptions()->getOption(TR_DisableJProfilerThread))1624{1625((TR_JitPrivateConfig*)(jitConfig->privateConfig))->jProfiler = TR_JProfilerThread::allocate();1626if (!(((TR_JitPrivateConfig*)(jitConfig->privateConfig))->jProfiler))1627{1628TR::Options::getCmdLineOptions()->setOption(TR_DisableJProfilerThread);1629}1630}1631else1632{1633((TR_JitPrivateConfig*)(jitConfig->privateConfig))->jProfiler = NULL;1634}16351636vpMonitor = TR::Monitor::create("ValueProfilingMutex");16371638// initialize the HWProfiler1639UDATA riInitializeFailed = 1;1640if (TR::Options::_hwProfilerEnabled == TR_yes)1641{1642#if defined(TR_HOST_S390) && defined(BUILD_Z_RUNTIME_INSTRUMENTATION)1643if (TR::Compiler->target.cpu.supportsFeature(OMR_FEATURE_S390_RI))1644((TR_JitPrivateConfig*)(jitConfig->privateConfig))->hwProfiler = TR_ZHWProfiler::allocate(jitConfig);1645#elif defined(TR_HOST_POWER)1646#if !defined(J9OS_I5)1647/* We disable it on current releases. May enable in future. */1648((TR_JitPrivateConfig*)(jitConfig->privateConfig))->hwProfiler = TR::Compiler->target.cpu.isAtLeast(OMR_PROCESSOR_PPC_P8) ? TR_PPCHWProfiler::allocate(jitConfig) : NULL;1649#else1650((TR_JitPrivateConfig*)(jitConfig->privateConfig))->hwProfiler = NULL;1651#endif /* !defined(J9OS_I5) */1652#endif16531654//Initialize VM support for RI.1655#ifdef J9VM_JIT_RUNTIME_INSTRUMENTATION1656if (NULL != ((TR_JitPrivateConfig*)(jitConfig->privateConfig))->hwProfiler)1657riInitializeFailed = initializeJITRuntimeInstrumentation(javaVM);1658#endif1659}1660else1661{1662((TR_JitPrivateConfig*)(jitConfig->privateConfig))->hwProfiler = NULL;1663}16641665if (riInitializeFailed || ((TR_JitPrivateConfig*)(jitConfig->privateConfig))->hwProfiler == NULL)1666{1667// This will also internally call setRuntimeInstrumentationRecompilationEnabled(false)1668persistentMemory->getPersistentInfo()->setRuntimeInstrumentationEnabled(false);1669}1670else1671{1672persistentMemory->getPersistentInfo()->setRuntimeInstrumentationEnabled(true);16731674if (TR::Options::getCmdLineOptions()->getOption(TR_EnableHardwareProfileRecompilation) &&1675!(TR::Options::getCmdLineOptions()->getFixedOptLevel() == -1 &&1676TR::Options::getCmdLineOptions()->getOption(TR_InhibitRecompilation)))1677persistentMemory->getPersistentInfo()->setRuntimeInstrumentationRecompilationEnabled(true);1678}16791680#if defined(J9VM_OPT_JITSERVER)1681// server-side CH table is initialized per-client1682if (persistentMemory->getPersistentInfo()->getRemoteCompilationMode() != JITServer::SERVER)1683#endif1684{1685TR_PersistentCHTable *chtable;1686#if defined(J9VM_OPT_JITSERVER)1687if (persistentMemory->getPersistentInfo()->getRemoteCompilationMode() == JITServer::CLIENT)1688{1689chtable = new (PERSISTENT_NEW) JITClientPersistentCHTable(persistentMemory);1690}1691else1692#endif1693{1694chtable = new (PERSISTENT_NEW) TR_PersistentCHTable(persistentMemory);1695}1696if (chtable == NULL)1697return -1;1698persistentMemory->getPersistentInfo()->setPersistentCHTable(chtable);1699}17001701#if defined(J9VM_OPT_JITSERVER)1702if (JITServer::CommunicationStream::useSSL())1703{1704if (!JITServer::loadLibsslAndFindSymbols())1705return -1;1706}1707else1708{1709bool shareROMClasses = TR::Options::_shareROMClasses &&1710(compInfo->getPersistentInfo()->getRemoteCompilationMode() == JITServer::SERVER);1711bool useAOTCache = compInfo->getPersistentInfo()->getJITServerUseAOTCache();17121713// ROMClass sharing and AOT cache use a hash implementation from SSL.1714// Disable them (with an error message to vlog) if we can't load the library.1715if ((shareROMClasses || useAOTCache) && !JITServer::loadLibsslAndFindSymbols())1716{1717TR::Options::_shareROMClasses = false;1718compInfo->getPersistentInfo()->setJITServerUseAOTCache(false);17191720if (TR::Options::getVerboseOption(TR_VerboseJITServer))1721{1722if (shareROMClasses)1723TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,1724"ERROR: Failed to load SSL library, disabling ROMClass sharing");1725if (useAOTCache)1726TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,1727"ERROR: Failed to load SSL library, disabling AOT cache");1728}1729}1730}17311732if (compInfo->getPersistentInfo()->getRemoteCompilationMode() == JITServer::SERVER)1733{1734JITServer::CommunicationStream::initConfigurationFlags();17351736// Allocate the hashtable that holds information about clients1737compInfo->setClientSessionHT(ClientSessionHT::allocate());17381739((TR_JitPrivateConfig*)(jitConfig->privateConfig))->listener = TR_Listener::allocate();1740if (!((TR_JitPrivateConfig*)(jitConfig->privateConfig))->listener)1741{1742// warn that Listener was not allocated1743j9tty_printf(PORTLIB, "JITServer Listener not allocated, abort.\n");1744return -1;1745}1746if (jitConfig->samplingFrequency != 0)1747{1748((TR_JitPrivateConfig*)(jitConfig->privateConfig))->statisticsThreadObject = JITServerStatisticsThread::allocate();1749if (!((TR_JitPrivateConfig*)(jitConfig->privateConfig))->statisticsThreadObject)1750{1751// warn that Statistics Thread was not allocated1752j9tty_printf(PORTLIB, "JITServer Statistics thread not allocated, abort.\n");1753return -1;1754}1755}1756else1757{1758((TR_JitPrivateConfig*)(jitConfig->privateConfig))->statisticsThreadObject = NULL;1759}17601761//NOTE: This must be done only after the SSL library has been successfully loaded1762if (TR::Options::_shareROMClasses)1763{1764size_t numPartitions = std::max(1, TR::Options::_sharedROMClassCacheNumPartitions);1765auto cache = new (PERSISTENT_NEW) JITServerSharedROMClassCache(numPartitions);1766if (!cache)1767return -1;1768compInfo->setJITServerSharedROMClassCache(cache);1769}17701771//NOTE: This must be done only after the SSL library has been successfully loaded1772if (compInfo->getPersistentInfo()->getJITServerUseAOTCache())1773{1774auto aotCacheMap = new (PERSISTENT_NEW) JITServerAOTCacheMap();1775if (!aotCacheMap)1776return -1;1777compInfo->setJITServerAOTCacheMap(aotCacheMap);1778}1779}1780else if (compInfo->getPersistentInfo()->getRemoteCompilationMode() == JITServer::CLIENT)1781{1782compInfo->setUnloadedClassesTempList(new (PERSISTENT_NEW) PersistentVector<TR_OpaqueClassBlock*>(1783PersistentVector<TR_OpaqueClassBlock*>::allocator_type(TR::Compiler->persistentAllocator())));17841785compInfo->setIllegalFinalFieldModificationList(new (PERSISTENT_NEW) PersistentVector<TR_OpaqueClassBlock*>(1786PersistentVector<TR_OpaqueClassBlock*>::allocator_type(TR::Compiler->persistentAllocator())));17871788compInfo->setNewlyExtendedClasses(new (PERSISTENT_NEW) PersistentUnorderedMap<TR_OpaqueClassBlock*, uint8_t>(1789PersistentUnorderedMap<TR_OpaqueClassBlock*, uint8_t>::allocator_type(TR::Compiler->persistentAllocator())));17901791// Try to initialize SSL1792if (JITServer::ClientStream::static_init(compInfo->getPersistentInfo()) != 0)1793return -1;17941795JITServer::CommunicationStream::initConfigurationFlags();1796}1797#endif // J9VM_OPT_JITSERVER17981799#if defined(TR_HOST_S390)1800if (TR::Compiler->om.readBarrierType() != gc_modron_readbar_none)1801{1802// TODO (Guarded Storage): With the change to prevent lower trees, there's1803// an outstanding DLT issue where a LLGFSG is generated when loading the1804// DLT block from the J9VMThread instead of a LG. Disabling DLT until that1805// issue is fixed.1806TR::Options::getCmdLineOptions()->setOption(TR_DisableDynamicLoopTransfer);1807}1808#endif18091810jitConfig->runJitdump = runJitdump;18111812jitConfig->printAOTHeaderProcessorFeatures = printAOTHeaderProcessorFeatures;18131814if (!TR::Compiler->target.cpu.isI386())1815{1816TR_J2IThunkTable *ieThunkTable = new (PERSISTENT_NEW) TR_J2IThunkTable(persistentMemory, "InvokeExactJ2IThunkTable");1817if (ieThunkTable == NULL)1818return -1;1819persistentMemory->getPersistentInfo()->setInvokeExactJ2IThunkTable(ieThunkTable);1820}1821return 0;1822}182318241825extern "C" int32_t1826aboutToBootstrap(J9JavaVM * javaVM, J9JITConfig * jitConfig)1827{1828char isSMP;1829PORT_ACCESS_FROM_JAVAVM(javaVM);1830bool isSharedAOT = false;18311832if (!jitConfig)1833return -1;18341835#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))1836isSharedAOT = TR::Options::sharedClassCache();1837#endif /* J9VM_INTERP_AOT_COMPILE_SUPPORT && J9VM_OPT_SHARED_CLASSES && TR_HOST_X86 && TR_HOST_S390 */18381839#if defined(J9VM_OPT_SHARED_CLASSES)1840// must be called before latePostProcess1841if (isSharedAOT)1842{1843TR::CompilationInfo * compInfo = getCompilationInfo(jitConfig);1844J9SharedClassJavacoreDataDescriptor *javacoreDataPtr = compInfo->getAddrOfJavacoreData();18451846TR_ASSERT(javaVM->sharedClassConfig, "sharedClassConfig must exist");1847if (javaVM->sharedClassConfig->getJavacoreData)1848{1849memset(javacoreDataPtr, 0, sizeof(J9SharedClassJavacoreDataDescriptor));1850if (javaVM->sharedClassConfig->getJavacoreData(javaVM, javacoreDataPtr))1851{1852if (javacoreDataPtr->numAOTMethods > TR::Options::_aotWarmSCCThreshold)1853compInfo->setIsWarmSCC(TR_yes);1854else1855compInfo->setIsWarmSCC(TR_no);1856}1857}18581859if (TR::Options::getAOTCmdLineOptions()->getOption(TR_DisablePersistIProfile) ||1860TR::Options::getJITCmdLineOptions()->getOption(TR_DisablePersistIProfile))1861{1862javaVM->sharedClassConfig->runtimeFlags &= ~J9SHR_RUNTIMEFLAG_ENABLE_JITDATA;1863}1864else if ((javaVM->sharedClassConfig->runtimeFlags & J9SHR_RUNTIMEFLAG_ENABLE_JITDATA) == 0)1865{1866printf("\n ** sc disabled **\n");18671868TR::Options::getAOTCmdLineOptions()->setOption(TR_DisablePersistIProfile);1869}1870}1871#endif18721873char * endOptionsAOT = TR::Options::latePostProcessAOT(jitConfig);1874if ((intptr_t)endOptionsAOT == 1)1875return 1;18761877if (endOptionsAOT)1878{1879scan_failed(PORTLIB, "AOT", endOptionsAOT);1880printf("<JIT: fatal error, invalid command line>\n");1881#ifdef DEBUG1882printf(" for help use -Xaot:help\n\n");1883#endif1884return -1;1885}18861887char * endOptions = TR::Options::latePostProcessJIT(jitConfig);1888if ((intptr_t)endOptions == 1)1889return 1;18901891if (endOptions)1892{1893scan_failed(PORTLIB, "JIT", endOptions);1894printf("<JIT: fatal error, invalid command line>\n");1895#ifdef DEBUG1896printf(" for help use -Xjit:help\n\n");1897#endif1898return -1;1899}19001901if (!TR::Options::getCmdLineOptions()->allowRecompilation() || !TR::Options::getAOTCmdLineOptions()->allowRecompilation())1902{1903TR::Options::getCmdLineOptions()->setOption(TR_DisableCHOpts);1904TR::Options::getAOTCmdLineOptions()->setOption(TR_DisableCHOpts);1905}19061907// Get local var names if available (ie. classfile was compiled with -g).1908// We just check getDebug() for lack of a reliable way to check whether there are any methods being logged.1909//1910// Do this after all option processing because we don't want the option1911// processing to think the user has requested a local variable table. That1912// makes it drop into FSD mode.1913//1914if (TR::Options::getDebug())1915javaVM->requiredDebugAttributes |= J9VM_DEBUG_ATTRIBUTE_LOCAL_VARIABLE_TABLE;19161917J9VMThread *curThread = javaVM->internalVMFunctions->currentVMThread(javaVM);1918TR_J9VMBase *vm = TR_J9VMBase::get(jitConfig, curThread);1919TR::CompilationInfo * compInfo = TR::CompilationInfo::get(jitConfig);19201921/* Initialize helpers */1922codert_init_helpers_and_targets(jitConfig, TR::Compiler->target.isSMP());19231924if (vm->isAOT_DEPRECATED_DO_NOT_USE() || (jitConfig->runtimeFlags & J9JIT_TOSS_CODE))1925return 0;19261927TR::PersistentInfo *persistentInfo = compInfo->getPersistentInfo();1928#if defined(J9VM_OPT_JITSERVER)1929if (persistentInfo->getRemoteCompilationMode() != JITServer::SERVER)1930#endif /* defined(J9VM_OPT_JITSERVER) */1931{1932/* jit specific helpers */1933initializeJitRuntimeHelperTable(TR::Compiler->target.isSMP());1934}19351936#if defined(TR_TARGET_POWER)1937if (TR::Compiler->target.cpu.isPower())1938{1939void *tocBase = ppcPicTrampInit(vm, persistentInfo);1940if (tocBase == reinterpret_cast<void *>(0x1))1941{1942printf("<JIT: Cannot allocate TableOfConstants\n");1943return -1; // fail the JVM1944}19451946#if defined(TR_TARGET_64BIT) && defined(TR_HOST_POWER)1947jitConfig->pseudoTOC = tocBase;1948#endif1949}1950#endif195119521953#if defined(J9VM_OPT_SHARED_CLASSES)1954if (isSharedAOT)1955{1956bool validateSCC = true;19571958#if defined(J9VM_OPT_JITSERVER)1959if (persistentInfo->getRemoteCompilationMode() == JITServer::SERVER)1960validateSCC = false;1961#endif /* defined(J9VM_OPT_JITSERVER) */19621963if (validateSCC)1964{1965/* If AOT Shared Classes is turned ON, perform compatibility checks for AOT Shared Classes1966*1967* This check has to be done after latePostProcessJIT so that all the necessary JIT options1968* can be set1969*/1970TR_J9VMBase *fe = TR_J9VMBase::get(jitConfig, curThread);1971if (!compInfo->reloRuntime()->validateAOTHeader(fe, curThread))1972{1973TR_ASSERT_FATAL(static_cast<TR_JitPrivateConfig *>(jitConfig->privateConfig)->aotValidHeader != TR_yes,1974"aotValidHeader is TR_yes after failing to validate AOT header\n");19751976/* If this is the second run, then failing to validate AOT header will cause aotValidHeader1977* to be TR_no, in which case the SCC is not valid for use. However, if this is the first1978* run, then aotValidHeader will be TR_maybe; try to store the AOT Header in this case.1979*/1980if (static_cast<TR_JitPrivateConfig *>(jitConfig->privateConfig)->aotValidHeader == TR_no1981|| !compInfo->reloRuntime()->storeAOTHeader(fe, curThread))1982{1983static_cast<TR_JitPrivateConfig *>(jitConfig->privateConfig)->aotValidHeader = TR_no;1984TR::Options::getAOTCmdLineOptions()->setOption(TR_NoLoadAOT);1985TR::Options::getAOTCmdLineOptions()->setOption(TR_NoStoreAOT);1986TR::Options::setSharedClassCache(false);1987TR_J9SharedCache::setSharedCacheDisabledReason(TR_J9SharedCache::AOT_DISABLED);1988}1989}1990else1991{1992TR::Compiler->relocatableTarget.cpu = TR::CPU::customize(compInfo->reloRuntime()->getProcessorDescriptionFromSCC(curThread));1993jitConfig->relocatableTargetProcessor = TR::Compiler->relocatableTarget.cpu.getProcessorDescription();1994}1995}19961997if (TR::Options::getAOTCmdLineOptions()->getOption(TR_NoStoreAOT))1998{1999javaVM->sharedClassConfig->runtimeFlags &= ~J9SHR_RUNTIMEFLAG_ENABLE_AOT;2000TR_J9SharedCache::setSharedCacheDisabledReason(TR_J9SharedCache::AOT_DISABLED);2001#if defined(J9VM_OPT_JITSERVER)2002if (persistentInfo->getRemoteCompilationMode() == JITServer::SERVER)2003{2004fprintf(stderr, "Error: -Xaot:nostore option is not compatible with JITServer mode.");2005return -1;2006}2007#endif /* defined(J9VM_OPT_JITSERVER) */2008}2009else if ((javaVM->sharedClassConfig->runtimeFlags & J9SHR_RUNTIMEFLAG_ENABLE_AOT) == 0)2010{2011TR::Options::getAOTCmdLineOptions()->setOption(TR_NoStoreAOT);2012TR_J9SharedCache::setSharedCacheDisabledReason(TR_J9SharedCache::AOT_DISABLED);2013#if defined(J9VM_OPT_JITSERVER)2014if (persistentInfo->getRemoteCompilationMode() == JITServer::SERVER)2015{2016fprintf(stderr, "Error: -Xnoaot option must not be specified for JITServer.");2017return -1;2018}2019#endif /* defined(J9VM_OPT_JITSERVER) */2020}2021}2022#endif /* defined(J9VM_OPT_SHARED_CLASSES) */20232024#if defined(J9VM_OPT_JITSERVER)2025// Create AOT deserializer at the client if using JITServer with AOT cache2026if ((persistentInfo->getRemoteCompilationMode() == JITServer::CLIENT) && persistentInfo->getJITServerUseAOTCache())2027{2028if (TR::Options::sharedClassCache())2029{2030auto deserializer = new (PERSISTENT_NEW) JITServerAOTDeserializer(persistentInfo->getPersistentClassLoaderTable());2031if (!deserializer)2032return -1;2033compInfo->setJITServerAOTDeserializer(deserializer);2034}2035else2036{2037fprintf(stderr, "Disabling JITServer AOT cache since AOT compilation is disabled\n");2038persistentInfo->setJITServerUseAOTCache(false);2039}2040}2041#endif /* defined(J9VM_OPT_JITSERVER) */20422043#if defined(J9VM_OPT_CRIU_SUPPORT)2044/* If the JVM is in CRIU mode and checkpointing is allowed, then the JIT should be2045* limited to the same processor features as those used in Portable AOT mode. This2046* is because, the restore run may not be on the same machine as the one that created2047* the snapshot; thus the JIT code must be portable.2048*/2049if (javaVM->internalVMFunctions->isCheckpointAllowed(curThread))2050{2051TR::Compiler->target.cpu = TR::CPU::detectRelocatable(TR::Compiler->omrPortLib);2052jitConfig->targetProcessor = TR::Compiler->target.cpu.getProcessorDescription();2053}2054#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */20552056#if defined(TR_TARGET_S390)2057uintptr_t * tocBase = (uintptr_t *)jitConfig->pseudoTOC;20582059// Initialize the helper function table (0 to TR_S390numRuntimeHelpers-2)2060for (int32_t idx=1; idx<TR_S390numRuntimeHelpers; idx++)2061tocBase[idx-1] = (uintptr_t)runtimeHelperValue((TR_RuntimeHelper)idx);2062#endif20632064TR::CodeCacheManager::instance()->lateInitialization();20652066/* Do not set up the following hooks if we are in testmode */2067if (!(jitConfig->runtimeFlags & J9JIT_TOSS_CODE))2068{2069if (setUpHooks(javaVM, jitConfig, vm))2070return -1;2071}20722073// For RI enabled we may want to start as off and only enable when there is2074// compilation pressure2075if (persistentInfo->isRuntimeInstrumentationEnabled() &&2076TR::Options::getCmdLineOptions()->getOption(TR_UseRIOnlyForLargeQSZ))2077{2078TR_HWProfiler *hwProfiler = compInfo->getHWProfiler();2079hwProfiler->turnBufferProcessingOffTemporarily();2080}20812082UT_MODULE_LOADED(J9_UTINTERFACE_FROM_VM(javaVM));2083Trc_JIT_VMInitStages_Event1(curThread);2084Trc_JIT_portableSharedCache_enabled_or_disabled(curThread, J9_ARE_ANY_BITS_SET(javaVM->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_ENABLE_PORTABLE_SHARED_CACHE) ? 1 : 0);2085return 0;2086}208720882089// -----------------------------------------------------------------------------2090// GPU2091// -----------------------------------------------------------------------------20922093#ifdef ENABLE_GPU2094extern I_32 jitCallGPU(J9VMThread *vmThread, J9Method *method,2095char * programSource, jobject invokeObject, int deviceId,2096I_32 gridDimX, I_32 gridDimY, I_32 gridDimZ,2097I_32 blockDimX, I_32 blockDimY, I_32 blockDimZ,2098I_32 argCount, void **args);20992100IDATA launchGPU(J9VMThread *vmThread, jobject invokeObject,2101J9Method *method, int deviceId,2102I_32 gridDimX, I_32 gridDimY, I_32 gridDimZ,2103I_32 blockDimX, I_32 blockDimY, I_32 blockDimZ,2104void **args)2105{2106TR::CompilationInfo * compInfo = getCompilationInfo(jitConfig);2107bool queued = false;2108TR_MethodEvent event;2109I_32 result = 0;2110event._eventType = TR_MethodEvent::InterpreterCounterTripped;2111event._j9method = method;2112event._oldStartPC = 0;2113event._vmThread = vmThread;2114event._classNeedingThunk = 0;2115bool newPlanCreated;2116TR_OptimizationPlan *plan = TR::CompilationController::getCompilationStrategy()->processEvent(&event, &newPlanCreated);2117if (plan)2118{2119plan->setIsExplicitCompilation(true);21202121plan->setIsGPUCompilation(true);2122plan->setGPUBlockDimX(blockDimX);2123plan->setGPUParms(args);2124if (!args)2125plan->setIsGPUParallelStream(true);21262127static char *GPUCompileCPUCode = feGetEnv("TR_GPUCompileCPUCode");2128if (GPUCompileCPUCode)2129plan->setIsGPUCompileCPUCode(true);21302131// If the controller decides to compile this method, trigger the compilation and wait here21322133{ // scope for details2134TR::IlGeneratorMethodDetails details(method);21352136clock_t start = clock();2137if(!compInfo->isCompiled(method) || GPUCompileCPUCode)2138compInfo->compileMethod(vmThread, details, 0, TR_no, NULL, &queued, plan);2139clock_t end = clock();2140printf ("\tJitted Java Kernel %6.3f msec\n", (double)(end-start)*1000/CLOCKS_PER_SEC);21412142result = plan->getGPUResult();21432144if (result == 0)2145{2146J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);2147I_32 argCount = J9_ARG_COUNT_FROM_ROM_METHOD(romMethod) - 1; // for this (this is not passed to GPU)21482149if (GPUCompileCPUCode)2150{2151typedef I_32 (*gpuCodePtr)(J9VMThread *vmThread, J9Method *method,2152char * programSource, jobject invokeObject, int deviceId,2153I_32 gridDimX, I_32 gridDimY, I_32 gridDimZ,2154I_32 blockDimX, I_32 blockDimY, I_32 blockDimZ,2155I_32 argCount, void **args);21562157printf ("In launchGPU: %p %p %p %p %d %d %d %d %d %d %d %d %p\n",2158vmThread, method, plan->getGPUIR(), invokeObject, deviceId,2159gridDimX, gridDimY, gridDimZ,2160blockDimX, blockDimY, blockDimZ,2161argCount, args);216221632164gpuCodePtr gpuCode = (gpuCodePtr)TR::CompilationInfo::getJ9MethodExtra(method);21652166if ((int64_t)gpuCode != 0x1)2167result = gpuCode(vmThread, method, plan->getGPUIR(), invokeObject, deviceId,2168gridDimX, gridDimY, gridDimZ,2169blockDimX, blockDimY, blockDimZ,2170argCount, args);2171}2172else2173{2174result = jitCallGPU(vmThread, method, plan->getGPUIR(), invokeObject, deviceId,2175gridDimX, gridDimY, gridDimZ,2176blockDimX, blockDimY, blockDimZ,2177argCount, args);2178}21792180printf ("launchGPU result = %d\n", result);2181fflush(NULL);2182}2183}21842185if (!queued && newPlanCreated)2186TR_OptimizationPlan::freeOptimizationPlan(plan);2187}21882189return result;2190}219121922193static UDATA forEachIterator(J9VMThread *vmThread, J9StackWalkState *walkState)2194{2195// stop iterating if the walk state is null2196if (!walkState)2197{2198return J9_STACKWALK_STOP_ITERATING;2199}22002201J9Method *j9method = walkState->method;2202J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(j9method);22032204J9JITConfig* jitConfig = vmThread->javaVM->jitConfig;2205TR::CompilationInfo *compInfo = TR::CompilationInfo::get(jitConfig);22062207compInfo->acquireCompMonitor(vmThread);22082209intptr_t count = TR::CompilationInfo::getJ9MethodExtra(j9method) >> 1;22102211if (!(romMethod->modifiers & J9AccNative) && // Never change the extra field of a native method2212!(walkState->jitInfo) && // If the frame has jit metadata, it was already compiled2213!(TR::CompilationInfo::isCompiled(j9method)) && //If isCompiled is true it was already compiled2214!(TR::CompilationInfo::getJ9MethodVMExtra(j9method) == J9_JIT_QUEUED_FOR_COMPILATION) && //No change needed if already queued2215(count > 0)) // No change needed if count is already 02216{2217TR::CompilationInfo::setInitialInvocationCountUnsynchronized(j9method,0); //set count to 02218}22192220compInfo->releaseCompMonitor(vmThread);22212222return J9_STACKWALK_STOP_ITERATING;2223}2224#endif222522262227void promoteGPUCompile(J9VMThread *vmThread)2228{2229#ifdef ENABLE_GPU2230if (TR::Options::getCmdLineOptions()->getEnableGPU(TR_EnableGPU))2231{2232J9StackWalkState walkState;22332234walkState.walkThread = vmThread;2235walkState.skipCount = 3; //method to compile is 3 up from the forEach22362237walkState.flags = J9_STACKWALK_VISIBLE_ONLY |2238J9_STACKWALK_INCLUDE_NATIVES |2239J9_STACKWALK_ITERATE_FRAMES;2240walkState.frameWalkFunction = forEachIterator;22412242vmThread->javaVM->walkStackFrames(vmThread, &walkState);2243}2244#endif2245}224622472248