Path: blob/master/runtime/compiler/control/JITClientCompilationThread.cpp
6000 views
/*******************************************************************************1* Copyright (c) 2019, 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 "codegen/CodeGenerator.hpp"23#include "codegen/PicHelpers.hpp"24#include "control/CompilationRuntime.hpp"25#include "control/CompilationThread.hpp"26#include "control/JITServerHelpers.hpp"27#include "control/MethodToBeCompiled.hpp"28#include "env/ClassTableCriticalSection.hpp"29#include "env/J2IThunk.hpp"30#include "env/j9methodServer.hpp"31#include "env/JITServerPersistentCHTable.hpp"32#include "env/ut_j9jit.h"33#include "env/VMAccessCriticalSection.hpp"34#include "env/VMJ9.h"35#include "env/VerboseLog.hpp"36#include "net/ClientStream.hpp"37#include "optimizer/TransformUtil.hpp"38#include "runtime/CodeCacheExceptions.hpp"39#include "runtime/CodeCache.hpp"40#include "runtime/CodeCacheManager.hpp"41#include "runtime/J9VMAccess.hpp"42#include "runtime/JITClientSession.hpp"43#include "runtime/JITServerAOTDeserializer.hpp"44#include "runtime/JITServerIProfiler.hpp"45#include "runtime/RelocationTarget.hpp"46#include "env/TypeLayout.hpp"47#include "env/JSR292Methods.h"48#include "jitprotos.h"49#include "vmaccess.h"505152extern TR::Monitor *assumptionTableMutex;5354// TODO: This method is copied from runtime/jit_vm/ctsupport.c,55// in the future it's probably better to make that method publicly accessible56static UDATA57findField(J9VMThread *vmStruct, J9ConstantPool *constantPool, UDATA index, BOOLEAN isStatic, J9Class **declaringClass)58{59J9JavaVM *javaVM = vmStruct->javaVM;60J9ROMFieldRef *romRef;61J9ROMClassRef *classRef; /* ROM class of the field */62U_32 classRefCPIndex;63J9UTF8 *classNameUTF;64J9Class *clazz;65UDATA result = 0;6667*declaringClass = NULL;68romRef = (J9ROMFieldRef*) &(((J9ROMConstantPoolItem*) constantPool->romConstantPool)[index]);69classRefCPIndex = romRef->classRefCPIndex;70classRef = (J9ROMClassRef*) &(((J9ROMConstantPoolItem*) constantPool->romConstantPool)[classRefCPIndex]);71classNameUTF = J9ROMCLASSREF_NAME(classRef);72clazz = javaVM->internalVMFunctions->internalFindClassUTF8(vmStruct, J9UTF8_DATA(classNameUTF),73J9UTF8_LENGTH(classNameUTF), constantPool->ramClass->classLoader, J9_FINDCLASS_FLAG_EXISTING_ONLY);74if (NULL != clazz)75{76J9ROMNameAndSignature *nameAndSig = J9ROMFIELDREF_NAMEANDSIGNATURE(romRef);77J9UTF8 *signature = J9ROMNAMEANDSIGNATURE_SIGNATURE(nameAndSig);78J9UTF8 *name = J9ROMNAMEANDSIGNATURE_NAME(nameAndSig);7980if (!isStatic)81{82UDATA instanceField;83IDATA offset = javaVM->internalVMFunctions->instanceFieldOffset(84vmStruct, clazz, J9UTF8_DATA(name),85J9UTF8_LENGTH(name), J9UTF8_DATA(signature), J9UTF8_LENGTH(signature), declaringClass,86&instanceField, J9_LOOK_NO_JAVA);8788if (-1 != offset)89{90result = instanceField;91}92}93else94{95UDATA staticField;96void * addr = javaVM->internalVMFunctions->staticFieldAddress(97vmStruct, clazz, J9UTF8_DATA(name),98J9UTF8_LENGTH(name), J9UTF8_DATA(signature), J9UTF8_LENGTH(signature), declaringClass,99&staticField, J9_LOOK_NO_JAVA, NULL);100101if (NULL != addr)102{103result = staticField;104}105}106}107return result;108}109110static void111handler_IProfiler_profilingSample(JITServer::ClientStream *client, TR_J9VM *fe, TR::Compilation *comp)112{113auto recv = client->getRecvData<TR_OpaqueMethodBlock*, uint32_t, uintptr_t>();114auto method = std::get<0>(recv);115auto bcIndex = std::get<1>(recv);116auto data = std::get<2>(recv); // data==1 means 'send info for 1 bytecode'; data==0 means 'send info for entire method if possible'117118JITClientIProfiler *iProfiler = (JITClientIProfiler *)fe->getIProfiler();119120bool isCompiled = TR::CompilationInfo::isCompiled((J9Method*)method);121bool isInProgress = comp->getMethodBeingCompiled()->getPersistentIdentifier() == method;122bool abort = false;123// Used to tell the server if a profiled entry should be stored in persistent or heap memory124bool usePersistentCache = isCompiled || isInProgress;125bool wholeMethodInfo = data == 0;126127if (wholeMethodInfo)128{129// Serialize all the information related to this method130abort = iProfiler->serializeAndSendIProfileInfoForMethod(method, comp, client, usePersistentCache, isCompiled);131}132if (!wholeMethodInfo || abort) // Send information just for this entry133{134auto entry = iProfiler->profilingSample(method, bcIndex, comp, data, false);135if (entry && !entry->isInvalid())136{137uint32_t canPersist = entry->canBeSerialized(comp->getPersistentInfo()); // This may lock the entry138if (canPersist == IPBC_ENTRY_CAN_PERSIST)139{140uint32_t bytes = entry->getBytesFootprint();141std::string entryBytes(bytes, '\0');142auto storage = (TR_IPBCDataStorageHeader*)&entryBytes[0];143uintptr_t methodStartAddress = (uintptr_t)TR::Compiler->mtd.bytecodeStart(method);144entry->serialize(methodStartAddress, storage, comp->getPersistentInfo());145client->write(JITServer::MessageType::IProfiler_profilingSample, entryBytes, false, usePersistentCache, isCompiled);146}147else148{149client->write(JITServer::MessageType::IProfiler_profilingSample, std::string(), false, usePersistentCache, isCompiled);150}151// Unlock the entry152if (auto callGraphEntry = entry->asIPBCDataCallGraph())153if (canPersist != IPBC_ENTRY_PERSIST_LOCK && callGraphEntry->isLocked())154callGraphEntry->releaseEntry();155}156else // No valid info for specified bytecode index157{158client->write(JITServer::MessageType::IProfiler_profilingSample, std::string(), false, usePersistentCache, isCompiled);159}160}161}162163static bool164handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::MessageType &response)165{166using JITServer::MessageType;167TR::CompilationInfoPerThread *compInfoPT = fe->_compInfoPT;168J9VMThread *vmThread = compInfoPT->getCompilationThread();169TR_Memory *trMemory = compInfoPT->getCompilation()->trMemory();170TR::Compilation *comp = compInfoPT->getCompilation();171TR::CompilationInfo *compInfo = compInfoPT->getCompilationInfo();172173TR_ASSERT(TR::MonitorTable::get()->getClassUnloadMonitorHoldCount(compInfoPT->getCompThreadId()) == 0, "Must not hold classUnloadMonitor");174TR::MonitorTable *table = TR::MonitorTable::get();175TR_ASSERT(table && table->isThreadInSafeMonitorState(vmThread), "Must not hold any monitors when waiting for server");176177response = client->read();178179// Acquire VM access and check for possible class unloading180acquireVMAccessNoSuspend(vmThread);181182// Update statistics for server message type183JITServerHelpers::serverMsgTypeCount[response] += 1;184185// If JVM has unloaded classes inform the server to abort this compilation186uint8_t interruptReason = compInfoPT->compilationShouldBeInterrupted();187if (interruptReason && response != MessageType::jitDumpPrintIL)188{189// Inform the server if compilation is not yet complete190if ((response != MessageType::compilationCode) &&191(response != MessageType::compilationFailure))192client->writeError(JITServer::MessageType::compilationInterrupted, 0 /* placeholder */);193194if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompilationDispatch))195TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE, "Interrupting remote compilation (interruptReason %u) in handleServerMessage(%s) for %s @ %s",196interruptReason, JITServer::messageNames[response], comp->signature(), comp->getHotnessName());197198Trc_JITServerInterruptRemoteCompile(vmThread, interruptReason, JITServer::messageNames[response], comp->signature(), comp->getHotnessName());199comp->failCompilation<TR::CompilationInterrupted>("Compilation interrupted in handleServerMessage");200}201202TR::KnownObjectTable *knot = comp->getOrCreateKnownObjectTable();203204bool done = false;205switch (response)206{207case MessageType::compilationCode:208case MessageType::compilationFailure:209case MessageType::compilationThreadCrashed:210done = true;211break;212case MessageType::jitDumpPrintIL:213{214client->getRecvData<JITServer::Void>();215done = true;216client->write(response, JITServer::Void());217}218break;219case MessageType::getUnloadedClassRangesAndCHTable:220{221uint64_t serverUID = std::get<0>(client->getRecvData<uint64_t>());222uint64_t previousUID = compInfo->getPersistentInfo()->getServerUID();223compInfo->getPersistentInfo()->setServerUID(serverUID);224225auto unloadedClasses = comp->getPersistentInfo()->getUnloadedClassAddresses();226std::vector<TR_AddressRange> ranges;227ranges.reserve(unloadedClasses->getNumberOfRanges());228{229OMR::CriticalSection getAddressSetRanges(assumptionTableMutex);230unloadedClasses->getRanges(ranges);231}232// Add the entire CHTable as well233auto table = (JITClientPersistentCHTable *)comp->getPersistentInfo()->getPersistentCHTable();234std::string serializedCHTable = FlatPersistentClassInfo::serializeHierarchy(table);235236{237OMR::CriticalSection romClassCache(compInfo->getclassesCachedAtServerMonitor());238compInfo->getclassesCachedAtServer().clear();239}240241auto deserializer = compInfo->getJITServerAOTDeserializer();242// Reset AOT deserializer if connected to a new server (cached serialization records are now invalid)243if (deserializer && (previousUID != serverUID))244deserializer->reset();245246client->write(response, ranges, unloadedClasses->getMaxRanges(), serializedCHTable);247248if ((previousUID != serverUID) && TR::Options::getVerboseOption(TR_VerboseJITServerConns))249{250TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "t=%6u Connected to a server (serverUID=%llu)",251(uint32_t)compInfo->getPersistentInfo()->getElapsedTime(),252(unsigned long long)serverUID);253}254}255break;256case MessageType::VM_isClassLibraryClass:257{258bool rv = fe->isClassLibraryClass(std::get<0>(client->getRecvData<TR_OpaqueClassBlock*>()));259client->write(response, rv);260}261break;262case MessageType::VM_isClassLibraryMethod:263{264auto tup = client->getRecvData<TR_OpaqueMethodBlock*, bool>();265bool rv = fe->isClassLibraryMethod(std::get<0>(tup), std::get<1>(tup));266client->write(response, rv);267}268break;269case MessageType::VM_getSystemClassFromClassName:270{271auto recv = client->getRecvData<std::string, bool>();272const std::string name = std::get<0>(recv);273bool isVettedForAOT = std::get<1>(recv);274// Always need non-AOT front-end here, since class validation is done on the server275TR_J9VMBase *fej9 = TR_J9VMBase::get(vmThread->javaVM->jitConfig, vmThread);276client->write(response, fej9->getSystemClassFromClassName(name.c_str(), name.length(), isVettedForAOT));277}278break;279case MessageType::VM_isMethodTracingEnabled:280{281auto method = std::get<0>(client->getRecvData<TR_OpaqueMethodBlock *>());282client->write(response, fe->isMethodTracingEnabled(method));283}284break;285case MessageType::VM_getClassClassPointer:286{287auto clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock*>());288client->write(response, fe->getClassClassPointer(clazz));289}290break;291case MessageType::VM_getClassOfMethod:292{293auto method = std::get<0>(client->getRecvData<TR_OpaqueMethodBlock*>());294client->write(response, fe->getClassOfMethod(method));295}296break;297case MessageType::VM_getClassFromSignature:298{299// Need to get a non-AOT frontend because the AOT frontend also300// performs some class validation which we want to do at the server301TR_J9VMBase *fej9 = TR_J9VMBase::get(vmThread->javaVM->jitConfig, vmThread);302auto recv = client->getRecvData<std::string, TR_OpaqueMethodBlock *, bool>();303std::string sig = std::get<0>(recv);304auto method = std::get<1>(recv);305bool isVettedForAOT = std::get<2>(recv);306auto clazz = fej9->getClassFromSignature(sig.c_str(), sig.length(), method, isVettedForAOT);307J9ClassLoader *cl = clazz ? reinterpret_cast<J9ClassLoader *>(fej9->getClassLoader(clazz)) : NULL;308J9ClassLoader *methodCL = reinterpret_cast<J9ClassLoader *>(fej9->getClassLoader(fej9->getClassOfMethod(method)));309client->write(response, clazz, cl, methodCL);310}311break;312case MessageType::VM_jitFieldsOrStaticsAreSame:313{314auto recv = client->getRecvData<TR_ResolvedMethod*, int32_t, TR_ResolvedMethod *, int32_t, int32_t>();315TR_ResolvedMethod *method1 = std::get<0>(recv);316int32_t cpIndex1 = std::get<1>(recv);317TR_ResolvedMethod *method2 = std::get<2>(recv);318int32_t cpIndex2 = std::get<3>(recv);319int32_t isStatic = std::get<4>(recv);320bool identical = false;321UDATA f1 = 0, f2 = 0;322J9Class *declaringClass1 = NULL, *declaringClass2 = NULL;323J9ConstantPool *cp1 = (J9ConstantPool *) method1->ramConstantPool();324J9ConstantPool *cp2 = (J9ConstantPool *) method2->ramConstantPool();325326f1 = findField(fe->vmThread(), cp1, cpIndex1, isStatic, &declaringClass1);327f2 = findField(fe->vmThread(), cp2, cpIndex2, isStatic, &declaringClass2);328client->write(response, declaringClass1, declaringClass2, f1, f2);329};330break;331case MessageType::VM_compiledAsDLTBefore:332{333auto clazz = std::get<0>(client->getRecvData<TR_ResolvedMethod *>());334client->write(response, fe->compiledAsDLTBefore(clazz));335}336break;337case MessageType::VM_classHasBeenExtended:338{339auto clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());340client->write(response, fe->classHasBeenExtended(clazz));341}342break;343case MessageType::VM_isThunkArchetype:344{345J9Method *method = std::get<0>(client->getRecvData<J9Method *>());346client->write(response, fe->isThunkArchetype(method));347}348break;349case MessageType::VM_printTruncatedSignature:350{351J9Method *method = (J9Method *) std::get<0>(client->getRecvData<TR_OpaqueMethodBlock *>());352J9UTF8 * className;353J9UTF8 * name;354J9UTF8 * signature;355getClassNameSignatureFromMethod(method, className, name, signature);356std::string classNameStr(utf8Data(className), J9UTF8_LENGTH(className));357std::string nameStr(utf8Data(name), J9UTF8_LENGTH(name));358std::string signatureStr(utf8Data(signature), J9UTF8_LENGTH(signature));359client->write(response, classNameStr, nameStr, signatureStr);360}361break;362case MessageType::VM_getStaticHookAddress:363{364int32_t event = std::get<0>(client->getRecvData<int32_t>());365client->write(response, fe->getStaticHookAddress(event));366}367break;368case MessageType::VM_isClassInitialized:369{370TR_OpaqueClassBlock *clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());371client->write(response, fe->isClassInitialized(clazz));372}373break;374case MessageType::VM_getOSRFrameSizeInBytes:375{376TR_OpaqueMethodBlock *method = std::get<0>(client->getRecvData<TR_OpaqueMethodBlock *>());377client->write(response, fe->getOSRFrameSizeInBytes(method));378}379break;380case MessageType::VM_getInitialLockword:381{382TR_OpaqueClassBlock *clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());383client->write(response, fe->getInitialLockword(clazz));384}385break;386case MessageType::VM_JavaStringObject:387{388client->getRecvData<JITServer::Void>();389client->write(response, (TR_OpaqueClassBlock *)J9VMJAVALANGSTRING(vmThread->javaVM));390}391break;392case MessageType::VM_getMethods:393{394TR_OpaqueClassBlock *clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());395client->write(response, fe->getMethods(clazz));396}397break;398case MessageType::VM_getResolvedMethodsAndMirror:399{400TR_OpaqueClassBlock *clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());401uint32_t numMethods = fe->getNumMethods(clazz);402J9Method *methods = (J9Method *) fe->getMethods(clazz);403404// Create mirrors and put methodInfo for each method in a vector to be sent to the server405std::vector<TR_ResolvedJ9JITServerMethodInfo> methodsInfo;406methodsInfo.reserve(numMethods);407for (int i = 0; i < numMethods; ++i)408{409TR_ResolvedJ9JITServerMethodInfo methodInfo;410TR_ResolvedJ9JITServerMethod::createResolvedMethodMirror(methodInfo, (TR_OpaqueMethodBlock *) &(methods[i]), 0, 0, fe, trMemory);411methodsInfo.push_back(methodInfo);412}413client->write(response, methods, methodsInfo);414}415break;416case MessageType::VM_getVMInfo:417{418ClientSessionData::VMInfo vmInfo = {};419J9JavaVM * javaVM = vmThread->javaVM;420vmInfo._systemClassLoader = fe->getSystemClassLoader();421vmInfo._processID = fe->getProcessID();422vmInfo._canMethodEnterEventBeHooked = fe->canMethodEnterEventBeHooked();423vmInfo._canMethodExitEventBeHooked = fe->canMethodExitEventBeHooked();424vmInfo._canExceptionEventBeHooked = fe->canExceptionEventBeHooked();425vmInfo._usesDiscontiguousArraylets = TR::Compiler->om.usesDiscontiguousArraylets();426vmInfo._isIProfilerEnabled = fe->getIProfiler();427vmInfo._arrayletLeafLogSize = TR::Compiler->om.arrayletLeafLogSize();428vmInfo._arrayletLeafSize = TR::Compiler->om.arrayletLeafSize();429vmInfo._overflowSafeAllocSize = static_cast<uint64_t>(fe->getOverflowSafeAllocSize());430vmInfo._compressedReferenceShift = TR::Compiler->om.compressedReferenceShift();431vmInfo._j9SharedClassCacheDescriptorList = NULL;432vmInfo._stringCompressionEnabled = fe->isStringCompressionEnabledVM();433vmInfo._hasSharedClassCache = TR::Options::sharedClassCache();434vmInfo._elgibleForPersistIprofileInfo = vmInfo._isIProfilerEnabled ? fe->getIProfiler()->elgibleForPersistIprofileInfo(comp) : false;435vmInfo._reportByteCodeInfoAtCatchBlock = comp->getOptions()->getReportByteCodeInfoAtCatchBlock();436for (int32_t i = 0; i <= 7; i++)437{438vmInfo._arrayTypeClasses[i] = fe->getClassFromNewArrayTypeNonNull(i + 4);439}440vmInfo._byteArrayClass = fe->getByteArrayClass();441vmInfo._readBarrierType = TR::Compiler->om.readBarrierType();442vmInfo._writeBarrierType = TR::Compiler->om.writeBarrierType();443vmInfo._compressObjectReferences = TR::Compiler->om.compressObjectReferences();444vmInfo._processorDescription = TR::Compiler->target.cpu.getProcessorDescription();445vmInfo._noTypeInvokeExactThunkHelper = comp->getSymRefTab()->findOrCreateRuntimeHelper(TR_icallVMprJavaSendInvokeExact0)->getMethodAddress();446vmInfo._int64InvokeExactThunkHelper = comp->getSymRefTab()->findOrCreateRuntimeHelper(TR_icallVMprJavaSendInvokeExactJ)->getMethodAddress();447vmInfo._int32InvokeExactThunkHelper = comp->getSymRefTab()->findOrCreateRuntimeHelper(TR_icallVMprJavaSendInvokeExact1)->getMethodAddress();448vmInfo._addressInvokeExactThunkHelper = comp->getSymRefTab()->findOrCreateRuntimeHelper(TR_icallVMprJavaSendInvokeExactL)->getMethodAddress();449vmInfo._floatInvokeExactThunkHelper = comp->getSymRefTab()->findOrCreateRuntimeHelper(TR_icallVMprJavaSendInvokeExactF)->getMethodAddress();450vmInfo._doubleInvokeExactThunkHelper = comp->getSymRefTab()->findOrCreateRuntimeHelper(TR_icallVMprJavaSendInvokeExactD)->getMethodAddress();451vmInfo._interpreterVTableOffset = TR::Compiler->vm.getInterpreterVTableOffset();452vmInfo._maxHeapSizeInBytes = TR::Compiler->vm.maxHeapSizeInBytes();453vmInfo._enableGlobalLockReservation = vmThread->javaVM->enableGlobalLockReservation;454fe->getNurserySpaceBounds(&vmInfo._nurserySpaceBoundsBase, &vmInfo._nurserySpaceBoundsTop);455vmInfo._lowTenureAddress = fe->getLowTenureAddress();456vmInfo._highTenureAddress = fe->getHighTenureAddress();457458{459TR::VMAccessCriticalSection getVMInfo(fe);460vmInfo._jlrMethodInvoke = javaVM->jlrMethodInvoke;461#if defined(J9VM_OPT_SIDECAR)462if (javaVM->srMethodAccessor != NULL)463vmInfo._srMethodAccessorClass = (TR_OpaqueClassBlock *) J9VM_J9CLASS_FROM_JCLASS(vmThread, javaVM->srMethodAccessor);464else465vmInfo._srMethodAccessorClass = NULL;466if (javaVM->srConstructorAccessor != NULL)467vmInfo._srConstructorAccessorClass = (TR_OpaqueClassBlock *) J9VM_J9CLASS_FROM_JCLASS(vmThread, javaVM->srConstructorAccessor);468else469vmInfo._srConstructorAccessorClass = NULL;470#endif // J9VM_OPT_SIDECAR471vmInfo._extendedRuntimeFlags2 = javaVM->extendedRuntimeFlags2;472#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)473// These offsets are initialized later on474vmInfo._vmtargetOffset = 0;475vmInfo._vmindexOffset = 0;476#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */477}478479// For multi-layered SCC support480std::vector<ClientSessionData::CacheDescriptor> listOfCacheDescriptors;481if (fe->sharedCache() && fe->sharedCache()->getCacheDescriptorList())482{483// The cache descriptor list is linked last to first and is circular, so last->previous == first.484J9SharedClassCacheDescriptor *head = fe->sharedCache()->getCacheDescriptorList();485J9SharedClassCacheDescriptor *curCache = head;486do487{488ClientSessionData::CacheDescriptor cacheDesc =489{490(uintptr_t)curCache->cacheStartAddress,491curCache->cacheSizeBytes,492(uintptr_t)curCache->romclassStartAddress,493(uintptr_t)curCache->metadataStartAddress494};495listOfCacheDescriptors.push_back(cacheDesc);496curCache = curCache->next;497}498while (curCache != head);499}500501#if defined(TR_HOST_POWER)502for (int32_t i = 0; i < TR_numRuntimeHelpers; ++i)503vmInfo._helperAddresses[i] = runtimeHelperValue((TR_RuntimeHelper) i);504#endif505vmInfo._isHotReferenceFieldRequired = TR::Compiler->om.isHotReferenceFieldRequired();506vmInfo._osrGlobalBufferSize = javaVM->osrGlobalBufferSize;507vmInfo._needsMethodTrampolines = TR::CodeCacheManager::instance()->codeCacheConfig().needsMethodTrampolines();508vmInfo._objectAlignmentInBytes = TR::Compiler->om.getObjectAlignmentInBytes();509vmInfo._isGetImplInliningSupported = fe->isGetImplInliningSupported();510vmInfo._isAllocateZeroedTLHPagesEnabled = fe->tlhHasBeenCleared();511vmInfo._staticObjectAllocateFlags = fe->getStaticObjectFlags();512vmInfo._referenceArrayCopyHelperAddress = fe->getReferenceArrayCopyHelperAddress();513vmInfo._JavaLangObject = (TR_OpaqueClassBlock*)J9VMJAVALANGOBJECT(vmThread->javaVM);514vmInfo._JavaStringObject = (TR_OpaqueClassBlock*)J9VMJAVALANGSTRING(vmThread->javaVM);515516vmInfo._useAOTCache = comp->getPersistentInfo()->getJITServerUseAOTCache();517if (vmInfo._useAOTCache)518{519auto header = compInfoPT->reloRuntime()->getStoredAOTHeader(vmThread);520TR_ASSERT_FATAL(header, "Must have valid AOT header stored in SCC by now");521vmInfo._aotHeader = *header;522}523524client->write(response, vmInfo, listOfCacheDescriptors, comp->getPersistentInfo()->getJITServerAOTCacheName());525}526break;527case MessageType::VM_getObjectClass:528{529TR::VMAccessCriticalSection getObjectClass(fe);530uintptr_t objectPointer = std::get<0>(client->getRecvData<uintptr_t>());531client->write(response, fe->getObjectClass(objectPointer));532}533break;534case MessageType::VM_getObjectClassAt:535{536uintptr_t objectAddress = std::get<0>(client->getRecvData<uintptr_t>());537client->write(response, fe->getObjectClassAt(objectAddress));538}539break;540case MessageType::VM_getObjectClassFromKnownObjectIndex:541{542auto recv = client->getRecvData<TR::KnownObjectTable::Index>();543auto idx = std::get<0>(recv);544client->write(response, fe->getObjectClassFromKnownObjectIndex(comp, idx));545}546break;547case MessageType::VM_getStaticReferenceFieldAtAddress:548{549TR::VMAccessCriticalSection getStaticReferenceFieldAtAddress(fe);550uintptr_t fieldAddress = std::get<0>(client->getRecvData<uintptr_t>());551client->write(response, fe->getStaticReferenceFieldAtAddress(fieldAddress));552}553break;554case MessageType::VM_stackWalkerMaySkipFrames:555{556client->getRecvData<JITServer::Void>();557client->write(response,558vmThread->javaVM->jlrMethodInvoke,559vmThread->javaVM->srMethodAccessor ? (TR_OpaqueClassBlock *) J9VM_J9CLASS_FROM_JCLASS(vmThread, vmThread->javaVM->srMethodAccessor) : NULL,560vmThread->javaVM->srConstructorAccessor ? (TR_OpaqueClassBlock *) J9VM_J9CLASS_FROM_JCLASS(vmThread, vmThread->javaVM->srConstructorAccessor) : NULL);561}562break;563case MessageType::VM_stackWalkerMaySkipFramesSVM:564{565auto recv = client->getRecvData<TR_OpaqueMethodBlock*, TR_OpaqueClassBlock*>();566TR_OpaqueMethodBlock *method = std::get<0>(recv);567TR_OpaqueClassBlock *clazz = std::get<1>(recv);568client->write(response, fe->stackWalkerMaySkipFrames(method, clazz));569}570break;571case MessageType::VM_getStringUTF8Length:572{573uintptr_t string = std::get<0>(client->getRecvData<uintptr_t>());574{575TR::VMAccessCriticalSection getStringUTF8Length(fe);576client->write(response, fe->getStringUTF8Length(string));577}578}579break;580case MessageType::VM_classInitIsFinished:581{582TR_OpaqueClassBlock *clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());583client->write(response, fe->classInitIsFinished(clazz));584}585break;586case MessageType::VM_getClassFromNewArrayType:587{588int32_t index = std::get<0>(client->getRecvData<int32_t>());589client->write(response, fe->getClassFromNewArrayType(index));590}591break;592case MessageType::VM_getArrayClassFromComponentClass:593{594auto clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());595client->write(response, fe->getArrayClassFromComponentClass(clazz));596}597break;598case MessageType::VM_matchRAMclassFromROMclass:599{600J9ROMClass *clazz = std::get<0>(client->getRecvData<J9ROMClass *>());601client->write(response, fe->matchRAMclassFromROMclass(clazz, comp));602}603break;604case MessageType::VM_getReferenceFieldAtAddress:605{606TR::VMAccessCriticalSection getReferenceFieldAtAddress(fe);607uintptr_t fieldAddress = std::get<0>(client->getRecvData<uintptr_t>());608client->write(response, fe->getReferenceFieldAtAddress(fieldAddress));609}610break;611case MessageType::VM_getReferenceFieldAt:612{613auto recv = client->getRecvData<uintptr_t, uintptr_t>();614uintptr_t objectPointer = std::get<0>(recv);615uintptr_t fieldOffset = std::get<1>(recv);616client->write(response, fe->getReferenceFieldAt(objectPointer, fieldOffset));617}618break;619case MessageType::VM_getVolatileReferenceFieldAt:620{621auto recv = client->getRecvData<uintptr_t, uintptr_t>();622uintptr_t objectPointer = std::get<0>(recv);623uintptr_t fieldOffset = std::get<1>(recv);624client->write(response, fe->getVolatileReferenceFieldAt(objectPointer, fieldOffset));625}626break;627case MessageType::VM_getInt32FieldAt:628{629auto recv = client->getRecvData<uintptr_t, uintptr_t>();630uintptr_t objectPointer = std::get<0>(recv);631uintptr_t fieldOffset = std::get<1>(recv);632TR::VMAccessCriticalSection getInt32FieldAt(fe);633client->write(response, fe->getInt32FieldAt(objectPointer, fieldOffset));634}635break;636case MessageType::VM_getInt64FieldAt:637{638auto recv = client->getRecvData<uintptr_t, uintptr_t>();639uintptr_t objectPointer = std::get<0>(recv);640uintptr_t fieldOffset = std::get<1>(recv);641TR::VMAccessCriticalSection getInt64FieldAt(fe);642client->write(response, fe->getInt64FieldAt(objectPointer, fieldOffset));643}644break;645case MessageType::VM_setInt64FieldAt:646{647auto recv = client->getRecvData<uintptr_t, uintptr_t, int64_t>();648uintptr_t objectPointer = std::get<0>(recv);649uintptr_t fieldOffset = std::get<1>(recv);650int64_t newValue = std::get<2>(recv);651fe->setInt64FieldAt(objectPointer, fieldOffset, newValue);652client->write(response, JITServer::Void());653}654break;655case MessageType::VM_compareAndSwapInt64FieldAt:656{657auto recv = client->getRecvData<uintptr_t, uintptr_t, int64_t, int64_t>();658uintptr_t objectPointer = std::get<0>(recv);659uintptr_t fieldOffset = std::get<1>(recv);660int64_t oldValue = std::get<2>(recv);661int64_t newValue = std::get<3>(recv);662client->write(response, fe->compareAndSwapInt64FieldAt(objectPointer, fieldOffset, oldValue, newValue));663}664break;665case MessageType::VM_getArrayLengthInElements:666{667uintptr_t objectPointer = std::get<0>(client->getRecvData<uintptr_t>());668TR::VMAccessCriticalSection getArrayLengthInElements(fe);669client->write(response, fe->getArrayLengthInElements(objectPointer));670}671break;672case MessageType::VM_getClassFromJavaLangClass:673{674uintptr_t objectPointer = std::get<0>(client->getRecvData<uintptr_t>());675client->write(response, fe->getClassFromJavaLangClass(objectPointer));676}677break;678case MessageType::VM_getOffsetOfClassFromJavaLangClassField:679{680client->getRecvData<JITServer::Void>();681client->write(response, fe->getOffsetOfClassFromJavaLangClassField());682}683break;684case MessageType::VM_getIdentityHashSaltPolicy:685{686client->getRecvData<JITServer::Void>();687client->write(response, fe->getIdentityHashSaltPolicy());688}689break;690case MessageType::VM_getOffsetOfJLThreadJ9Thread:691{692client->getRecvData<JITServer::Void>();693client->write(response, fe->getOffsetOfJLThreadJ9Thread());694}695break;696case MessageType::VM_scanReferenceSlotsInClassForOffset:697{698auto recv = client->getRecvData<TR_OpaqueClassBlock *, int32_t>();699TR_OpaqueClassBlock *clazz = std::get<0>(recv);700int32_t offset = std::get<1>(recv);701client->write(response, fe->scanReferenceSlotsInClassForOffset(comp, clazz, offset));702}703break;704case MessageType::VM_findFirstHotFieldTenuredClassOffset:705{706TR_OpaqueClassBlock *clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());707client->write(response, fe->findFirstHotFieldTenuredClassOffset(comp, clazz));708}709break;710case MessageType::VM_getResolvedVirtualMethod:711{712auto recv = client->getRecvData<TR_OpaqueClassBlock *, I_32, bool>();713auto clazz = std::get<0>(recv);714auto offset = std::get<1>(recv);715auto ignoreRTResolve = std::get<2>(recv);716client->write(response, fe->getResolvedVirtualMethod(clazz, offset, ignoreRTResolve));717}718break;719case MessageType::VM_getJ2IThunk:720{721auto recv = client->getRecvData<std::string>();722std::string signature = std::get<0>(recv);723client->write(response, fe->getJ2IThunk(&signature[0], signature.size(), comp));724}725break;726case MessageType::VM_setJ2IThunk:727{728auto recv = client->getRecvData<std::string, std::string>();729std::string signature = std::get<0>(recv);730std::string serializedThunk = std::get<1>(recv);731732void *thunkAddress;733if (!comp->compileRelocatableCode())734{735// For non-AOT, copy thunk to code cache and relocate the vm helper address right away736uint8_t *thunkStart = TR_JITServerRelocationRuntime::copyDataToCodeCache(serializedThunk.data(), serializedThunk.size(), fe);737if (!thunkStart)738compInfoPT->getCompilation()->failCompilation<TR::CodeCacheError>("Failed to allocate space in the code cache");739740thunkAddress = thunkStart + 8;741void *vmHelper = j9ThunkVMHelperFromSignature(fe->_jitConfig, signature.size(), &signature[0]);742compInfoPT->reloRuntime()->reloTarget()->performThunkRelocation(reinterpret_cast<uint8_t *>(thunkAddress), (UDATA)vmHelper);743}744else745{746// For AOT, set address to received string, because it will be stored to SCC, so747// no need for code cache allocation748thunkAddress = reinterpret_cast<void *>(&serializedThunk[0] + 8);749}750751// Ideally, should use signature.data() here, but setJ2IThunk has non-const pointer752// as argument, and it uses it to invoke a VM function that also takes non-const pointer.753thunkAddress = fe->setJ2IThunk(&signature[0], signature.size(), thunkAddress, comp);754755client->write(response, thunkAddress);756}757break;758case MessageType::VM_needsInvokeExactJ2IThunk:759{760auto recv = client->getRecvData<std::string>();761std::string signature = std::get<0>(recv);762763TR_J2IThunkTable *thunkTable = comp->getPersistentInfo()->getInvokeExactJ2IThunkTable();764// Ideally, should use signature.data() here, but findThunk takes non-const pointer765TR_J2IThunk *thunk = thunkTable->findThunk(&signature[0], fe);766client->write(response, thunk == NULL);767}768break;769case MessageType::VM_setInvokeExactJ2IThunk:770{771auto recv = client->getRecvData<std::string>();772std::string &serializedThunk = std::get<0>(recv);773774// Do not need relocation here, because helper address should have been originally775// fetched from the client.776uint8_t *thunkStart = TR_JITServerRelocationRuntime::copyDataToCodeCache(serializedThunk.data(), serializedThunk.size(), fe);777if (!thunkStart)778compInfoPT->getCompilation()->failCompilation<TR::CodeCacheError>("Failed to allocate space in the code cache");779780void *thunkAddress = reinterpret_cast<void *>(thunkStart);781fe->setInvokeExactJ2IThunk(thunkAddress, comp);782client->write(response, JITServer::Void());783}784break;785case MessageType::VM_getInstanceFieldOffset:786{787auto recv = client->getRecvData<TR_OpaqueClassBlock *, std::string, std::string, UDATA>();788TR_OpaqueClassBlock *clazz = std::get<0>(recv);789std::string field = std::get<1>(recv);790std::string sig = std::get<2>(recv);791UDATA options = std::get<3>(recv);792client->write(response, fe->getInstanceFieldOffset(clazz, const_cast<char*>(field.c_str()), field.length(),793const_cast<char*>(sig.c_str()), sig.length(), options));794}795break;796case MessageType::VM_getJavaLangClassHashCode:797{798TR_OpaqueClassBlock *clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());799bool hashCodeComputed = false;800int32_t hashCode = fe->getJavaLangClassHashCode(comp, clazz, hashCodeComputed);801client->write(response, hashCode, hashCodeComputed);802}803break;804case MessageType::VM_getClassDepthAndFlagsValue:805{806TR_OpaqueClassBlock *clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());807client->write(response, fe->getClassDepthAndFlagsValue(clazz));808}809break;810case MessageType::VM_getMethodFromName:811{812auto recv = client->getRecvData<std::string, std::string, std::string>();813std::string className = std::get<0>(recv);814std::string methodName = std::get<1>(recv);815std::string signature = std::get<2>(recv);816client->write(response, fe->getMethodFromName(const_cast<char*>(className.c_str()),817const_cast<char*>(methodName.c_str()), const_cast<char*>(signature.c_str())));818}819break;820case MessageType::VM_getMethodFromClass:821{822auto recv = client->getRecvData<TR_OpaqueClassBlock *, std::string, std::string, TR_OpaqueClassBlock *>();823TR_OpaqueClassBlock *methodClass = std::get<0>(recv);824std::string methodName = std::get<1>(recv);825std::string signature = std::get<2>(recv);826TR_OpaqueClassBlock *callingClass = std::get<3>(recv);827client->write(response, fe->getMethodFromClass(methodClass, const_cast<char*>(methodName.c_str()),828const_cast<char*>(signature.c_str()), callingClass));829}830break;831case MessageType::VM_createMethodHandleArchetypeSpecimen:832{833auto recv = client->getRecvData<uintptr_t*, TR_ResolvedJ9Method *>();834uintptr_t *methodHandleLocation = std::get<0>(recv);835TR_ResolvedJ9Method *owningMethod = std::get<1>(recv);836intptr_t length;837char *thunkableSignature;838{839TR::VMAccessCriticalSection createMethodHandleArchetypeSpecimen(fe);840TR_OpaqueMethodBlock *archetype = fe->lookupMethodHandleThunkArchetype(*methodHandleLocation);841uintptr_t signatureString = fe->getReferenceField(fe->getReferenceField(842*methodHandleLocation,843"thunks", "Ljava/lang/invoke/ThunkTuple;"),844"thunkableSignature", "Ljava/lang/String;");845length = fe->getStringUTF8Length(signatureString);846thunkableSignature = (char*)trMemory->allocateStackMemory(length+1);847fe->getStringUTF8(signatureString, thunkableSignature, length+1);848849TR_ResolvedMethod *resolvedMethod = fe->createResolvedMethodWithSignature(850trMemory,851archetype,852NULL,853thunkableSignature,854length,855owningMethod);856resolvedMethod->convertToMethod()->setArchetypeSpecimen();857resolvedMethod->setMethodHandleLocation(methodHandleLocation);858859TR_ResolvedJ9JITServerMethodInfo methodInfo;860TR_ResolvedJ9JITServerMethod::packMethodInfo(methodInfo, static_cast<TR_ResolvedJ9Method *>(resolvedMethod), fe);861862client->write(response, archetype, std::string(thunkableSignature, length), methodInfo);863}864}865break;866case MessageType::VM_isClassVisible:867{868auto recv = client->getRecvData<TR_OpaqueClassBlock *, TR_OpaqueClassBlock *>();869TR_OpaqueClassBlock *sourceClass = std::get<0>(recv);870TR_OpaqueClassBlock *destClass = std::get<1>(recv);871client->write(response, fe->isClassVisible(sourceClass, destClass));872}873break;874case MessageType::VM_markClassForTenuredAlignment:875{876auto recv = client->getRecvData<TR_OpaqueClassBlock *, uint32_t>();877TR_OpaqueClassBlock *clazz = std::get<0>(recv);878uint32_t alignFromStart = std::get<1>(recv);879fe->markClassForTenuredAlignment(comp, clazz, alignFromStart);880client->write(response, JITServer::Void());881}882break;883case MessageType::VM_reportHotField:884{885auto recv = client->getRecvData<int32_t, J9Class *, uint8_t, uint32_t>();886fe->reportHotField(std::get<0>(recv), std::get<1>(recv), std::get<2>(recv), std::get<3>(recv));887client->write(response, JITServer::Void());888}889break;890case MessageType::VM_getReferenceSlotsInClass:891{892TR_OpaqueClassBlock *clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());893int32_t *start = fe->getReferenceSlotsInClass(comp, clazz);894if (!start)895client->write(response, std::string(""));896else897{898int32_t numSlots = 0;899for (; start[numSlots]; ++numSlots);900// Copy the null terminated array into a string901std::string slotsStr((char *) start, (1 + numSlots) * sizeof(int32_t));902client->write(response, slotsStr);903}904}905break;906case MessageType::VM_getMethodSize:907{908TR_OpaqueMethodBlock *method = std::get<0>(client->getRecvData<TR_OpaqueMethodBlock *>());909client->write(response, fe->getMethodSize(method));910}911break;912case MessageType::VM_addressOfFirstClassStatic:913{914TR_OpaqueClassBlock *clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());915client->write(response, fe->addressOfFirstClassStatic(clazz));916}917break;918case MessageType::VM_getStaticFieldAddress:919{920auto recv = client->getRecvData<TR_OpaqueClassBlock *, std::string, std::string>();921TR_OpaqueClassBlock *clazz = std::get<0>(recv);922std::string fieldName = std::get<1>(recv);923std::string sigName = std::get<2>(recv);924client->write(response, fe->getStaticFieldAddress(clazz,925reinterpret_cast<unsigned char*>(const_cast<char*>(fieldName.c_str())),926fieldName.length(),927reinterpret_cast<unsigned char*>(const_cast<char*>(sigName.c_str())),928sigName.length()));929}930break;931case MessageType::VM_getInterpreterVTableSlot:932{933auto recv = client->getRecvData<TR_OpaqueMethodBlock *, TR_OpaqueClassBlock *>();934TR_OpaqueMethodBlock *method = std::get<0>(recv);935TR_OpaqueClassBlock *clazz = std::get<1>(recv);936client->write(response, fe->getInterpreterVTableSlot(method, clazz));937}938break;939case MessageType::VM_revertToInterpreted:940{941TR_OpaqueMethodBlock *method = std::get<0>(client->getRecvData<TR_OpaqueMethodBlock *>());942fe->revertToInterpreted(method);943client->write(response, JITServer::Void());944}945break;946case MessageType::VM_getLocationOfClassLoaderObjectPointer:947{948TR_OpaqueClassBlock *clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());949client->write(response, fe->getLocationOfClassLoaderObjectPointer(clazz));950}951break;952case MessageType::VM_getClassFromMethodBlock:953{954TR_OpaqueMethodBlock *method = std::get<0>(client->getRecvData<TR_OpaqueMethodBlock *>());955client->write(response, fe->getClassFromMethodBlock(method));956}957break;958case MessageType::VM_fetchMethodExtendedFlagsPointer:959{960J9Method *method = std::get<0>(client->getRecvData<J9Method *>());961client->write(response, fe->fetchMethodExtendedFlagsPointer(method));962}963break;964case MessageType::VM_stringEquals:965{966auto recv = client->getRecvData<uintptr_t *, uintptr_t *>();967uintptr_t *stringLocation1 = std::get<0>(recv);968uintptr_t *stringLocation2 = std::get<1>(recv);969int32_t result;970bool isEqual = fe->stringEquals(comp, stringLocation1, stringLocation2, result);971client->write(response, result, isEqual);972}973break;974case MessageType::VM_getStringHashCode:975{976uintptr_t *stringLocation = std::get<0>(client->getRecvData<uintptr_t *>());977int32_t result;978bool isGet = fe->getStringHashCode(comp, stringLocation, result);979client->write(response, result, isGet);980}981break;982case MessageType::VM_getLineNumberForMethodAndByteCodeIndex:983{984auto recv = client->getRecvData<TR_OpaqueMethodBlock *, int32_t>();985TR_OpaqueMethodBlock *method = std::get<0>(recv);986int32_t bcIndex = std::get<1>(recv);987client->write(response, fe->getLineNumberForMethodAndByteCodeIndex(method, bcIndex));988}989break;990case MessageType::VM_getObjectNewInstanceImplMethod:991{992client->getRecvData<JITServer::Void>();993client->write(response, fe->getObjectNewInstanceImplMethod());994}995break;996case MessageType::VM_getBytecodePC:997{998TR_OpaqueMethodBlock *method = std::get<0>(client->getRecvData<TR_OpaqueMethodBlock *>());999client->write(response, TR::Compiler->mtd.bytecodeStart(method));1000}1001break;1002case MessageType::VM_getVFTEntry:1003{1004auto recv = client->getRecvData<TR_OpaqueClassBlock *, int32_t>();1005client->write(response, fe->getVFTEntry(std::get<0>(recv), std::get<1>(recv)));1006}1007break;1008case MessageType::VM_isClassArray:1009{1010auto recv = client->getRecvData<TR_OpaqueClassBlock*>();1011auto clazz = std::get<0>(recv);1012client->write(response, fe->isClassArray(clazz));1013}1014break;1015case MessageType::VM_instanceOfOrCheckCast:1016{1017auto recv = client->getRecvData<J9Class*, J9Class*>();1018auto clazz1 = std::get<0>(recv);1019auto clazz2 = std::get<1>(recv);1020client->write(response, fe->instanceOfOrCheckCast(clazz1, clazz2));1021}1022break;1023case MessageType::VM_instanceOfOrCheckCastNoCacheUpdate:1024{1025auto recv = client->getRecvData<J9Class*, J9Class*>();1026auto clazz1 = std::get<0>(recv);1027auto clazz2 = std::get<1>(recv);1028client->write(response, fe->instanceOfOrCheckCastNoCacheUpdate(clazz1, clazz2));1029}1030break;1031case MessageType::VM_transformJlrMethodInvoke:1032{1033auto recv = client->getRecvData<J9Method*, J9Class*>();1034auto method = std::get<0>(recv);1035auto clazz = std::get<1>(recv);1036client->write(response, fe->transformJlrMethodInvoke(method, clazz));1037}1038break;1039case MessageType::VM_dereferenceStaticAddress:1040{1041auto recv = client->getRecvData<void *, TR::DataType>();1042void *address = std::get<0>(recv);1043auto addressType = std::get<1>(recv);1044client->write(response, fe->dereferenceStaticFinalAddress(address, addressType));1045}1046break;1047case MessageType::VM_getClassFromCP:1048{1049auto recv = client->getRecvData<J9ConstantPool *>();1050client->write(response, fe->getClassFromCP(std::get<0>(recv)));1051}1052break;1053case MessageType::VM_getROMMethodFromRAMMethod:1054{1055auto recv = client->getRecvData<J9Method *>();1056client->write(response, fe->getROMMethodFromRAMMethod(std::get<0>(recv)));1057}1058break;1059case MessageType::VM_getCellSizeForSizeClass:1060{1061auto recv = client->getRecvData<uintptr_t>();1062client->write(response, fe->getCellSizeForSizeClass(std::get<0>(recv)));1063}1064break;1065case MessageType::VM_getObjectSizeClass:1066{1067auto recv = client->getRecvData<uintptr_t>();1068client->write(response, fe->getObjectSizeClass(std::get<0>(recv)));1069}1070break;1071case MessageType::VM_getFields:1072{1073auto recv = client->getRecvData<TR_ResolvedJ9Method *, std::vector<int32_t>, std::vector<uint8_t>>();1074TR_ResolvedJ9Method *owningMethod = std::get<0>(recv);1075auto &cpIndices = std::get<1>(recv);1076auto &isStatic = std::get<2>(recv);10771078int32_t numFields = cpIndices.size();1079std::vector<J9Class *> declaringClasses;1080std::vector<UDATA> fields;1081declaringClasses.reserve(numFields);1082fields.reserve(numFields);10831084J9ConstantPool *cp = reinterpret_cast<J9ConstantPool *>(owningMethod->ramConstantPool());1085for (int32_t i = 0; i < numFields; ++i)1086{1087J9Class *declaringClass;1088// do we need to check if the field is resolved?1089UDATA field = findField(fe->vmThread(), cp, cpIndices[i], isStatic[i], &declaringClass);1090declaringClasses.push_back(declaringClass);1091fields.push_back(field);1092}1093client->write(response, declaringClasses, fields);1094}1095break;1096case MessageType::VM_increaseOSRGlobalBufferSize:1097{1098auto recv = client->getRecvData<uintptr_t, uintptr_t, uintptr_t>();1099bool result = fe->ensureOSRBufferSize(comp, std::get<0>(recv), std::get<1>(recv), std::get<2>(recv));1100client->write(response, result, jitConfig->javaVM->osrGlobalBufferSize);1101}1102break;1103case MessageType::VM_methodOfDirectOrVirtualHandle:1104{1105auto recv = client->getRecvData<uintptr_t*, bool>();1106uintptr_t *mh = std::get<0>(recv);1107bool isVirtual = std::get<1>(recv);1108TR_J9VMBase::MethodOfHandle moh =1109fe->methodOfDirectOrVirtualHandle(mh, isVirtual);1110client->write(response, moh.j9method, moh.vmSlot);1111}1112break;1113#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)1114case MessageType::VM_targetMethodFromMemberName:1115{1116auto recv = client->getRecvData<TR::KnownObjectTable::Index>();1117client->write(response, fe->targetMethodFromMemberName(comp, std::get<0>(recv)));1118}1119break;1120case MessageType::VM_targetMethodFromMethodHandle:1121{1122auto recv = client->getRecvData<TR::KnownObjectTable::Index>();1123client->write(response, fe->targetMethodFromMethodHandle(comp, std::get<0>(recv)));1124}1125break;1126case MessageType::VM_getKnotIndexOfInvokeCacheArrayAppendixElement:1127{1128auto recv = client->getRecvData<uintptr_t *>();1129TR::KnownObjectTable::Index idx = fe->getKnotIndexOfInvokeCacheArrayAppendixElement(comp, std::get<0>(recv));1130client->write(response, idx, knot->getPointerLocation(idx));1131}1132break;1133case MessageType::VM_targetMethodFromInvokeCacheArrayMemberNameObj:1134{1135auto recv = client->getRecvData<TR_ResolvedJ9Method *, uintptr_t *>();1136auto *targetMethod = static_cast<TR_ResolvedJ9Method *>(fe->targetMethodFromInvokeCacheArrayMemberNameObj(comp, std::get<0>(recv), std::get<1>(recv)));1137TR_ResolvedJ9JITServerMethodInfo methodInfo;1138TR_ResolvedJ9JITServerMethod::packMethodInfo(methodInfo, targetMethod, fe);1139client->write(response, targetMethod->getPersistentIdentifier(), methodInfo);1140}1141break;1142case MessageType::VM_refineInvokeCacheElementSymRefWithKnownObjectIndex:1143{1144auto recv = client->getRecvData<uintptr_t *>();1145uintptr_t *invokeCacheArray = std::get<0>(recv);1146uintptr_t arrayElementRef = (uintptr_t) fe->getReferenceElement(*invokeCacheArray, JSR292_invokeCacheArrayAppendixIndex);1147TR::KnownObjectTable::Index arrayElementKnotIndex = knot->getOrCreateIndex(arrayElementRef);1148client->write(response, arrayElementKnotIndex, knot->getPointerLocation(arrayElementKnotIndex));1149}1150break;1151case MessageType::VM_isLambdaFormGeneratedMethod:1152{1153auto recv = client->getRecvData<TR_OpaqueMethodBlock *>();1154client->write(response, fe->isLambdaFormGeneratedMethod(std::get<0>(recv)));1155}1156break;1157case MessageType::VM_vTableOrITableIndexFromMemberName:1158{1159auto recv = client->getRecvData<TR::KnownObjectTable::Index>();1160client->write(response, fe->vTableOrITableIndexFromMemberName(comp, std::get<0>(recv)));1161}1162break;1163case MessageType::VM_delegatingMethodHandleTarget:1164{1165auto recv = client->getRecvData<TR::KnownObjectTable::Index, TR_OpaqueClassBlock *>();1166TR::KnownObjectTable::Index idx = fe->delegatingMethodHandleTargetHelper(comp, std::get<0>(recv), std::get<1>(recv));1167client->write(response, idx, knot->getPointerLocation(idx));1168}1169break;1170case MessageType::VM_getVMTargetOffset:1171{1172client->getRecvData<JITServer::Void>();1173client->write(response, fe->getVMTargetOffset());1174}1175break;1176case MessageType::VM_getVMIndexOffset:1177{1178client->getRecvData<JITServer::Void>();1179client->write(response, fe->getVMIndexOffset());1180}1181break;1182case MessageType::VM_getMemberNameFieldKnotIndexFromMethodHandleKnotIndex:1183{1184auto recv = client->getRecvData<TR::KnownObjectTable::Index, std::string>();1185auto &memberNameStr = std::get<1>(recv);1186TR::KnownObjectTable::Index fieldKnotIndex =1187fe->getMemberNameFieldKnotIndexFromMethodHandleKnotIndex(1188comp, std::get<0>(recv),1189&memberNameStr[0]);1190client->write(response, fieldKnotIndex, knot->getPointerLocation(fieldKnotIndex));1191}1192break;1193case MessageType::VM_isMethodHandleExpectedType:1194{1195auto recv = client->getRecvData<TR::KnownObjectTable::Index, TR::KnownObjectTable::Index>();1196TR::KnownObjectTable::Index mhIndex = std::get<0>(recv);1197TR::KnownObjectTable::Index expectedTypeIndex = std::get<1>(recv);1198bool result = fe->isMethodHandleExpectedType(comp, mhIndex, expectedTypeIndex);1199client->write(response, result, knot->getPointerLocation(mhIndex), knot->getPointerLocation(expectedTypeIndex));1200}1201break;1202#endif // J9VM_OPT_OPENJDK_METHODHANDLE1203case MessageType::VM_isStable:1204{1205auto recv = client->getRecvData<J9Class *, int>();1206J9Class *fieldClass = std::get<0>(recv);1207int cpIndex = std::get<1>(recv);12081209bool isStable = fe->isStable(fieldClass, cpIndex);1210client->write(response, isStable);1211}1212break;1213case MessageType::mirrorResolvedJ9Method:1214{1215// allocate a new TR_ResolvedJ9Method on the heap, to be used as a mirror for performing actions which are only1216// easily done on the client side.1217auto recv = client->getRecvData<TR_OpaqueMethodBlock *, TR_ResolvedJ9Method *, uint32_t, bool>();1218TR_OpaqueMethodBlock *method = std::get<0>(recv);1219auto *owningMethod = std::get<1>(recv);1220uint32_t vTableSlot = std::get<2>(recv);1221bool isAOT = std::get<3>(recv);1222TR_ResolvedJ9JITServerMethodInfo methodInfo;1223// if in AOT mode, create a relocatable method mirror1224TR_ResolvedJ9JITServerMethod::createResolvedMethodMirror(methodInfo, method, vTableSlot, owningMethod, fe, trMemory);12251226client->write(response, methodInfo);1227}1228break;1229case MessageType::ResolvedMethod_getRemoteROMClassAndMethods:1230{1231J9Class *clazz = std::get<0>(client->getRecvData<J9Class *>());1232{1233OMR::CriticalSection romClassCache(compInfo->getclassesCachedAtServerMonitor());1234compInfo->getclassesCachedAtServer().insert(clazz);1235}1236client->write(response, JITServerHelpers::packRemoteROMClassInfo(clazz, fe->vmThread(), trMemory, true));1237}1238break;1239case MessageType::ResolvedMethod_staticAttributes:1240{1241auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t, bool, bool>();1242TR_ResolvedJ9Method *method = std::get<0>(recv);1243int32_t cpIndex = std::get<1>(recv);1244int32_t isStore = std::get<2>(recv);1245int32_t needAOTValidation = std::get<3>(recv);1246void *address;1247TR::DataType type = TR::NoType;1248bool volatileP = true;1249bool isFinal = false;1250bool isPrivate = false;1251bool unresolvedInCP;1252bool result = method->staticAttributes(comp, cpIndex, &address, &type, &volatileP, &isFinal, &isPrivate, isStore, &unresolvedInCP, needAOTValidation);1253TR_J9MethodFieldAttributes attrs(reinterpret_cast<uintptr_t>(address), type.getDataType(), volatileP, isFinal, isPrivate, unresolvedInCP, result);1254client->write(response, attrs);1255}1256break;1257case MessageType::ResolvedMethod_definingClassFromCPFieldRef:1258{1259auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t, bool>();1260TR_ResolvedJ9Method *method = std::get<0>(recv);1261int32_t cpIndex = std::get<1>(recv);1262bool isStatic = std::get<2>(recv);1263client->write(response, method->definingClassFromCPFieldRef(comp, cpIndex, isStatic));1264}1265break;1266case MessageType::ResolvedMethod_getClassFromConstantPool:1267{1268auto recv = client->getRecvData<TR_ResolvedJ9Method *, uint32_t, bool>();1269TR_ResolvedJ9Method *method = std::get<0>(recv);1270uint32_t cpIndex = std::get<1>(recv);1271bool returnClassForAOT = std::get<2>(recv);1272client->write(response, method->getClassFromConstantPool(comp, cpIndex, returnClassForAOT));1273}1274break;1275case MessageType::ResolvedMethod_getDeclaringClassFromFieldOrStatic:1276{1277auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t>();1278TR_ResolvedJ9Method *method = std::get<0>(recv);1279int32_t cpIndex = std::get<1>(recv);1280client->write(response, method->getDeclaringClassFromFieldOrStatic(comp, cpIndex));1281}1282break;1283case MessageType::ResolvedMethod_classOfStatic:1284{1285auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t, bool>();1286TR_ResolvedJ9Method *method = std::get<0>(recv);1287int32_t cpIndex = std::get<1>(recv);1288int32_t returnClassForAOT = std::get<2>(recv);1289client->write(response, method->classOfStatic(cpIndex, returnClassForAOT));1290}1291break;1292case MessageType::ResolvedMethod_fieldAttributes:1293{1294auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t, bool, bool>();1295TR_ResolvedJ9Method *method = std::get<0>(recv);1296I_32 cpIndex = std::get<1>(recv);1297bool isStore = std::get<2>(recv);1298bool needAOTValidation = std::get<3>(recv);1299U_32 fieldOffset;1300TR::DataType type = TR::NoType;1301bool volatileP = true;1302bool isFinal = false;1303bool isPrivate = false;1304bool unresolvedInCP;1305bool result = method->fieldAttributes(comp, cpIndex, &fieldOffset, &type, &volatileP, &isFinal, &isPrivate, isStore, &unresolvedInCP, needAOTValidation);1306TR_J9MethodFieldAttributes attrs(static_cast<uintptr_t>(fieldOffset), type.getDataType(), volatileP, isFinal, isPrivate, unresolvedInCP, result);1307client->write(response, attrs);1308}1309break;1310case MessageType::ResolvedMethod_getResolvedStaticMethodAndMirror:1311{1312auto recv = client->getRecvData<TR_ResolvedJ9Method *, I_32>();1313auto *method = std::get<0>(recv);1314int32_t cpIndex = std::get<1>(recv);1315bool unresolvedInCP;1316J9Method *ramMethod = jitGetJ9MethodUsingIndex(fe->vmThread(), method->cp(), cpIndex);1317unresolvedInCP = !ramMethod || !J9_BYTECODE_START_FROM_RAM_METHOD(ramMethod);13181319{1320TR::VMAccessCriticalSection resolveStaticMethodRef(fe);1321ramMethod = jitResolveStaticMethodRef(fe->vmThread(), method->cp(), cpIndex, J9_RESOLVE_FLAG_JIT_COMPILE_TIME);1322}13231324// Create a mirror right away1325TR_ResolvedJ9JITServerMethodInfo methodInfo;1326if (ramMethod)1327TR_ResolvedJ9JITServerMethod::createResolvedMethodFromJ9MethodMirror(methodInfo, (TR_OpaqueMethodBlock *) ramMethod, 0, method, fe, trMemory);13281329client->write(response, ramMethod, methodInfo, unresolvedInCP);1330}1331break;1332case MessageType::ResolvedMethod_getResolvedSpecialMethodAndMirror:1333{1334auto recv = client->getRecvData<TR_ResolvedJ9Method *, I_32>();1335TR_ResolvedJ9Method *method = std::get<0>(recv);1336int32_t cpIndex = std::get<1>(recv);1337J9Method *ramMethod = NULL;1338TR_ResolvedJ9JITServerMethodInfo methodInfo;1339if (!((fe->_jitConfig->runtimeFlags & J9JIT_RUNTIME_RESOLVE) &&1340!comp->ilGenRequest().details().isMethodHandleThunk() &&1341performTransformation(comp, "Setting as unresolved special call cpIndex=%d\n",cpIndex)))1342{1343TR::VMAccessCriticalSection resolveSpecialMethodRef(fe);1344ramMethod = jitResolveSpecialMethodRef(fe->vmThread(), method->cp(), cpIndex, J9_RESOLVE_FLAG_JIT_COMPILE_TIME);13451346if (ramMethod)1347TR_ResolvedJ9JITServerMethod::createResolvedMethodFromJ9MethodMirror(methodInfo, (TR_OpaqueMethodBlock *) ramMethod, 0, method, fe, trMemory);1348}13491350client->write(response, ramMethod, methodInfo);1351}1352break;1353case MessageType::ResolvedMethod_startAddressForJittedMethod:1354{1355TR_ResolvedJ9Method *method = std::get<0>(client->getRecvData<TR_ResolvedJ9Method *>());1356client->write(response, method->startAddressForJittedMethod());1357}1358break;1359case MessageType::ResolvedMethod_getResolvedPossiblyPrivateVirtualMethodAndMirror:1360{1361// 1. Resolve method1362auto recv = client->getRecvData<TR_ResolvedMethod *, J9RAMConstantPoolItem *, I_32>();1363auto *owningMethod = std::get<0>(recv);1364auto literals = std::get<1>(recv);1365J9ConstantPool *cp = (J9ConstantPool*)literals;1366I_32 cpIndex = std::get<2>(recv);1367bool unresolvedInCP = true;13681369// Only call the resolve if unresolved1370J9Method * ramMethod = 0;1371UDATA vTableIndex = (((J9RAMVirtualMethodRef*) literals)[cpIndex]).methodIndexAndArgCount;1372vTableIndex >>= 8;1373if ((TR::Compiler->vm.getInterpreterVTableOffset() + sizeof(uintptr_t)) == vTableIndex)1374{1375TR::VMAccessCriticalSection resolveVirtualMethodRef(fe);1376vTableIndex = fe->_vmFunctionTable->resolveVirtualMethodRefInto(fe->vmThread(), cp, cpIndex,1377J9_RESOLVE_FLAG_JIT_COMPILE_TIME, &ramMethod, NULL);1378}1379else if (!TR_ResolvedJ9Method::isInvokePrivateVTableOffset(vTableIndex))1380{1381// Go fishing for the J9Method...1382uint32_t classIndex = ((J9ROMMethodRef *) cp->romConstantPool)[cpIndex].classRefCPIndex;1383J9Class * classObject = (((J9RAMClassRef*) literals)[classIndex]).value;1384ramMethod = *(J9Method **)((char *)classObject + vTableIndex);1385unresolvedInCP = false;1386}13871388if(TR_ResolvedJ9Method::isInvokePrivateVTableOffset(vTableIndex))1389ramMethod = (((J9RAMVirtualMethodRef*) literals)[cpIndex]).method;13901391// 2. Mirror the resolved method on the client1392if (vTableIndex)1393{1394TR_OpaqueMethodBlock *method = (TR_OpaqueMethodBlock *) ramMethod;13951396TR_ResolvedJ9JITServerMethodInfo methodInfo;1397TR_ResolvedJ9JITServerMethod::createResolvedMethodFromJ9MethodMirror(methodInfo, (TR_OpaqueMethodBlock *) ramMethod, (uint32_t) vTableIndex, owningMethod, fe, trMemory);13981399client->write(response, ramMethod, vTableIndex, unresolvedInCP, methodInfo);1400}1401else1402{1403client->write(response, ramMethod, vTableIndex, unresolvedInCP, TR_ResolvedJ9JITServerMethodInfo());1404}1405}1406break;1407case MessageType::ResolvedMethod_getResolvedVirtualMethod:1408{1409auto recv = client->getRecvData<TR_OpaqueClassBlock *, I_32, bool, TR_ResolvedJ9Method *>();1410auto clazz = std::get<0>(recv);1411auto offset = std::get<1>(recv);1412auto ignoreRTResolve = std::get<2>(recv);1413auto owningMethod = std::get<3>(recv);1414TR_OpaqueMethodBlock *ramMethod = fe->getResolvedVirtualMethod(clazz, offset, ignoreRTResolve);1415TR_ResolvedJ9JITServerMethodInfo methodInfo;1416if (ramMethod)1417TR_ResolvedJ9JITServerMethod::createResolvedMethodMirror(methodInfo, ramMethod, 0, owningMethod, fe, trMemory);1418client->write(response, ramMethod, methodInfo);1419}1420break;1421case MessageType::get_params_to_construct_TR_j9method:1422{1423auto recv = client->getRecvData<J9Class *, uintptr_t>();1424J9Class * aClazz = std::get<0>(recv);1425uintptr_t cpIndex = std::get<1>(recv);1426J9ROMClass * romClass = aClazz->romClass;1427uintptr_t realCPIndex = jitGetRealCPIndex(fe->vmThread(), romClass, cpIndex);1428J9ROMMethodRef * romRef = &J9ROM_CP_BASE(romClass, J9ROMMethodRef)[realCPIndex];1429J9ROMClassRef * classRef = &J9ROM_CP_BASE(romClass, J9ROMClassRef)[romRef->classRefCPIndex];1430J9ROMNameAndSignature * nameAndSignature = J9ROMMETHODREF_NAMEANDSIGNATURE(romRef);1431J9UTF8 * className = J9ROMCLASSREF_NAME(classRef);1432J9UTF8 * name = J9ROMNAMEANDSIGNATURE_NAME(nameAndSignature);1433J9UTF8 * signature = J9ROMNAMEANDSIGNATURE_SIGNATURE(nameAndSignature);1434std::string classNameStr(utf8Data(className), J9UTF8_LENGTH(className));1435std::string nameStr(utf8Data(name), J9UTF8_LENGTH(name));1436std::string signatureStr(utf8Data(signature), J9UTF8_LENGTH(signature));1437client->write(response, classNameStr, nameStr, signatureStr);1438}1439break;1440case MessageType::ResolvedMethod_setRecognizedMethodInfo:1441{1442auto recv = client->getRecvData<TR_ResolvedJ9Method *, TR::RecognizedMethod>();1443TR_ResolvedJ9Method *method = std::get<0>(recv);1444TR::RecognizedMethod rm = std::get<1>(recv);1445method->setRecognizedMethodInfo(rm);1446client->write(response, JITServer::Void());1447}1448break;1449case MessageType::ResolvedMethod_localName:1450{1451auto recv = client->getRecvData<TR_ResolvedJ9Method *, U_32, U_32>();1452TR_ResolvedJ9Method *method = std::get<0>(recv);1453U_32 slotNumber = std::get<1>(recv);1454U_32 bcIndex = std::get<2>(recv);1455I_32 len;1456char *nameChars = method->localName(slotNumber, bcIndex, len, trMemory);1457if (nameChars)1458client->write(response, std::string(nameChars, len));1459else1460client->write(response, std::string());1461}1462break;1463case MessageType::ResolvedMethod_getResolvedInterfaceMethod_2:1464{1465auto recv = client->getRecvData<TR_ResolvedJ9Method*, I_32>();1466auto mirror = std::get<0>(recv);1467auto cpIndex = std::get<1>(recv);1468UDATA pITableIndex;1469TR_OpaqueClassBlock *clazz = mirror->getResolvedInterfaceMethod(cpIndex, &pITableIndex);1470client->write(response, clazz, pITableIndex);1471}1472break;1473case MessageType::ResolvedMethod_getResolvedInterfaceMethodAndMirror_3:1474{1475auto recv = client->getRecvData<TR_OpaqueMethodBlock *, TR_OpaqueClassBlock *, I_32, TR_ResolvedJ9Method *>();1476auto method = std::get<0>(recv);1477auto clazz = std::get<1>(recv);1478auto cpIndex = std::get<2>(recv);1479auto owningMethod = std::get<3>(recv);1480J9Method * ramMethod = (J9Method *)fe->getResolvedInterfaceMethod(method, clazz, cpIndex);1481bool resolved = ramMethod && J9_BYTECODE_START_FROM_RAM_METHOD(ramMethod);14821483// Create a mirror right away1484TR_ResolvedJ9JITServerMethodInfo methodInfo;1485if (resolved)1486TR_ResolvedJ9JITServerMethod::createResolvedMethodFromJ9MethodMirror(methodInfo, (TR_OpaqueMethodBlock *) ramMethod, 0, owningMethod, fe, trMemory);14871488client->write(response, resolved, ramMethod, methodInfo);1489}1490break;1491case MessageType::ResolvedMethod_getResolvedInterfaceMethodOffset:1492{1493auto recv = client->getRecvData<TR_ResolvedJ9Method*, TR_OpaqueClassBlock*, I_32>();1494auto mirror = std::get<0>(recv);1495auto clazz = std::get<1>(recv);1496auto cpIndex = std::get<2>(recv);1497U_32 offset = mirror->getResolvedInterfaceMethodOffset(clazz, cpIndex);1498client->write(response, offset);1499}1500break;1501case MessageType::ResolvedMethod_getResolvedImproperInterfaceMethodAndMirror:1502{1503auto recv = client->getRecvData<TR_ResolvedJ9Method *, I_32>();1504auto mirror = std::get<0>(recv);1505auto cpIndex = std::get<1>(recv);1506UDATA vtableOffset = 0;1507J9Method *j9method = NULL;1508{1509TR::VMAccessCriticalSection getResolvedHandleMethod(fe);1510j9method = jitGetImproperInterfaceMethodFromCP(fe->vmThread(), mirror->cp(), cpIndex, &vtableOffset);1511}1512// Create a mirror right away1513TR_ResolvedJ9JITServerMethodInfo methodInfo;1514if (j9method)1515TR_ResolvedJ9JITServerMethod::createResolvedMethodFromJ9MethodMirror(methodInfo, (TR_OpaqueMethodBlock *) j9method, (uint32_t)vtableOffset, mirror, fe, trMemory);15161517client->write(response, j9method, methodInfo, vtableOffset);1518}1519break;1520case MessageType::ResolvedMethod_startAddressForJNIMethod:1521{1522TR_ResolvedJ9Method *ramMethod = std::get<0>(client->getRecvData<TR_ResolvedJ9Method *>());1523client->write(response, ramMethod->startAddressForJNIMethod(comp));1524}1525break;1526case MessageType::ResolvedMethod_startAddressForInterpreterOfJittedMethod:1527{1528TR_ResolvedJ9Method *ramMethod = std::get<0>(client->getRecvData<TR_ResolvedJ9Method *>());1529client->write(response, ramMethod->startAddressForInterpreterOfJittedMethod());1530}1531break;1532case MessageType::ResolvedMethod_getUnresolvedStaticMethodInCP:1533{1534auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t>();1535TR_ResolvedJ9Method *method= std::get<0>(recv);1536int32_t cpIndex = std::get<1>(recv);1537client->write(response, method->getUnresolvedStaticMethodInCP(cpIndex));1538}1539break;1540case MessageType::ResolvedMethod_getUnresolvedSpecialMethodInCP:1541{1542auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t>();1543TR_ResolvedJ9Method *method= std::get<0>(recv);1544int32_t cpIndex = std::get<1>(recv);1545client->write(response, method->getUnresolvedSpecialMethodInCP(cpIndex));1546}1547break;1548case MessageType::ResolvedMethod_getUnresolvedFieldInCP:1549{1550auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t>();1551TR_ResolvedJ9Method *method= std::get<0>(recv);1552int32_t cpIndex = std::get<1>(recv);1553client->write(response, method->getUnresolvedFieldInCP(cpIndex));1554}1555break;1556case MessageType::ResolvedMethod_isSubjectToPhaseChange:1557{1558TR_ResolvedJ9Method *method = std::get<0>(client->getRecvData<TR_ResolvedJ9Method *>());1559client->write(response, method->isSubjectToPhaseChange(comp));1560}1561break;1562case MessageType::ResolvedMethod_getResolvedHandleMethod:1563{1564auto recv = client->getRecvData<TR_ResolvedJ9Method*, int32_t>();1565auto *owningMethod = std::get<0>(recv);1566int32_t cpIndex = std::get<1>(recv);1567bool isUnresolvedInCP;1568auto *handleMethod = static_cast<TR_ResolvedJ9Method *>(owningMethod->getResolvedHandleMethod(comp, cpIndex, &isUnresolvedInCP));1569TR_ResolvedJ9JITServerMethodInfo methodInfo;1570TR_ResolvedJ9JITServerMethod::packMethodInfo(methodInfo, handleMethod, fe);1571std::string signature(utf8Data(handleMethod->_signature), J9UTF8_LENGTH(handleMethod->_signature));15721573client->write(1574response,1575handleMethod->getPersistentIdentifier(),1576methodInfo,1577signature,1578isUnresolvedInCP1579);1580}1581break;1582case MessageType::ResolvedMethod_methodTypeTableEntryAddress:1583{1584auto recv = client->getRecvData<TR_ResolvedJ9Method*, I_32>();1585auto mirror = std::get<0>(recv);1586I_32 cpIndex = std::get<1>(recv);1587client->write(response, mirror->methodTypeTableEntryAddress(cpIndex));1588}1589break;1590case MessageType::ResolvedMethod_isUnresolvedMethodTypeTableEntry:1591{1592auto recv = client->getRecvData<TR_ResolvedJ9Method*, I_32>();1593auto mirror = std::get<0>(recv);1594I_32 cpIndex = std::get<1>(recv);1595client->write(response, mirror->isUnresolvedMethodTypeTableEntry(cpIndex));1596}1597break;1598case MessageType::ResolvedMethod_isUnresolvedCallSiteTableEntry:1599{1600auto recv = client->getRecvData<TR_ResolvedJ9Method*, int32_t>();1601auto mirror = std::get<0>(recv);1602int32_t callSiteIndex = std::get<1>(recv);1603client->write(response, mirror->isUnresolvedCallSiteTableEntry(callSiteIndex));1604}1605break;1606case MessageType::ResolvedMethod_callSiteTableEntryAddress:1607{1608auto recv = client->getRecvData<TR_ResolvedJ9Method*, int32_t>();1609auto mirror = std::get<0>(recv);1610int32_t callSiteIndex = std::get<1>(recv);1611client->write(response, mirror->callSiteTableEntryAddress(callSiteIndex));1612}1613break;1614#if defined(J9VM_OPT_METHOD_HANDLE)1615case MessageType::ResolvedMethod_varHandleMethodTypeTableEntryAddress:1616{1617auto recv = client->getRecvData<TR_ResolvedJ9Method*, int32_t>();1618auto mirror = std::get<0>(recv);1619int32_t cpIndex = std::get<1>(recv);1620client->write(response, mirror->varHandleMethodTypeTableEntryAddress(cpIndex));1621}1622break;1623case MessageType::ResolvedMethod_isUnresolvedVarHandleMethodTypeTableEntry:1624{1625auto recv = client->getRecvData<TR_ResolvedJ9Method*, int32_t>();1626auto mirror = std::get<0>(recv);1627int32_t cpIndex = std::get<1>(recv);1628client->write(response, mirror->isUnresolvedVarHandleMethodTypeTableEntry(cpIndex));1629}1630break;1631#endif /* defined(J9VM_OPT_METHOD_HANDLE) */1632case MessageType::ResolvedMethod_getResolvedDynamicMethod:1633{1634auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t>();1635TR_ResolvedJ9Method *owningMethod = std::get<0>(recv);1636int32_t callSiteIndex = std::get<1>(recv);16371638bool isUnresolvedInCP;1639auto *dynamicMethod = static_cast<TR_ResolvedJ9Method *>(owningMethod->getResolvedDynamicMethod(comp, callSiteIndex, &isUnresolvedInCP));1640TR_ResolvedJ9JITServerMethodInfo methodInfo;1641TR_ResolvedJ9JITServerMethod::packMethodInfo(methodInfo, (TR_ResolvedJ9Method *) dynamicMethod, fe);16421643client->write(1644response,1645dynamicMethod->getPersistentIdentifier(),1646methodInfo,1647std::string(utf8Data(dynamicMethod->_signature), J9UTF8_LENGTH(dynamicMethod->_signature)),1648isUnresolvedInCP1649);1650}1651break;1652case MessageType::ResolvedMethod_shouldFailSetRecognizedMethodInfoBecauseOfHCR:1653{1654auto mirror = std::get<0>(client->getRecvData<TR_ResolvedJ9Method*>());1655client->write(response, mirror->shouldFailSetRecognizedMethodInfoBecauseOfHCR());1656}1657break;1658case MessageType::ResolvedMethod_isSameMethod:1659{1660auto recv = client->getRecvData<uintptr_t*, uintptr_t*>();1661client->write(response, *std::get<0>(recv) == *std::get<1>(recv));1662}1663break;1664case MessageType::ResolvedMethod_isInlineable:1665{1666TR_ResolvedJ9Method *mirror = std::get<0>(client->getRecvData<TR_ResolvedJ9Method *>());1667client->write(response, mirror->isInlineable(comp));1668}1669break;1670case MessageType::ResolvedMethod_setWarmCallGraphTooBig:1671{1672auto recv = client->getRecvData<TR_ResolvedJ9Method *, uint32_t>();1673TR_ResolvedJ9Method *mirror = std::get<0>(recv);1674uint32_t bcIndex = std::get<1>(recv);1675mirror->setWarmCallGraphTooBig(bcIndex, comp);1676client->write(response, JITServer::Void());1677}1678break;1679case MessageType::ResolvedMethod_setVirtualMethodIsOverridden:1680{1681TR_ResolvedJ9Method *mirror = std::get<0>(client->getRecvData<TR_ResolvedJ9Method *>());1682mirror->setVirtualMethodIsOverridden();1683client->write(response, JITServer::Void());1684}1685break;1686case MessageType::ResolvedMethod_methodIsNotzAAPEligible:1687{1688TR_ResolvedJ9Method *mirror = std::get<0>(client->getRecvData<TR_ResolvedJ9Method *>());1689client->write(response, mirror->methodIsNotzAAPEligible());1690}1691break;1692case MessageType::ResolvedMethod_setClassForNewInstance:1693{1694auto recv = client->getRecvData<TR_ResolvedJ9Method*, J9Class*>();1695TR_ResolvedJ9Method *mirror = std::get<0>(recv);1696J9Class *clazz = std::get<1>(recv);1697mirror->setClassForNewInstance(clazz);1698client->write(response, JITServer::Void());1699}1700break;1701case MessageType::ResolvedMethod_isUnresolvedString:1702{1703auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t, bool>();1704auto mirror = std::get<0>(recv);1705auto cpIndex = std::get<1>(recv);1706auto optimizeForAOT = std::get<2>(recv);1707client->write(response, mirror->isUnresolvedString(cpIndex, optimizeForAOT));1708}1709break;1710case MessageType::ResolvedMethod_stringConstant:1711{1712auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t>();1713auto mirror = std::get<0>(recv);1714auto cpIndex = std::get<1>(recv);1715client->write(response, mirror->stringConstant(cpIndex),1716mirror->isUnresolvedString(cpIndex, true),1717mirror->isUnresolvedString(cpIndex, false));1718}1719break;1720case MessageType::ResolvedMethod_getMultipleResolvedMethods:1721{1722auto recv = client->getRecvData<TR_ResolvedJ9Method *, std::vector<TR_ResolvedMethodType>, std::vector<int32_t>>();1723auto owningMethod = std::get<0>(recv);1724auto methodTypes = std::get<1>(recv);1725auto cpIndices = std::get<2>(recv);1726int32_t numMethods = methodTypes.size();1727std::vector<TR_OpaqueMethodBlock *> ramMethods(numMethods);1728std::vector<uint32_t> vTableOffsets(numMethods);1729std::vector<TR_ResolvedJ9JITServerMethodInfo> methodInfos(numMethods);1730for (int32_t i = 0; i < numMethods; ++i)1731{1732int32_t cpIndex = cpIndices[i];1733TR_ResolvedMethodType type = methodTypes[i];1734TR_ResolvedJ9Method *resolvedMethod = NULL;1735TR_OpaqueMethodBlock *ramMethod = NULL;1736uint32_t vTableOffset = 0;1737TR_ResolvedJ9JITServerMethodInfo methodInfo;1738bool unresolvedInCP = false;1739switch (type)1740{1741case TR_ResolvedMethodType::VirtualFromCP:1742{1743resolvedMethod = static_cast<TR_ResolvedJ9Method *>(owningMethod->getResolvedPossiblyPrivateVirtualMethod(comp, cpIndex, true, &unresolvedInCP));1744vTableOffset = resolvedMethod ? resolvedMethod->vTableSlot(cpIndex) : 0;1745break;1746}1747case TR_ResolvedMethodType::Static:1748{1749resolvedMethod = static_cast<TR_ResolvedJ9Method *>(owningMethod->getResolvedStaticMethod(comp, cpIndex, &unresolvedInCP));1750break;1751}1752case TR_ResolvedMethodType::Special:1753{1754resolvedMethod = static_cast<TR_ResolvedJ9Method *>(owningMethod->getResolvedSpecialMethod(comp, cpIndex, &unresolvedInCP));1755break;1756}1757case TR_ResolvedMethodType::ImproperInterface:1758{1759resolvedMethod = static_cast<TR_ResolvedJ9Method *>(owningMethod->getResolvedImproperInterfaceMethod(comp, cpIndex));1760vTableOffset = resolvedMethod ? resolvedMethod->vTableSlot(cpIndex) : 0;1761break;1762}1763default:1764{1765break;1766}1767}1768if (resolvedMethod)1769{1770TR_ResolvedJ9JITServerMethod::packMethodInfo(methodInfo, resolvedMethod, fe);1771ramMethod = resolvedMethod->getPersistentIdentifier();1772}1773ramMethods[i] = ramMethod;1774vTableOffsets[i] = vTableOffset;1775methodInfos[i] = methodInfo;1776}1777client->write(response, ramMethods, vTableOffsets, methodInfos);1778}1779break;1780case MessageType::ResolvedMethod_getConstantDynamicTypeFromCP:1781{1782auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t>();1783auto mirror = std::get<0>(recv);1784auto cpIndex = std::get<1>(recv);17851786J9UTF8 *constantDynamicTypeUtf8 = (J9UTF8 *)mirror->getConstantDynamicTypeFromCP(cpIndex);1787int constantDynamicTypeUtf8Length = J9UTF8_LENGTH(constantDynamicTypeUtf8);1788char* constantDynamicTypeUtf8Data = (char *)J9UTF8_DATA(constantDynamicTypeUtf8);17891790client->write(response, std::string(constantDynamicTypeUtf8Data, constantDynamicTypeUtf8Length));1791}1792break;1793case MessageType::ResolvedMethod_isUnresolvedConstantDynamic:1794{1795auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t>();1796auto mirror = std::get<0>(recv);1797auto cpIndex = std::get<1>(recv);17981799client->write(response, mirror->isUnresolvedConstantDynamic(cpIndex));1800}1801break;1802case MessageType::ResolvedMethod_dynamicConstant:1803{1804auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t>();1805auto mirror = std::get<0>(recv);1806auto cpIndex = std::get<1>(recv);18071808TR::VMAccessCriticalSection condyCriticalSection(fe);1809uintptr_t obj = 0;1810uintptr_t *objLocation = (uintptr_t*)mirror->dynamicConstant(cpIndex, &obj);1811client->write(response, objLocation, obj);1812}1813break;1814case MessageType::ResolvedMethod_getResolvedImplementorMethods:1815{1816auto recv = client->getRecvData<TR_OpaqueClassBlock *, int32_t, int32_t, TR_ResolvedJ9Method *, TR_YesNoMaybe>();1817TR_OpaqueClassBlock *clazz = std::get<0>(recv);1818int32_t maxCount = std::get<1>(recv);1819int32_t slotOrIndex = std::get<2>(recv);1820TR_ResolvedJ9Method *callerMethod = std::get<3>(recv);1821TR_YesNoMaybe useGetResolvedInterfaceMethod = std::get<4>(recv);18221823TR_ResolvedMethod *implArray[maxCount];1824TR_PersistentClassInfo *classInfo = comp->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(clazz, comp, true);1825int32_t implCount =1826TR_ClassQueries::collectImplementorsCapped(1827classInfo,1828implArray,1829maxCount,1830slotOrIndex,1831callerMethod,1832comp,1833false,1834useGetResolvedInterfaceMethod);18351836// pack resolved method infos and send them back to the client1837std::vector<TR_ResolvedJ9JITServerMethodInfo> methodInfos;1838std::vector<J9Method *> ramMethods;1839if (implCount <= maxCount)1840{1841// otherwise, collection failed1842for (int32_t i = 0; i < implCount; ++i)1843{1844TR_ResolvedJ9JITServerMethodInfo methodInfo;1845TR_ResolvedJ9JITServerMethod::packMethodInfo(methodInfo, (TR_ResolvedJ9Method *) implArray[i], fe);1846methodInfos.push_back(methodInfo);1847ramMethods.push_back(static_cast<TR_ResolvedJ9Method *>(implArray[i])->ramMethod());1848}1849}1850client->write(response, methodInfos, ramMethods, implCount);1851}1852break;1853case MessageType::ResolvedMethod_isFieldFlattened:1854{1855auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t, bool>();1856auto mirror = std::get<0>(recv);1857int32_t cpIndex = std::get<1>(recv);1858bool isStatic = std::get<2>(recv);1859client->write(response, mirror->isFieldFlattened(comp, cpIndex, isStatic));1860}1861break;1862case MessageType::ResolvedRelocatableMethod_createResolvedRelocatableJ9Method:1863{1864auto recv = client->getRecvData<TR_ResolvedJ9Method *, J9Method *, int32_t, uint32_t>();1865auto mirror = std::get<0>(recv);1866auto j9method = std::get<1>(recv);1867auto cpIndex = std::get<2>(recv);1868auto vTableSlot = std::get<3>(recv);18691870bool sameLoaders = false;1871bool sameClass = false;1872bool isRomClassForMethodInSC = false;18731874// Create mirror, if possible1875TR_ResolvedJ9JITServerMethodInfo methodInfo;1876TR_ResolvedJ9JITServerMethod::createResolvedMethodFromJ9MethodMirror(methodInfo, (TR_OpaqueMethodBlock *) j9method, vTableSlot, mirror, fe, trMemory);18771878// Collect AOT stats1879TR_ResolvedJ9Method *resolvedMethod = std::get<0>(methodInfo).remoteMirror;18801881isRomClassForMethodInSC = fe->sharedCache()->isROMClassInSharedCache(J9_CLASS_FROM_METHOD(j9method)->romClass);18821883J9Class *j9clazz = (J9Class *) J9_CLASS_FROM_CP(((J9RAMConstantPoolItem *) J9_CP_FROM_METHOD(((J9Method *)j9method))));1884TR_OpaqueClassBlock *clazzOfInlinedMethod = fe->convertClassPtrToClassOffset(j9clazz);1885TR_OpaqueClassBlock *clazzOfCompiledMethod = fe->convertClassPtrToClassOffset(J9_CLASS_FROM_METHOD(mirror->ramMethod()));1886sameLoaders = fe->sameClassLoaders(clazzOfInlinedMethod, clazzOfCompiledMethod);1887if (resolvedMethod)1888sameClass = fe->convertClassPtrToClassOffset(J9_CLASS_FROM_METHOD(mirror->ramMethod())) == fe->convertClassPtrToClassOffset(J9_CLASS_FROM_METHOD(j9method));18891890client->write(response, methodInfo, isRomClassForMethodInSC, sameLoaders, sameClass);1891}1892break;1893case MessageType::ResolvedRelocatableMethod_getFieldType:1894{1895auto recv = client->getRecvData<int32_t, TR_ResolvedJ9Method *>();1896auto cpIndex = std::get<0>(recv);1897TR_ResolvedJ9Method *method= std::get<1>(recv);1898UDATA ltype = getFieldType((J9ROMConstantPoolItem *)(method->romLiterals()), cpIndex);1899client->write(response, ltype);1900}1901break;1902case MessageType::ResolvedRelocatableMethod_fieldAttributes:1903{1904auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t, bool, bool>();1905TR_ResolvedJ9Method *method = std::get<0>(recv);1906I_32 cpIndex = std::get<1>(recv);1907bool isStore = std::get<2>(recv);1908bool needAOTValidation = std::get<3>(recv);1909U_32 fieldOffset;1910TR::DataType type = TR::NoType;1911bool volatileP = true;1912bool isFinal = false;1913bool isPrivate = false;1914bool unresolvedInCP;1915bool result = method->fieldAttributes(comp, cpIndex, &fieldOffset, &type, &volatileP, &isFinal, &isPrivate, isStore, &unresolvedInCP, needAOTValidation);19161917J9ConstantPool *constantPool = (J9ConstantPool *) J9_CP_FROM_METHOD(method->ramMethod());1918TR_OpaqueClassBlock *definingClass = TR_ResolvedJ9Method::definingClassFromCPFieldRef(comp, constantPool, cpIndex, false);19191920TR_J9MethodFieldAttributes attrs(static_cast<uintptr_t>(fieldOffset), type.getDataType(), volatileP, isFinal, isPrivate, unresolvedInCP, result, definingClass);19211922client->write(response, attrs);1923}1924break;1925case MessageType::ResolvedRelocatableMethod_staticAttributes:1926{1927auto recv = client->getRecvData<TR_ResolvedJ9Method *, int32_t, bool, bool>();1928TR_ResolvedJ9Method *method = std::get<0>(recv);1929int32_t cpIndex = std::get<1>(recv);1930int32_t isStore = std::get<2>(recv);1931int32_t needAOTValidation = std::get<3>(recv);1932void *address;1933TR::DataType type = TR::NoType;1934bool volatileP = true;1935bool isFinal = false;1936bool isPrivate = false;1937bool unresolvedInCP;1938bool result = method->staticAttributes(comp, cpIndex, &address, &type, &volatileP, &isFinal, &isPrivate, isStore, &unresolvedInCP, needAOTValidation);19391940J9ConstantPool *constantPool = (J9ConstantPool *) J9_CP_FROM_METHOD(method->ramMethod());1941TR_OpaqueClassBlock *definingClass = TR_ResolvedJ9Method::definingClassFromCPFieldRef(comp, constantPool, cpIndex, true);19421943TR_J9MethodFieldAttributes attrs(reinterpret_cast<uintptr_t>(address), type.getDataType(), volatileP, isFinal, isPrivate, unresolvedInCP, result, definingClass);19441945client->write(response, attrs);1946}1947break;19481949case MessageType::CompInfo_isCompiled:1950{1951J9Method *method = std::get<0>(client->getRecvData<J9Method *>());1952client->write(response, TR::CompilationInfo::isCompiled(method));1953}1954break;1955case MessageType::CompInfo_getPCIfCompiled:1956{1957J9Method *method = std::get<0>(client->getRecvData<J9Method *>());1958client->write(response, TR::CompilationInfo::getPCIfCompiled(method));1959}1960break;1961case MessageType::CompInfo_getJ9MethodExtra:1962{1963J9Method *method = std::get<0>(client->getRecvData<J9Method *>());1964client->write(response, (uint64_t) TR::CompilationInfo::getJ9MethodExtra(method));1965}1966break;1967case MessageType::CompInfo_getInvocationCount:1968{1969J9Method *method = std::get<0>(client->getRecvData<J9Method *>());1970client->write(response, TR::CompilationInfo::getInvocationCount(method));1971}1972break;1973case MessageType::CompInfo_setInvocationCount:1974{1975auto recv = client->getRecvData<J9Method *, int32_t>();1976J9Method *method = std::get<0>(recv);1977int32_t count = std::get<1>(recv);1978client->write(response, TR::CompilationInfo::setInvocationCount(method, count));1979}1980break;1981case MessageType::CompInfo_setInvocationCountAtomic:1982{1983auto recv = client->getRecvData<J9Method *, int32_t, int32_t>();1984J9Method *method = std::get<0>(recv);1985int32_t oldCount = std::get<1>(recv);1986int32_t newCount = std::get<2>(recv);1987client->write(response, TR::CompilationInfo::setInvocationCount(method, oldCount, newCount));1988}1989break;1990case MessageType::CompInfo_isJNINative:1991{1992J9Method *method = std::get<0>(client->getRecvData<J9Method *>());1993client->write(response, TR::CompilationInfo::isJNINative(method));1994}1995break;1996case MessageType::CompInfo_isJSR292:1997{1998J9Method *method = std::get<0>(client->getRecvData<J9Method *>());1999client->write(response, TR::CompilationInfo::isJSR292(method));2000}2001break;2002case MessageType::CompInfo_getMethodBytecodeSize:2003{2004J9Method *method = std::get<0>(client->getRecvData<J9Method *>());2005client->write(response, TR::CompilationInfo::getMethodBytecodeSize(method));2006}2007break;2008case MessageType::CompInfo_setJ9MethodExtra:2009{2010auto recv = client->getRecvData<J9Method *, uint64_t>();2011J9Method *method = std::get<0>(recv);2012uint64_t count = std::get<1>(recv);2013TR::CompilationInfo::setJ9MethodExtra(method, count);2014client->write(response, JITServer::Void());2015}2016break;2017case MessageType::CompInfo_getJ9MethodStartPC:2018{2019J9Method *method = std::get<0>(client->getRecvData<J9Method *>());2020client->write(response, TR::CompilationInfo::getJ9MethodStartPC(method));2021}2022break;20232024case MessageType::ClassEnv_classFlagsValue:2025{2026auto clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());2027client->write(response, TR::Compiler->cls.classFlagsValue(clazz));2028}2029break;2030case MessageType::ClassEnv_superClassesOf:2031{2032auto clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());2033client->write(response, TR::Compiler->cls.superClassesOf(clazz));2034}2035break;2036case MessageType::ClassEnv_iTableOf:2037{2038auto clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());2039client->write(response, TR::Compiler->cls.iTableOf(clazz));2040}2041break;2042case MessageType::ClassEnv_iTableNext:2043{2044auto clazz = std::get<0>(client->getRecvData<J9ITable *>());2045client->write(response, TR::Compiler->cls.iTableNext(clazz));2046}2047break;2048case MessageType::ClassEnv_iTableRomClass:2049{2050auto clazz = std::get<0>(client->getRecvData<J9ITable *>());2051client->write(response, TR::Compiler->cls.iTableRomClass(clazz));2052}2053break;2054case MessageType::ClassEnv_getITable:2055{2056auto clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());2057client->write(response, TR::Compiler->cls.getITable(clazz));2058}2059break;2060case MessageType::ClassEnv_indexedSuperClassOf:2061{2062auto recv = client->getRecvData<TR_OpaqueClassBlock *, size_t>();2063auto clazz = std::get<0>(recv);2064size_t index = std::get<1>(recv);2065client->write(response, TR::Compiler->cls.superClassesOf(clazz)[index]);2066}2067break;2068case MessageType::ClassEnv_isClassRefValueType:2069{2070auto recv = client->getRecvData<TR_OpaqueClassBlock *, int32_t>();2071auto clazz = std::get<0>(recv);2072auto cpIndex = std::get<1>(recv);2073client->write(response, TR::Compiler->cls.isClassRefValueType(comp, clazz, cpIndex));2074}2075break;2076case MessageType::ClassEnv_flattenedArrayElementSize:2077{2078auto recv = client->getRecvData<TR_OpaqueClassBlock *>();2079auto arrayClass = std::get<0>(recv);2080client->write(response, TR::Compiler->cls.flattenedArrayElementSize(comp, arrayClass));2081}2082break;2083case MessageType::ClassEnv_enumerateFields:2084{2085auto recv = client->getRecvData<TR_OpaqueClassBlock *>();2086const TR::TypeLayout* layout = comp->typeLayout(std::get<0>(recv));20872088std::vector<TR::TypeLayoutEntry> entries;2089std::vector<std::string> fieldNames;2090std::vector<std::string> typeSignatures;2091entries.reserve(layout->count());2092fieldNames.reserve(layout->count());2093typeSignatures.reserve(layout->count());2094for (int32_t idx = 0; idx < layout->count(); ++idx)2095{2096const TR::TypeLayoutEntry &entry = layout->entry(idx);2097entries.push_back(entry);2098// both strings are null-terminated so we don't need to know length2099fieldNames.push_back(std::string(entry._fieldname));2100typeSignatures.push_back(std::string(entry._typeSignature));2101}2102client->write(response, entries, fieldNames, typeSignatures);2103}2104break;2105case MessageType::SharedCache_getClassChainOffsetIdentifyingLoader:2106{2107auto recv = client->getRecvData<TR_OpaqueClassBlock *, bool>();2108auto j9class = std::get<0>(recv);2109bool getName = std::get<1>(recv);2110auto sharedCache = fe->sharedCache();2111uintptr_t *chain = NULL;2112uintptr_t offset = sharedCache->getClassChainOffsetIdentifyingLoader(j9class, &chain);2113std::string nameStr;2114if (getName && chain)2115{2116const J9UTF8 *name = J9ROMCLASS_CLASSNAME(sharedCache->startingROMClassOfClassChain(chain));2117nameStr = std::string((const char *)J9UTF8_DATA(name), J9UTF8_LENGTH(name));2118}2119client->write(response, offset, nameStr);2120}2121break;2122case MessageType::SharedCache_rememberClass:2123{2124auto recv = client->getRecvData<J9Class *, bool, bool>();2125auto clazz = std::get<0>(recv);2126bool create = std::get<1>(recv);2127bool getClasses = std::get<2>(recv);2128uintptr_t *classChain = fe->sharedCache()->rememberClass(clazz, NULL, create);2129std::vector<J9Class *> ramClassChain;2130std::vector<J9Class *> uncachedRAMClasses;2131std::vector<JITServerHelpers::ClassInfoTuple> uncachedClassInfos;2132if (create && getClasses && classChain)2133{2134// The first word of the class chain data stores the size of the whole record in bytes2135uintptr_t numClasses = classChain[0] / sizeof(classChain[0]) - 1;2136ramClassChain = JITServerHelpers::getRAMClassChain(clazz, numClasses, vmThread, trMemory, compInfo,2137uncachedRAMClasses, uncachedClassInfos);2138}2139client->write(response, classChain, ramClassChain, uncachedRAMClasses, uncachedClassInfos);2140}2141break;2142case MessageType::SharedCache_addHint:2143{2144auto recv = client->getRecvData<J9Method *, TR_SharedCacheHint>();2145auto method = std::get<0>(recv);2146auto hint = std::get<1>(recv);2147if (fe->sharedCache())2148fe->sharedCache()->addHint(method, hint);2149client->write(response, JITServer::Void());2150}2151break;2152case MessageType::SharedCache_storeSharedData:2153{2154auto recv = client->getRecvData<std::string, J9SharedDataDescriptor, std::string>();2155auto key = std::get<0>(recv);2156auto descriptor = std::get<1>(recv);2157auto dataStr = std::get<2>(recv);2158descriptor.address = (U_8 *) &dataStr[0];2159auto ptr = fe->sharedCache()->storeSharedData(vmThread, (char *) key.data(), &descriptor);2160client->write(response, ptr);2161}2162break;2163case MessageType::runFEMacro_invokeILGenMacrosInvokeExactAndFixup:2164{2165auto recv = client->getRecvData<uintptr_t*, std::vector<uintptr_t> >();2166TR::VMAccessCriticalSection invokeILGenMacrosInvokeExactAndFixup(fe);2167uintptr_t receiverHandle = *std::get<0>(recv);2168const std::vector<uintptr_t>& listOfOffsets = std::get<1>(recv);2169uintptr_t methodHandle = listOfOffsets.size() == 0 ? receiverHandle : JITServerHelpers::walkReferenceChainWithOffsets(fe, listOfOffsets, receiverHandle);2170uintptr_t methodDescriptorRef = fe->getReferenceField(fe->getReferenceField(2171methodHandle,2172"type", "Ljava/lang/invoke/MethodType;"),2173"methodDescriptor", "Ljava/lang/String;");2174intptr_t methodDescriptorLength = fe->getStringUTF8Length(methodDescriptorRef);2175char *methodDescriptor = (char*)alloca(methodDescriptorLength+1);2176fe->getStringUTF8(methodDescriptorRef, methodDescriptor, methodDescriptorLength+1);2177client->write(response, std::string(methodDescriptor, methodDescriptorLength));2178}2179break;2180case MessageType::runFEMacro_invokeCollectHandleNumArgsToCollect:2181{2182auto recv = client->getRecvData<uintptr_t*, bool>();2183TR::VMAccessCriticalSection invokeCollectHandleNumArgsToCollect(fe);2184uintptr_t methodHandle = *std::get<0>(recv);2185bool getPos = std::get<1>(recv);2186int32_t collectArraySize = fe->getInt32Field(methodHandle, "collectArraySize");2187uintptr_t arguments = fe->getReferenceField(2188fe->getReferenceField(methodHandle, "type", "Ljava/lang/invoke/MethodType;"),2189"ptypes", "[Ljava/lang/Class;");2190int32_t numArguments = (int32_t)fe->getArrayLengthInElements(arguments);2191int32_t collectionStart = 0;2192if (getPos)2193collectionStart = fe->getInt32Field(methodHandle, "collectPosition");2194client->write(response, collectArraySize, numArguments, collectionStart);2195}2196break;2197case MessageType::runFEMacro_invokeGuardWithTestHandleNumGuardArgs:2198{2199auto recv = client->getRecvData<uintptr_t*>();2200TR::VMAccessCriticalSection invokeGuardWithTestHandleNumGuardArgs(fe);2201uintptr_t methodHandle = *std::get<0>(recv);2202uintptr_t guardArgs = fe->getReferenceField(fe->methodHandle_type(fe->getReferenceField(methodHandle,2203"guard", "Ljava/lang/invoke/MethodHandle;")),2204"ptypes", "[Ljava/lang/Class;");2205int32_t numGuardArgs = (int32_t)fe->getArrayLengthInElements(guardArgs);2206client->write(response, numGuardArgs);2207}2208break;2209case MessageType::runFEMacro_invokeExplicitCastHandleConvertArgs:2210{2211auto recv = client->getRecvData<uintptr_t*>();2212TR::VMAccessCriticalSection invokeExplicitCastHandleConvertArgs(fe);2213uintptr_t methodHandle = *std::get<0>(recv);2214uintptr_t methodDescriptorRef = fe->getReferenceField(fe->getReferenceField(fe->getReferenceField(2215methodHandle,2216"next", "Ljava/lang/invoke/MethodHandle;"),2217"type", "Ljava/lang/invoke/MethodType;"),2218"methodDescriptor", "Ljava/lang/String;");2219size_t methodDescriptorLength = fe->getStringUTF8Length(methodDescriptorRef);2220char *methodDescriptor = (char*)alloca(methodDescriptorLength+1);2221fe->getStringUTF8(methodDescriptorRef, methodDescriptor, methodDescriptorLength+1);2222client->write(response, std::string(methodDescriptor, methodDescriptorLength));2223}2224break;2225case MessageType::runFEMacro_targetTypeL:2226{2227auto recv = client->getRecvData<uintptr_t*, int32_t>();2228TR::VMAccessCriticalSection targetTypeL(fe);2229uintptr_t methodHandle = *std::get<0>(recv);2230int32_t argIndex = std::get<1>(recv);2231uintptr_t targetArguments = fe->getReferenceField(fe->getReferenceField(fe->getReferenceField(2232methodHandle,2233"next", "Ljava/lang/invoke/MethodHandle;"),2234"type", "Ljava/lang/invoke/MethodType;"),2235"ptypes", "[Ljava/lang/Class;");2236TR_OpaqueClassBlock *targetParmClass = (TR_OpaqueClassBlock*)(intptr_t)fe->getInt64Field(fe->getReferenceElement(targetArguments, argIndex),2237"vmRef" /* should use fej9->getOffsetOfClassFromJavaLangClassField() */);2238// Load callsite type and check if two types are compatible2239uintptr_t sourceArguments = fe->getReferenceField(fe->getReferenceField(2240methodHandle,2241"type", "Ljava/lang/invoke/MethodType;"),2242"ptypes", "[Ljava/lang/Class;");2243TR_OpaqueClassBlock *sourceParmClass = (TR_OpaqueClassBlock*)(intptr_t)fe->getInt64Field(fe->getReferenceElement(sourceArguments, argIndex),2244"vmRef" /* should use fej9->getOffsetOfClassFromJavaLangClassField() */);2245client->write(response, sourceParmClass, targetParmClass);2246}2247break;2248case MessageType::runFEMacro_invokeSpreadHandleArrayArg:2249{2250auto recv = client->getRecvData<uintptr_t*>();2251TR::VMAccessCriticalSection invokeSpreadHandleArrayArg(fe);2252uintptr_t methodHandle = *std::get<0>(recv);2253uintptr_t arrayClass = fe->getReferenceField(methodHandle, "arrayClass", "Ljava/lang/Class;");2254J9ArrayClass *arrayJ9Class = (J9ArrayClass*)(intptr_t)fe->getInt64Field(arrayClass,2255"vmRef" /* should use fej9->getOffsetOfClassFromJavaLangClassField() */);2256J9Class *leafClass = arrayJ9Class->leafComponentType;2257UDATA arity = arrayJ9Class->arity;2258uint32_t spreadPositionOffset = fe->getInstanceFieldOffset(fe->getObjectClass(methodHandle), "spreadPosition", "I");2259int32_t spreadPosition = -1;2260if (spreadPositionOffset != ~0)2261spreadPosition = fe->getInt32FieldAt(methodHandle, spreadPositionOffset);22622263int32_t leafClassNameLength;2264char *leafClassNameChars = fe->getClassNameChars((TR_OpaqueClassBlock*)leafClass, leafClassNameLength);2265bool isPrimitive = TR::Compiler->cls.isPrimitiveClass(comp, (TR_OpaqueClassBlock*)leafClass);2266client->write(response, arrayJ9Class, spreadPosition, arity, leafClass, std::string(leafClassNameChars, leafClassNameLength), isPrimitive);2267}2268break;2269case MessageType::runFEMacro_invokeSpreadHandle:2270{2271auto recv = client->getRecvData<uintptr_t*, bool>();2272TR::VMAccessCriticalSection invokeSpreadHandle(fe);2273uintptr_t methodHandle = *std::get<0>(recv);2274bool getSpreadPosition = std::get<1>(recv);2275uintptr_t arguments = fe->getReferenceField(fe->methodHandle_type(methodHandle), "ptypes", "[Ljava/lang/Class;");2276int32_t numArguments = (int32_t)fe->getArrayLengthInElements(arguments);2277uintptr_t next = fe->getReferenceField(methodHandle, "next", "Ljava/lang/invoke/MethodHandle;");2278uintptr_t nextArguments = fe->getReferenceField(fe->methodHandle_type(next), "ptypes", "[Ljava/lang/Class;");2279int32_t numNextArguments = (int32_t)fe->getArrayLengthInElements(nextArguments);2280int32_t spreadStart = 0;2281// Guard to protect old code2282if (getSpreadPosition)2283spreadStart = fe->getInt32Field(methodHandle, "spreadPosition");2284client->write(response, numArguments, numNextArguments, spreadStart);2285}2286break;2287case MessageType::runFEMacro_invokeInsertHandle:2288{2289auto recv = client->getRecvData<uintptr_t*>();2290TR::VMAccessCriticalSection invokeInsertHandle(fe);2291uintptr_t methodHandle = *std::get<0>(recv);2292int32_t insertionIndex = fe->getInt32Field(methodHandle, "insertionIndex");2293uintptr_t arguments = fe->getReferenceField(fe->getReferenceField(methodHandle, "type",2294"Ljava/lang/invoke/MethodType;"), "ptypes", "[Ljava/lang/Class;");2295int32_t numArguments = (int32_t)fe->getArrayLengthInElements(arguments);2296uintptr_t values = fe->getReferenceField(methodHandle, "values", "[Ljava/lang/Object;");2297int32_t numValues = (int32_t)fe->getArrayLengthInElements(values);2298client->write(response, insertionIndex, numArguments, numValues);2299}2300break;2301case MessageType::runFEMacro_invokeFoldHandle:2302{2303auto recv = client->getRecvData<uintptr_t*>();2304TR::VMAccessCriticalSection invokeFoldHandle(fe);2305uintptr_t methodHandle = *std::get<0>(recv);2306uintptr_t argIndices = fe->getReferenceField(methodHandle, "argumentIndices", "[I");2307int32_t arrayLength = (int32_t)fe->getArrayLengthInElements(argIndices);2308int32_t foldPosition = fe->getInt32Field(methodHandle, "foldPosition");2309std::vector<int32_t> indices(arrayLength);2310int32_t numArgs = 0;2311if (arrayLength != 0)2312{2313// Put indices in the original order, reversal is done on the server2314for (int i = 0; i < arrayLength; i++)2315{2316indices[i] = fe->getInt32Element(argIndices, i);2317}2318}2319else2320{2321uintptr_t combiner = fe->getReferenceField(methodHandle, "combiner", "Ljava/lang/invoke/MethodHandle;");2322uintptr_t combinerArguments = fe->getReferenceField(fe->methodHandle_type(combiner), "ptypes", "[Ljava/lang/Class;");2323numArgs = (int32_t)fe->getArrayLengthInElements(combinerArguments);2324}2325client->write(response, indices, foldPosition, numArgs);2326}2327break;2328case MessageType::runFEMacro_invokeFoldHandle2:2329{2330auto recv = client->getRecvData<uintptr_t*>();2331TR::VMAccessCriticalSection invokeFoldHandle(fe);2332uintptr_t methodHandle = *std::get<0>(recv);2333int32_t foldPosition = fe->getInt32Field(methodHandle, "foldPosition");2334client->write(response, foldPosition);2335}2336break;2337case MessageType::runFEMacro_invokeFilterArgumentsWithCombinerHandleArgumentIndices:2338{2339auto recv = client->getRecvData<uintptr_t*>();2340TR::VMAccessCriticalSection invokeFilterArgumentsWithCombinerHandle(fe);2341uintptr_t methodHandle = *std::get<0>(recv);2342uintptr_t argumentIndices = fe->getReferenceField(methodHandle, "argumentIndices", "[I");2343int32_t arrayLength = fe->getArrayLengthInElements(argumentIndices);2344std::vector<int32_t> argIndices(arrayLength);2345for (int i = arrayLength - 1; i >= 0; i--)2346{2347argIndices[i] = fe->getInt32Element(argumentIndices, i);2348}2349client->write(response, arrayLength, argIndices);2350}2351break;2352case MessageType::runFEMacro_invokeFilterArgumentsWithCombinerHandleFilterPosition:2353{2354auto recv = client->getRecvData<uintptr_t*>();2355TR::VMAccessCriticalSection invokeFilterArgumentsWithCombinerHandle(fe);2356uintptr_t methodHandle = *std::get<0>(recv);2357int32_t filterPosition = fe->getInt32Field(methodHandle, "filterPosition");2358client->write(response, filterPosition);2359}2360break;2361case MessageType::runFEMacro_invokeFinallyHandle:2362{2363auto recv = client->getRecvData<uintptr_t*>();2364TR::VMAccessCriticalSection invokeFinallyHandle(fe);2365uintptr_t methodHandle = *std::get<0>(recv);2366uintptr_t finallyTarget = fe->getReferenceField(methodHandle, "finallyTarget", "Ljava/lang/invoke/MethodHandle;");2367uintptr_t finallyType = fe->getReferenceField(finallyTarget, "type", "Ljava/lang/invoke/MethodType;");2368uintptr_t arguments = fe->getReferenceField(finallyType, "ptypes", "[Ljava/lang/Class;");2369int32_t numArgsPassToFinallyTarget = (int32_t)fe->getArrayLengthInElements(arguments);23702371uintptr_t methodDescriptorRef = fe->getReferenceField(finallyType, "methodDescriptor", "Ljava/lang/String;");2372int methodDescriptorLength = fe->getStringUTF8Length(methodDescriptorRef);2373char *methodDescriptor = (char*)alloca(methodDescriptorLength+1);2374fe->getStringUTF8(methodDescriptorRef, methodDescriptor, methodDescriptorLength+1);2375client->write(response, numArgsPassToFinallyTarget, std::string(methodDescriptor, methodDescriptorLength));2376}2377break;2378case MessageType::runFEMacro_invokeFilterArgumentsWithCombinerHandleNumSuffixArgs:2379{2380auto recv = client->getRecvData<uintptr_t*>();2381TR::VMAccessCriticalSection invokeFilterArgumentsWithCombinerHandle(fe);2382uintptr_t methodHandle = *std::get<0>(recv);2383uintptr_t arguments = fe->getReferenceField(fe->methodHandle_type(methodHandle), "ptypes", "[Ljava/lang/Class;");2384int32_t numArguments = (int32_t)fe->getArrayLengthInElements(arguments);2385int32_t filterPos = (int32_t)fe->getInt32Field(methodHandle, "filterPosition");2386client->write(response, numArguments, filterPos);2387}2388break;2389case MessageType::runFEMacro_invokeFilterArgumentsHandle:2390{2391auto recv = client->getRecvData<uintptr_t*, bool>();2392uintptr_t methodHandle = *std::get<0>(recv);2393bool knotEnabled = std::get<1>(recv);23942395int32_t startPos = 0;2396std::string nextSignatureString;2397std::vector<uint8_t> haveFilterList;2398std::vector<TR::KnownObjectTable::Index> filterIndexList;2399std::vector<uintptr_t *> filterObjectReferenceLocationList;24002401{2402TR::VMAccessCriticalSection invokeFilterArgumentsHandle(fe);2403uintptr_t filters = fe->getReferenceField(methodHandle, "filters", "[Ljava/lang/invoke/MethodHandle;");2404int32_t numFilters = fe->getArrayLengthInElements(filters);2405haveFilterList.resize(numFilters);2406filterIndexList.resize(numFilters);2407filterObjectReferenceLocationList.resize(numFilters);24082409for (int i = 0; i < numFilters; i++)2410{2411haveFilterList[i] = (fe->getReferenceElement(filters, i) != 0) ? 1 : 0;2412if (knotEnabled)2413{2414filterIndexList[i] = knot->getOrCreateIndex(fe->getReferenceElement(filters, i));2415filterObjectReferenceLocationList[i] = knot->getPointerLocation(filterIndexList[i]);2416}2417}24182419startPos = (int32_t)fe->getInt32Field(methodHandle, "startPos");2420uintptr_t methodDescriptorRef = fe->getReferenceField(fe->getReferenceField(fe->getReferenceField(2421methodHandle,2422"next", "Ljava/lang/invoke/MethodHandle;"),2423"type", "Ljava/lang/invoke/MethodType;"),2424"methodDescriptor", "Ljava/lang/String;");2425intptr_t methodDescriptorLength = fe->getStringUTF8Length(methodDescriptorRef);2426char *nextSignature = (char*)alloca(methodDescriptorLength+1);2427fe->getStringUTF8(methodDescriptorRef, nextSignature, methodDescriptorLength+1);2428nextSignatureString.assign(nextSignature, methodDescriptorLength);2429}24302431client->write(response, startPos, nextSignatureString, haveFilterList, filterIndexList, filterObjectReferenceLocationList);2432}2433break;2434case MessageType::runFEMacro_invokeFilterArgumentsHandle2:2435{2436auto recv = client->getRecvData<uintptr_t*>();2437TR::VMAccessCriticalSection invokeFilderArgumentsHandle(fe);2438uintptr_t methodHandle = *std::get<0>(recv);2439uintptr_t arguments = fe->getReferenceField(fe->methodHandle_type(methodHandle), "ptypes", "[Ljava/lang/Class;");2440int32_t numArguments = (int32_t)fe->getArrayLengthInElements(arguments);2441int32_t startPos = (int32_t)fe->getInt32Field(methodHandle, "startPos");2442uintptr_t filters = fe->getReferenceField(methodHandle, "filters", "[Ljava/lang/invoke/MethodHandle;");2443int32_t numFilters = fe->getArrayLengthInElements(filters);2444client->write(response, numArguments, startPos, numFilters);2445}2446break;2447case MessageType::runFEMacro_invokeCatchHandle:2448{2449auto recv = client->getRecvData<uintptr_t*>();2450TR::VMAccessCriticalSection invokeCatchHandle(fe);2451uintptr_t methodHandle = *std::get<0>(recv);2452uintptr_t catchTarget = fe->getReferenceField(methodHandle, "catchTarget", "Ljava/lang/invoke/MethodHandle;");2453uintptr_t catchArguments = fe->getReferenceField(fe->getReferenceField(2454catchTarget,2455"type", "Ljava/lang/invoke/MethodType;"),2456"ptypes", "[Ljava/lang/Class;");2457int32_t numCatchArguments = (int32_t)fe->getArrayLengthInElements(catchArguments);2458client->write(response, numCatchArguments);2459}2460break;2461case MessageType::runFEMacro_invokeArgumentMoverHandlePermuteArgs:2462{2463auto recv = client->getRecvData<uintptr_t*>();2464TR::VMAccessCriticalSection invokeArgumentMoverHandlePermuteArgs(fe);2465uintptr_t methodHandle = *std::get<0>(recv);2466uintptr_t methodDescriptorRef = fe->getReferenceField(fe->getReferenceField(fe->getReferenceField(2467methodHandle,2468"next", "Ljava/lang/invoke/MethodHandle;"),2469"type", "Ljava/lang/invoke/MethodType;"),2470"methodDescriptor", "Ljava/lang/String;");2471intptr_t methodDescriptorLength = fe->getStringUTF8Length(methodDescriptorRef);2472char *nextHandleSignature = (char*)alloca(methodDescriptorLength+1);2473fe->getStringUTF8(methodDescriptorRef, nextHandleSignature, methodDescriptorLength+1);2474client->write(response, std::string(nextHandleSignature, methodDescriptorLength));2475}2476break;2477case MessageType::runFEMacro_invokePermuteHandlePermuteArgs:2478{2479auto recv = client->getRecvData<uintptr_t*>();2480TR::VMAccessCriticalSection invokePermuteHandlePermuteArgs(fe);2481uintptr_t methodHandle = *std::get<0>(recv);2482uintptr_t permuteArray = fe->getReferenceField(methodHandle, "permute", "[I");2483int32_t permuteLength = fe->getArrayLengthInElements(permuteArray);2484std::vector<int32_t> argIndices(permuteLength);2485for (int32_t i=0; i < permuteLength; i++)2486{2487argIndices[i] = fe->getInt32Element(permuteArray, i);2488}2489client->write(response, permuteLength, argIndices);2490}2491break;2492case MessageType::runFEMacro_invokeILGenMacrosParameterCount:2493{2494auto recv = client->getRecvData<uintptr_t*, std::vector<uintptr_t> >();2495TR::VMAccessCriticalSection invokeILGenMacrosParameterCount(fe);2496uintptr_t receiverHandle = *std::get<0>(recv);2497const std::vector<uintptr_t>& listOfOffsets = std::get<1>(recv);2498uintptr_t methodHandle = JITServerHelpers::walkReferenceChainWithOffsets(fe, listOfOffsets, receiverHandle);2499uintptr_t arguments = fe->getReferenceField(fe->getReferenceField(2500methodHandle,2501"type", "Ljava/lang/invoke/MethodType;"),2502"ptypes", "[Ljava/lang/Class;");2503int32_t parameterCount = (int32_t)fe->getArrayLengthInElements(arguments);2504client->write(response, parameterCount);2505}2506break;2507case MessageType::runFEMacro_invokeILGenMacrosArrayLength:2508{2509auto recv = client->getRecvData<uintptr_t*, std::vector<uintptr_t> >();2510TR::VMAccessCriticalSection invokeILGenMacrosArrayLength(fe);2511uintptr_t receiverHandle = *std::get<0>(recv);2512const std::vector<uintptr_t>& listOfOffsets = std::get<1>(recv);2513uintptr_t array = JITServerHelpers::walkReferenceChainWithOffsets(fe, listOfOffsets, receiverHandle);2514int32_t arrayLength = (int32_t)fe->getArrayLengthInElements(array);2515client->write(response, arrayLength);2516}2517break;2518case MessageType::runFEMacro_invokeILGenMacrosGetField:2519{2520auto recv = client->getRecvData<uintptr_t*, uintptr_t, std::vector<uintptr_t> >();2521TR::VMAccessCriticalSection invokeILGenMacrosGetField(fe);2522uintptr_t receiverHandle = *std::get<0>(recv);2523uintptr_t fieldOffset = std::get<1>(recv);2524const std::vector<uintptr_t>& listOfOffsets = std::get<2>(recv);2525uintptr_t baseObject = JITServerHelpers::walkReferenceChainWithOffsets(fe, listOfOffsets, receiverHandle);2526int32_t result = fe->getInt32FieldAt(baseObject, fieldOffset);2527client->write(response, result);2528}2529break;2530case MessageType::runFEMacro_invokeCollectHandleAllocateArray:2531{2532auto recv = client->getRecvData<TR::KnownObjectTable::Index>();2533TR::KnownObjectTable::Index knotIndex = std::get<0>(recv);2534int32_t collectArraySize = 0;2535int32_t collectPosition = 0;2536TR_OpaqueClassBlock *componentClazz = NULL;25372538{2539TR::VMAccessCriticalSection invokeCollectHandleAllocateArray(fe);2540uintptr_t methodHandle = knot->getPointer(knotIndex);2541collectArraySize = fe->getInt32Field(methodHandle, "collectArraySize");2542collectPosition = fe->getInt32Field(methodHandle, "collectPosition");2543uintptr_t arguments = fe->getReferenceField(fe->getReferenceField(fe->getReferenceField(2544methodHandle,2545"next", "Ljava/lang/invoke/MethodHandle;"),2546"type", "Ljava/lang/invoke/MethodType;"),2547"ptypes", "[Ljava/lang/Class;");2548componentClazz = fe->getComponentClassFromArrayClass(fe->getClassFromJavaLangClass(fe->getReferenceElement(arguments, collectPosition)));2549}25502551client->write(response, collectArraySize, collectPosition, componentClazz);2552}2553break;2554case MessageType::CHTable_clearReservable:2555{2556auto clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock*>());2557client->write(response, JITServer::Void());2558auto table = (JITClientPersistentCHTable*)comp->getPersistentInfo()->getPersistentCHTable();2559auto info = table->findClassInfoAfterLocking(clazz, comp);2560info->setReservable(false);2561}2562break;2563case MessageType::IProfiler_searchForMethodSample:2564{2565auto recv = client->getRecvData<TR_OpaqueMethodBlock*>();2566auto method = std::get<0>(recv);2567JITClientIProfiler *iProfiler = (JITClientIProfiler *) fe->getIProfiler();2568client->write(response, iProfiler->serializeIProfilerMethodEntry(method));2569}2570break;2571case MessageType::IProfiler_profilingSample:2572{2573handler_IProfiler_profilingSample(client, fe, comp);2574}2575break;2576case MessageType::IProfiler_getMaxCallCount:2577{2578TR_IProfiler *iProfiler = fe->getIProfiler();2579client->write(response, iProfiler->getMaxCallCount());2580}2581break;2582case MessageType::IProfiler_setCallCount:2583{2584auto recv = client->getRecvData<TR_OpaqueMethodBlock*, int32_t, int32_t>();2585auto method = std::get<0>(recv);2586auto bcIndex = std::get<1>(recv);2587auto count = std::get<2>(recv);2588TR_IProfiler * iProfiler = fe->getIProfiler();2589iProfiler->setCallCount(method, bcIndex, count, comp);25902591client->write(response, TR::CompilationInfo::isCompiled((J9Method *)method));2592}2593break;2594case MessageType::Recompilation_getJittedBodyInfoFromPC:2595{2596void *startPC = std::get<0>(client->getRecvData<void *>());2597auto bodyInfo = J9::Recompilation::getJittedBodyInfoFromPC(startPC);2598if (!bodyInfo)2599client->write(response, std::string(), std::string());2600else2601client->write(response, std::string((char*) bodyInfo, sizeof(TR_PersistentJittedBodyInfo)),2602std::string((char*) bodyInfo->getMethodInfo(), sizeof(TR_PersistentMethodInfo)));2603}2604break;2605case MessageType::KnownObjectTable_getOrCreateIndex:2606{2607uintptr_t objectPointer = std::get<0>(client->getRecvData<uintptr_t>());2608TR::KnownObjectTable::Index index = TR::KnownObjectTable::UNKNOWN;2609uintptr_t *objectPointerReference = NULL;26102611{2612TR::VMAccessCriticalSection knownObjectTableGetIndex(fe);2613index = knot->getOrCreateIndex(objectPointer);2614objectPointerReference = knot->getPointerLocation(index);2615}26162617client->write(response, index, objectPointerReference);2618}2619break;2620case MessageType::KnownObjectTable_getOrCreateIndexAt:2621{2622uintptr_t *objectPointerReferenceServerQuery = std::get<0>(client->getRecvData<uintptr_t*>());2623TR::KnownObjectTable::Index index = knot->getOrCreateIndexAt(objectPointerReferenceServerQuery);2624client->write(response, index, knot->getPointerLocation(index));2625}2626break;2627case MessageType::KnownObjectTable_getPointer:2628{2629TR::KnownObjectTable::Index knotIndex = std::get<0>(client->getRecvData<TR::KnownObjectTable::Index>());2630uintptr_t objectPointer = 0;26312632{2633TR::VMAccessCriticalSection knownObjectTableGetPointer(fe);2634objectPointer = knot->getPointer(knotIndex);2635}26362637client->write(response, objectPointer);2638}2639break;2640case MessageType::KnownObjectTable_getExistingIndexAt:2641{2642uintptr_t *objectPointerReference = std::get<0>(client->getRecvData<uintptr_t*>());2643client->write(response, knot->getExistingIndexAt(objectPointerReference));2644}2645break;2646case MessageType::KnownObjectTable_symbolReferenceTableCreateKnownObject:2647{2648auto recv = client->getRecvData<void *, TR_ResolvedMethod *, int32_t>();2649void *dataAddress = std::get<0>(recv);2650TR_ResolvedMethod *owningMethod = std::get<1>(recv);2651int32_t cpIndex = std::get<2>(recv);26522653TR::KnownObjectTable::Index knotIndex =2654TR::TransformUtil::knownObjectFromFinalStatic(2655comp, owningMethod, cpIndex, dataAddress);26562657uintptr_t *objectPointerReference = NULL;2658if (knotIndex != TR::KnownObjectTable::UNKNOWN)2659{2660objectPointerReference =2661comp->getKnownObjectTable()->getPointerLocation(knotIndex);2662}26632664client->write(response, knotIndex, objectPointerReference);2665}2666break;2667case MessageType::KnownObjectTable_mutableCallSiteEpoch:2668{2669auto recv = client->getRecvData<uintptr_t*, bool>();2670uintptr_t* mcsReferenceLocation = std::get<0>(recv);2671bool knotEnabled = std::get<1>(recv);26722673uintptr_t mcsObject = 0;2674TR::KnownObjectTable::Index knotIndex = TR::KnownObjectTable::UNKNOWN;2675uintptr_t *objectPointerReference = NULL;26762677{2678TR::VMAccessCriticalSection mutableCallSiteEpoch(fe);2679mcsObject = fe->getStaticReferenceFieldAtAddress((uintptr_t)mcsReferenceLocation);2680if (mcsObject && knotEnabled && knot)2681{2682TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe);2683knotIndex = fej9->mutableCallSiteEpoch(comp, mcsObject);2684if (knotIndex != TR::KnownObjectTable::UNKNOWN)2685objectPointerReference = knot->getPointerLocation(knotIndex);2686}2687}26882689client->write(response, mcsObject, knotIndex, objectPointerReference);2690}2691break;2692case MessageType::KnownObjectTable_dereferenceKnownObjectField:2693{2694auto recv = client->getRecvData<TR::KnownObjectTable::Index, TR_ResolvedMethod *, int32_t>();2695TR::KnownObjectTable::Index baseObjectIndex = std::get<0>(recv);2696TR_ResolvedMethod *calleeMethod = std::get<1>(recv);2697int32_t cpIndex = std::get<2>(recv);26982699TR::KnownObjectTable::Index resultIndex = TR::KnownObjectTable::UNKNOWN;2700uintptr_t *objectPointerReference = NULL;2701uintptr_t fieldAddress = 0;2702uintptr_t baseObjectAddress = 0;2703bool avoidFolding = true;27042705TR::DataType type;2706uint32_t fieldOffset;2707TR::Symbol *fieldSymbol = TR::Symbol::createPossiblyRecognizedShadowFromCP(2708comp, trMemory->trStackMemory(), calleeMethod, cpIndex, &type, &fieldOffset, false);27092710if (fieldSymbol != NULL)2711{2712TR::VMAccessCriticalSection dereferenceKnownObjectField(fe);2713baseObjectAddress = knot->getPointer(baseObjectIndex);2714TR_OpaqueClassBlock *baseObjectClass = fe->getObjectClass(baseObjectAddress);2715TR_OpaqueClassBlock *fieldDeclaringClass = calleeMethod->getDeclaringClassFromFieldOrStatic(comp, cpIndex);27162717avoidFolding = TR::TransformUtil::avoidFoldingInstanceField(2718baseObjectAddress, fieldSymbol, fieldOffset, cpIndex, calleeMethod, comp);27192720if (fieldDeclaringClass && fe->isInstanceOf(baseObjectClass, fieldDeclaringClass, true) == TR_yes)2721{2722fieldAddress = fe->getReferenceFieldAtAddress(baseObjectAddress + fieldOffset);2723resultIndex = knot->getOrCreateIndex(fieldAddress);2724objectPointerReference = knot->getPointerLocation(resultIndex);2725}2726}27272728client->write(response, resultIndex, objectPointerReference, fieldAddress, baseObjectAddress, avoidFolding);2729}2730break;2731case MessageType::KnownObjectTable_dereferenceKnownObjectField2:2732{2733auto recv = client->getRecvData<TR_OpaqueClassBlock*, TR::KnownObjectTable::Index>();2734TR_OpaqueClassBlock *mutableCallsiteClass = std::get<0>(recv);2735TR::KnownObjectTable::Index receiverIndex = std::get<1>(recv);27362737TR::KnownObjectTable::Index resultIndex = TR::KnownObjectTable::UNKNOWN;2738uintptr_t *objectPointerReference = NULL;27392740{2741TR::VMAccessCriticalSection dereferenceKnownObjectField(fe);2742int32_t targetFieldOffset = fe->getInstanceFieldOffset(mutableCallsiteClass, "target", "Ljava/lang/invoke/MethodHandle;");2743uintptr_t receiverAddress = knot->getPointer(receiverIndex);2744TR_OpaqueClassBlock *receiverClass = fe->getObjectClass(receiverAddress);2745TR_ASSERT_FATAL(fe->isInstanceOf(receiverClass, mutableCallsiteClass, true) == TR_yes, "receiver of mutableCallsite_getTarget must be instance of MutableCallSite (*%p)", knot->getPointerLocation(receiverIndex));2746uintptr_t fieldAddress = fe->getReferenceFieldAt(receiverAddress, targetFieldOffset);27472748resultIndex = knot->getOrCreateIndex(fieldAddress);2749objectPointerReference = knot->getPointerLocation(resultIndex);2750}27512752client->write(response, resultIndex, objectPointerReference);2753}2754break;2755case MessageType::KnownObjectTable_createSymRefWithKnownObject:2756{2757void *staticAddress = std::get<0>(client->getRecvData<void*>());27582759TR::KnownObjectTable::Index resultIndex = TR::KnownObjectTable::UNKNOWN;2760uintptr_t *objectPointerReference = NULL;27612762{2763TR::VMAccessCriticalSection createSymRefWithKnownObject(fe);2764uintptr_t jlClass = (uintptr_t)J9VM_J9CLASS_TO_HEAPCLASS((J9Class*)staticAddress);2765TR_ASSERT(jlClass, "java/lang/Class reference from heap class must be non null");27662767resultIndex = knot->getOrCreateIndexAt(&jlClass);2768objectPointerReference = knot->getPointerLocation(resultIndex);2769}27702771client->write(response, resultIndex, objectPointerReference);2772}2773break;2774case MessageType::KnownObjectTable_getReferenceField:2775{2776auto recv = (client->getRecvData<bool, uintptr_t*, int32_t, bool>());2777bool isStatic = std::get<0>(recv);2778uintptr_t *baseObjectRefLocation = std::get<1>(recv);2779int32_t fieldOffset = std::get<2>(recv);2780bool knotEnabled = std::get<3>(recv);27812782TR::KnownObjectTable::Index resultIndex = TR::KnownObjectTable::UNKNOWN;2783uintptr_t *objectPointerReference = NULL;2784uintptr_t targetObjectReference = 0;27852786{2787TR::VMAccessCriticalSection getReferenceField(fe);2788uintptr_t baseObjectRef = isStatic ? fe->getStaticReferenceFieldAtAddress((uintptr_t)baseObjectRefLocation) : *baseObjectRefLocation;2789targetObjectReference = fe->getReferenceFieldAt(baseObjectRef, fieldOffset);27902791if (knotEnabled && knot)2792{2793resultIndex = knot->getOrCreateIndexAt(&targetObjectReference);2794objectPointerReference = knot->getPointerLocation(resultIndex);2795}2796}27972798client->write(response, resultIndex, objectPointerReference, targetObjectReference);2799}2800break;2801case MessageType::KnownObjectTable_getKnownObjectTableDumpInfo:2802{2803client->getRecvData<JITServer::Void>();28042805std::vector<TR_KnownObjectTableDumpInfo> knownObjectTableDumpInfoList;28062807knot->getKnownObjectTableDumpInfo(knownObjectTableDumpInfoList);28082809client->write(response, knownObjectTableDumpInfoList);2810}2811break;2812case MessageType::AOTCache_serializedAOTMethod:2813done = true;2814break;2815case MessageType::AOTCache_getROMClassBatch:2816{2817auto recv = client->getRecvData<std::vector<J9Class *>>();2818auto &ramClasses = std::get<0>(recv);2819std::vector<JITServerHelpers::ClassInfoTuple> classInfos;2820classInfos.reserve(ramClasses.size());28212822for (J9Class *ramClass : ramClasses)2823classInfos.push_back(JITServerHelpers::packRemoteROMClassInfo(ramClass, fe->vmThread(), trMemory, true));28242825{2826OMR::CriticalSection cs(compInfo->getclassesCachedAtServerMonitor());2827compInfo->getclassesCachedAtServer().insert(ramClasses.begin(), ramClasses.end());2828}28292830client->write(response, classInfos);2831}2832break;2833default:2834// It is vital that this remains a hard error during dev!2835TR_ASSERT(false, "JITServer: handleServerMessage received an unknown message type: %d\n", response);2836}28372838releaseVMAccess(vmThread);2839return done;2840}28412842static TR_MethodMetaData *2843remoteCompilationEnd(J9VMThread *vmThread, TR::Compilation *comp, TR_ResolvedMethod *compilee,2844J9Method *method, TR::CompilationInfoPerThreadBase *compInfoPT,2845const std::string &codeCacheStr, const std::string &dataCacheStr)2846{2847TR_MethodMetaData *relocatedMetaData = NULL;2848TR_J9VM *fe = comp->fej9vm();2849TR_MethodToBeCompiled *entry = compInfoPT->getMethodBeingCompiled();2850J9JITConfig *jitConfig = compInfoPT->getJitConfig();2851TR::CompilationInfo *compInfo = TR::CompilationInfo::get();2852const J9JITDataCacheHeader *storedCompiledMethod = NULL;2853PORT_ACCESS_FROM_JAVAVM(jitConfig->javaVM);28542855if (!fe->isAOT_DEPRECATED_DO_NOT_USE() && !comp->isDeserializedAOTMethod()) // For relocating received JIT compilations2856{2857compInfoPT->reloRuntime()->setReloStartTime(compInfoPT->getTimeWhenCompStarted());28582859relocatedMetaData = compInfoPT->reloRuntime()->prepareRelocateAOTCodeAndData(2860vmThread, fe, comp->cg()->getCodeCache(), (J9JITDataCacheHeader *)dataCacheStr.data(),2861method, false, comp->getOptions(), comp, compilee, (uint8_t *)codeCacheStr.data()2862);28632864if (!relocatedMetaData)2865{2866if (TR::Options::getVerboseOption(TR_VerboseJITServer))2867{2868TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,2869"JITClient: Relocation failure: %d",2870compInfoPT->reloRuntime()->returnCode());2871}2872Trc_JITServerRelocationFailure(vmThread, compInfoPT->reloRuntime()->returnCode());2873// Relocation failed, fail compilation2874entry->_compErrCode = compInfoPT->reloRuntime()->returnCode();2875comp->failCompilation<J9::AOTRelocationFailed>("Failed to relocate");2876}2877}2878#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))2879else // For relocating received AOT compilations2880{2881TR_ASSERT(entry->_useAotCompilation || comp->isDeserializedAOTMethod(),2882"entry must be an AOT compilation or a deserialized AOT method");2883TR_ASSERT(entry->isRemoteCompReq(), "entry must be a remote compilation");2884J9ROMMethod *romMethod = comp->fej9()->getROMMethodFromRAMMethod(method);2885TR::CompilationInfo::storeAOTInSharedCache(2886vmThread, romMethod, (uint8_t *)dataCacheStr.data(), dataCacheStr.size(),2887(uint8_t *)codeCacheStr.data(), codeCacheStr.size(), comp, jitConfig, entry2888);28892890#if defined(J9VM_INTERP_AOT_RUNTIME_SUPPORT)2891bool canRelocateMethod = TR::CompilationInfo::canRelocateMethod(comp);28922893if (canRelocateMethod)2894{2895TR_ASSERT_FATAL(comp->cg(), "CodeGenerator must be allocated");2896int32_t returnCode = 0;28972898if (TR::Options::getVerboseOption(TR_VerboseJITServer))2899TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,2900"JITClient: Applying remote AOT relocations to %s AOT body for %s @ %s",2901comp->isDeserializedAOTMethod() ? "deserialized" : "newly compiled",2902comp->signature(), comp->getHotnessName()2903);29042905Trc_JITServerApplyRemoteAOTRelocation(vmThread, comp->signature(), comp->getHotnessName());29062907try2908{2909// Need to get a non-shared cache VM to relocate2910TR_J9VMBase *fe = TR_J9VMBase::get(jitConfig, vmThread);2911relocatedMetaData = entry->_compInfoPT->reloRuntime()->prepareRelocateAOTCodeAndData(2912vmThread, fe, comp->cg()->getCodeCache(), (J9JITDataCacheHeader *)dataCacheStr.data(),2913method, false, comp->getOptions(), comp, compilee, (uint8_t *)codeCacheStr.data()2914);2915returnCode = entry->_compInfoPT->reloRuntime()->returnCode();2916}2917catch (std::exception &e)2918{2919// Relocation Failure2920returnCode = compilationAotRelocationInterrupted;2921}29222923if (relocatedMetaData)2924{2925if (TR::Options::getVerboseOption(TR_VerboseJITServer))2926{2927TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "JITClient successfully relocated metadata for %s", comp->signature());2928}29292930if (J9_EVENT_IS_HOOKED(jitConfig->javaVM->hookInterface, J9HOOK_VM_DYNAMIC_CODE_LOAD))2931{2932TR::CompilationInfo::addJ9HookVMDynamicCodeLoadForAOT(vmThread, method, jitConfig, relocatedMetaData);2933}2934}2935else2936{2937if (TR::Options::getVerboseOption(TR_VerboseJITServer))2938{2939TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,2940"JITClient: AOT Relocation failure: %d",2941compInfoPT->reloRuntime()->returnCode());2942}29432944Trc_JITServerRelocationAOTFailure(vmThread, compInfoPT->reloRuntime()->returnCode());29452946// Relocation failed, fail compilation2947// attempt to recompile in non-AOT mode2948entry->_doNotUseAotCodeFromSharedCache = true;2949entry->_doNotLoadFromJITServerAOTCache = true;2950entry->_compErrCode = returnCode;29512952if (entry->_compilationAttemptsLeft > 0)2953{2954entry->_tryCompilingAgain = true;2955}2956comp->failCompilation<J9::AOTRelocationFailed>("Failed to relocate");2957}2958}2959else2960{2961// AOT compilations can fail on purpose because we want to load2962// the AOT body later on. This case is signalled by having a successful compilation2963// but canRelocateMethod == false2964// We still need metadata, because metaData->startPC != 0 indicates that compilation2965// didn't actually fail.2966J9JITDataCacheHeader *dataCacheHeader = (J9JITDataCacheHeader *)dataCacheStr.data();2967J9JITExceptionTable *metaData = compInfoPT->reloRuntime()->copyMethodMetaData(dataCacheHeader);2968// Temporarily store meta data pointer.2969// This is not exactly how it's used in baseline, but in remote AOT we do not use2970// AOT method data start for anything else, so should be fine.2971comp->setAotMethodDataStart(metaData);2972TR::CompilationInfo::replenishInvocationCount(method, comp);2973return metaData;2974}2975#endif /* J9VM_INTERP_AOT_RUNTIME_SUPPORT */2976}2977#endif // 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))2978return relocatedMetaData;2979}29802981void2982updateCompThreadActivationPolicy(TR::CompilationInfoPerThreadBase *compInfoPT, JITServer::ServerMemoryState nextMemoryState,2983JITServer::ServerActiveThreadsState nextActiveThreadState)2984{2985// When the server starts running low on memory or uses high number of compilation threads, clients need to reduce load on the server.2986// This is achieved by suspending compilation threads once low server memory or high number of compilation threads are detected.2987//2988// Under normal conditions, a client uses AGGRESSIVE activation policy, starting new compilation2989// threads at lower thresholds then non-JITServer.2990//2991// Once the server reaches LOW threshold for memory or HIGH threshold for active threads, the client enters MAINTAIN activation policy,2992// it keeps the current threads running but is not allowed to start new ones.2993//2994// If the situation deteriorates further and the server reaches VERY_LOW threshold for memory or very HIGH threshold for active threads,2995// client begins SUSPEND activation policy, disabling all but one compilation thread.2996//2997// If at some point the situation improves and the server returns to NORMAL memory state,2998// then clients using MAINTAIN policy will begin SUBDUE policy, which allows them to start/resume2999// compilation threads, but at a much higher activation threshold to avoid overwhelming the server again.3000//3001auto *compInfo = compInfoPT->getCompilationInfo();3002JITServer::CompThreadActivationPolicy curPolicy = compInfo->getCompThreadActivationPolicy();3003if (nextMemoryState == JITServer::ServerMemoryState::VERY_LOW || nextActiveThreadState == JITServer::ServerActiveThreadsState::VERY_HIGH_THREAD)3004{3005compInfo->setCompThreadActivationPolicy(JITServer::CompThreadActivationPolicy::SUSPEND);3006}3007else if (nextMemoryState == JITServer::ServerMemoryState::LOW || nextActiveThreadState == JITServer::ServerActiveThreadsState::HIGH_THREAD)3008{3009compInfo->setCompThreadActivationPolicy(JITServer::CompThreadActivationPolicy::MAINTAIN);3010}3011else // ServerMemoryState::NORMAL or ServerActiveThreadsState::NORMAL_THREAD3012{3013if (curPolicy <= JITServer::CompThreadActivationPolicy::MAINTAIN)3014{3015// It's expected that client will transition from MAINTAIN to SUBDUE,3016// but it's possible to move from SUSPEND to SUBDUE, if there is a sudden3017// increase in available memory on the server or a large delay in-between updates3018compInfo->setCompThreadActivationPolicy(JITServer::CompThreadActivationPolicy::SUBDUE);3019}3020}30213022JITServer::CompThreadActivationPolicy newPolicy = compInfo->getCompThreadActivationPolicy();3023if (curPolicy != newPolicy &&3024(TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerboseCompilationThreads) ||3025TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerboseJITServer)))3026{3027TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "t=%6u client has begun %s activation policy",3028(uint32_t) compInfo->getPersistentInfo()->getElapsedTime(),3029JITServer::compThreadActivationPolicyNames[newPolicy]);3030}3031}30323033TR_MethodMetaData *3034remoteCompile(J9VMThread *vmThread, TR::Compilation *compiler, TR_ResolvedMethod *compilee, J9Method *method,3035TR::IlGeneratorMethodDetails &details, TR::CompilationInfoPerThreadBase *compInfoPT)3036{3037TR_ASSERT(vmThread->publicFlags & J9_PUBLIC_FLAGS_VM_ACCESS, "Client must work with VM access");3038// JITServer: if TR_EnableJITServerPerCompConn is set, then each remote compilation establishes a new connection3039// instead of re-using the connection shared within a compilation thread3040static bool enableJITServerPerCompConn = feGetEnv("TR_EnableJITServerPerCompConn") ? true : false;30413042// Prepare the parameters for the compilation request3043J9Class *clazz = J9_CLASS_FROM_METHOD(method);3044J9ROMClass *romClass = clazz->romClass;3045J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);3046std::string detailsStr((const char *)&details, sizeof(details));3047TR::CompilationInfo *compInfo = compInfoPT->getCompilationInfo();3048TR_MethodToBeCompiled *entry = compInfoPT->getMethodBeingCompiled();3049TR::PersistentInfo *persistentInfo = compInfo->getPersistentInfo();3050bool useAotCompilation = entry->_useAotCompilation;30513052bool aotCacheStore = useAotCompilation && persistentInfo->getJITServerUseAOTCache();3053bool aotCacheLoad = useAotCompilation && persistentInfo->getJITServerUseAOTCache() &&3054!entry->_doNotLoadFromJITServerAOTCache;3055auto deserializer = compInfo->getJITServerAOTDeserializer();3056if (!aotCacheLoad && deserializer)3057deserializer->incNumCacheBypasses();30583059// For JitDump recompilations need to use the same stream as for the original compile3060JITServer::ClientStream *client = (enableJITServerPerCompConn && !details.isJitDumpMethod()) ? NULL3061: compInfoPT->getClientStream();3062if (!client)3063{3064try3065{3066if (JITServerHelpers::isServerAvailable())3067{3068client = new (PERSISTENT_NEW) JITServer::ClientStream(persistentInfo);3069if (!enableJITServerPerCompConn)3070compInfoPT->setClientStream(client);3071}3072else if (JITServerHelpers::shouldRetryConnection(OMRPORT_FROM_J9PORT(compInfoPT->getJitConfig()->javaVM->portLibrary)))3073{3074client = new (PERSISTENT_NEW) JITServer::ClientStream(persistentInfo);3075if (!enableJITServerPerCompConn)3076compInfoPT->setClientStream(client);3077JITServerHelpers::postStreamConnectionSuccess();3078}3079else3080{3081if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompilationDispatch))3082TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,3083"Server is not available. Retry with local compilation for %s @ %s", compiler->signature(), compiler->getHotnessName());3084Trc_JITServerRetryLocalCompile(vmThread, compiler->signature(), compiler->getHotnessName());3085compiler->failCompilation<JITServer::StreamFailure>("Server is not available, should retry with local compilation.");3086}3087}3088catch (const JITServer::StreamFailure &e)3089{3090JITServerHelpers::postStreamFailure(OMRPORT_FROM_J9PORT(compInfoPT->getJitConfig()->javaVM->portLibrary), compInfo);3091if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompilationDispatch))3092TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,3093"JITServer::StreamFailure: %s for %s @ %s", e.what(), compiler->signature(), compiler->getHotnessName());30943095Trc_JITServerStreamFailure(vmThread, compInfoPT->getCompThreadId(), __FUNCTION__,3096compiler->signature(), compiler->getHotnessName(), e.what());30973098compiler->failCompilation<JITServer::StreamFailure>(e.what());3099}3100catch (const std::bad_alloc &e)3101{3102if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompilationDispatch))3103TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,3104"std::bad_alloc: %s for %s @ %s", e.what(), compiler->signature(), compiler->getHotnessName());3105compiler->failCompilation<std::bad_alloc>(e.what());3106}3107}31083109if (compiler->getOption(TR_UseSymbolValidationManager))3110{3111// We do not want client to validate anything during compilation, because3112// validations are done on the server. Creating heuristic region makes SVM assume that everything is valdiated.3113compiler->enterHeuristicRegion();3114}31153116if (compiler->isOptServer())3117compiler->setOption(TR_Server);31183119// Check the _classesCachedAtServer set to determine whether JITServer is likely to have this class already cached.3120// If so, do not send the ROMClass content to save network traffic.3121bool serializeClass = false;3122{3123OMR::CriticalSection romClassCache(compInfo->getclassesCachedAtServerMonitor());3124// Send the romClass to JITServer if clazz was not already in the set3125serializeClass = compInfo->getclassesCachedAtServer().insert(clazz).second;3126}31273128auto classInfoTuple = JITServerHelpers::packRemoteROMClassInfo(clazz, compiler->fej9vm()->vmThread(),3129compiler->trMemory(), serializeClass);3130std::string optionsStr = TR::Options::packOptions(compiler->getOptions());3131std::string recompMethodInfoStr = compiler->isRecompilationEnabled()3132? std::string((const char *)compiler->getRecompilationInfo()->getMethodInfo(), sizeof(TR_PersistentMethodInfo))3133: std::string();31343135uintptr_t *classChain = NULL;3136std::vector<J9Class *> ramClassChain;3137std::vector<J9Class *> uncachedRAMClasses;3138std::vector<JITServerHelpers::ClassInfoTuple> uncachedClassInfos;3139if (aotCacheStore || aotCacheLoad)3140{3141classChain = compiler->fej9vm()->sharedCache()->rememberClass(clazz);3142if (classChain)3143{3144// The first word of the class chain data stores the size of the whole record in bytes3145uintptr_t numClasses = classChain[0] / sizeof(classChain[0]) - 1;3146ramClassChain = JITServerHelpers::getRAMClassChain(clazz, numClasses, vmThread, compiler->trMemory(),3147compInfo, uncachedRAMClasses, uncachedClassInfos);3148}3149else if (TR::Options::getVerboseOption(TR_VerboseJITServer))3150{3151TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "ERROR: Failed to get defining class chain for method %s",3152compiler->signature());3153if (aotCacheLoad)3154deserializer->incNumCacheBypasses();3155aotCacheStore = false;3156aotCacheLoad = false;3157}3158}31593160std::vector<uintptr_t> newKnownIds = deserializer ? deserializer->getNewKnownIds() : std::vector<uintptr_t>();31613162// TODO: make this a synchronized region to avoid bad_alloc exceptions3163compInfo->getSequencingMonitor()->enter();3164// Collect the list of unloaded classes3165std::vector<TR_OpaqueClassBlock *> unloadedClasses(compInfo->getUnloadedClassesTempList()->begin(),3166compInfo->getUnloadedClassesTempList()->end());3167compInfo->getUnloadedClassesTempList()->clear();3168std::vector<TR_OpaqueClassBlock *> illegalModificationList(compInfo->getIllegalFinalFieldModificationList()->begin(),3169compInfo->getIllegalFinalFieldModificationList()->end());3170compInfo->getIllegalFinalFieldModificationList()->clear();3171// Collect and encode the CHTable updates; this will acquire CHTable mutex3172auto chTable = (JITClientPersistentCHTable *)persistentInfo->getPersistentCHTable();3173std::pair<std::string, std::string> chtableUpdates = chTable->serializeUpdates();3174// Update the sequence number for these updates3175uint32_t seqNo = compInfo->incCompReqSeqNo();3176uint32_t lastCriticalSeqNo = !details.isJitDumpMethod() ? compInfo->getLastCriticalSeqNo() : 0;3177// If needed, update the seqNo of the last request that carried information that needed to be processed in order3178if (!chtableUpdates.first.empty() || !chtableUpdates.second.empty() ||3179!illegalModificationList.empty() || !unloadedClasses.empty() || details.isJitDumpMethod())3180{3181compInfo->setLastCriticalSeqNo(seqNo);3182}3183compInfo->getSequencingMonitor()->exit();31843185uint32_t statusCode = compilationFailure;3186std::string codeCacheStr;3187std::string dataCacheStr;3188CHTableCommitData chTableData;3189std::vector<TR_OpaqueClassBlock *> classesThatShouldNotBeNewlyExtended;3190std::string logFileStr;3191std::string svmValueToSymbolStr;3192std::vector<TR_ResolvedJ9Method *> resolvedMirrorMethodsPersistIPInfo;3193TR_OptimizationPlan modifiedOptPlan;3194std::vector<SerializedRuntimeAssumption> serializedRuntimeAssumptions;3195std::vector<TR_OpaqueMethodBlock *> methodsRequiringTrampolines;3196uint32_t methodIndex = (uint32_t)(method - clazz->ramMethods);// Index in the array of methods of the defining class3197try3198{3199// Release VM access just before sending the compilation request3200// message just in case we block in the write operation3201releaseVMAccess(vmThread);32023203if (TR::Options::getVerboseOption(TR_VerboseJITServer))3204{3205TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,3206"Client sending compReq seqNo=%u to server for method %s @ %s.",3207seqNo, compiler->signature(), compiler->getHotnessName());3208}32093210Trc_JITServerRemoteCompileRequest(vmThread, seqNo, compiler->signature(), compiler->getHotnessName());32113212client->buildCompileRequest(3213persistentInfo->getClientUID(), seqNo, lastCriticalSeqNo, method, clazz, *entry->_optimizationPlan,3214detailsStr, details.getType(), unloadedClasses, illegalModificationList, classInfoTuple, optionsStr,3215recompMethodInfoStr, chtableUpdates.first, chtableUpdates.second, useAotCompilation,3216TR::Compiler->vm.isVMInStartupPhase(compInfoPT->getJitConfig()), aotCacheLoad, methodIndex,3217classChain, ramClassChain, uncachedRAMClasses, uncachedClassInfos, newKnownIds3218);32193220JITServer::MessageType response;3221while (!handleServerMessage(client, compiler->fej9vm(), response));32223223// Re-acquire VM access3224// handleServerMessage will always acquire VM access after read() and release VM access at the end3225// Therefore we need to re-acquire VM access after we get out of handleServerMessage3226acquireVMAccessNoSuspend(vmThread);32273228if (JITServer::MessageType::compilationCode == response)3229{3230auto recv = client->getRecvData<3231std::string, std::string, CHTableCommitData, std::vector<TR_OpaqueClassBlock*>, std::string, std::string,3232std::vector<TR_ResolvedJ9Method*>, TR_OptimizationPlan, std::vector<SerializedRuntimeAssumption>,3233JITServer::ServerMemoryState, JITServer::ServerActiveThreadsState, std::vector<TR_OpaqueMethodBlock *>3234>();3235statusCode = compilationOK;3236codeCacheStr = std::get<0>(recv);3237dataCacheStr = std::get<1>(recv);3238chTableData = std::get<2>(recv);3239classesThatShouldNotBeNewlyExtended = std::get<3>(recv);3240logFileStr = std::get<4>(recv);3241svmValueToSymbolStr = std::get<5>(recv);3242resolvedMirrorMethodsPersistIPInfo = std::get<6>(recv);3243modifiedOptPlan = std::get<7>(recv);3244serializedRuntimeAssumptions = std::get<8>(recv);3245JITServer::ServerMemoryState nextMemoryState = std::get<9>(recv);3246JITServer::ServerActiveThreadsState nextActiveThreadState = std::get<10>(recv);3247methodsRequiringTrampolines = std::get<11>(recv);32483249updateCompThreadActivationPolicy(compInfoPT, nextMemoryState, nextActiveThreadState);32503251if (aotCacheLoad)3252deserializer->incNumCacheMisses();3253}3254else if (JITServer::MessageType::AOTCache_serializedAOTMethod == response)3255{3256auto recv = client->getRecvData<std::string, std::vector<std::string>, TR_OptimizationPlan,3257JITServer::ServerMemoryState, JITServer::ServerActiveThreadsState>();3258auto &methodStr = std::get<0>(recv);3259auto &records = std::get<1>(recv);3260modifiedOptPlan = std::get<2>(recv);3261JITServer::ServerMemoryState nextMemoryState = std::get<3>(recv);3262JITServer::ServerActiveThreadsState nextActiveThreadState = std::get<4>(recv);32633264updateCompThreadActivationPolicy(compInfoPT, nextMemoryState, nextActiveThreadState);32653266auto method = SerializedAOTMethod::get(methodStr);3267bool usesSVM = false;3268if (deserializer->deserialize(method, records, compiler, usesSVM))3269{3270compiler->setDeserializedAOTMethod(true);3271compiler->setDeserializedAOTMethodUsingSVM(usesSVM);3272statusCode = compilationOK;3273codeCacheStr = std::string((const char *)method->code(), method->codeSize());3274dataCacheStr = std::string((const char *)method->data(), method->dataSize());3275// Remaining values are already set to empty defaults3276}3277else3278{3279entry->_compErrCode = aotCacheDeserializationFailure;3280entry->_doNotLoadFromJITServerAOTCache = true;3281if (entry->_compilationAttemptsLeft > 0)3282entry->_tryCompilingAgain = true;3283compiler->failCompilation<J9::AOTCacheDeserializationFailure>(3284"Failed to deserialize AOT cache method %s", compiler->signature());3285}3286}3287else if (JITServer::MessageType::jitDumpPrintIL == response)3288{3289// A server compilation thread has crashed, and the crashing thread3290// is generating a JitDump. Use the existing compilation to print IL3291// of the method causing the crash and then schedule a JitDump recompilation3292bool writeVerboseLog = TR::Options::isAnyVerboseOptionSet(3293TR_VerboseJITServer,3294TR_VerboseCompilationDispatch,3295TR_VerbosePerformance,3296TR_VerboseCompFailure3297);3298if (writeVerboseLog)3299TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,3300"Server compilation thread crashed while compiling %s (%s)", compiler->signature(), compiler->getHotnessName());3301Trc_JITServerCompThreadCrashed(vmThread, compInfoPT->getCompThreadId(), compiler->signature(), compiler->getHotnessName());33023303TR::CompilationInfoPerThreadBase::UninterruptibleOperation uop(*compInfoPT);3304releaseVMAccess(vmThread);3305while (!handleServerMessage(client, compiler->fej9vm(), response));3306acquireVMAccessNoSuspend(vmThread);33073308TR_ASSERT_FATAL(3309(response == JITServer::MessageType::compilationThreadCrashed) ||3310(response == JITServer::MessageType::compilationFailure),3311"Expected compilationThreadCrashed or compilationFailure but received %s\n",3312JITServer::messageNames[response]3313);33143315if (response == JITServer::MessageType::compilationThreadCrashed)3316{3317// IL of the crashing method generated successfully, proceed with diagnostic recompilation3318auto recv = client->getRecvData<TR::FILE *>();3319TR::FILE *jitdumpFile = std::get<0>(recv);3320client->write(response, JITServer::Void());33213322// Create method details for the JitDump recompilation3323// and update optimization plan with a file pointer to the jitdump log.3324// NOTE: JitDumpMethodDetails parameter "optionsFromOriginalCompile"3325// is set to NULL, because the original compile hasn't ended from the client's point of view3326// so options haven't changed.3327J9::JitDumpMethodDetails jitDumpDetails(method, NULL, useAotCompilation);3328entry->_optimizationPlan->setLogCompilation(jitdumpFile);33293330if (writeVerboseLog)3331TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,3332"Requested JitDump recompilation of %s (%s)", compiler->signature(), compiler->getHotnessName());3333if (enableJITServerPerCompConn)3334compInfoPT->setClientStream(client);3335try3336{3337// Recompile the method as a JitDump method3338TR_MethodMetaData *metaData = remoteCompile(vmThread, compiler, compilee, method, jitDumpDetails, compInfoPT);3339}3340catch (std::exception &e)3341{3342// We expect the above compilation to fail and throw3343// Since we are already handling this failure, ignore failures during diagnostic recompilation3344if (writeVerboseLog)3345TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,3346"Server diagnostic thread crashed while compiling %s (%s)", compiler->signature(), compiler->getHotnessName());3347}3348}3349else3350{3351if (writeVerboseLog)3352TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE, "Failed to generate IL of the crashing method, aborting diagnostic recompilation");3353}33543355// Since server has crashed, all compilations will switch to local3356JITServerHelpers::postStreamFailure(OMRPORT_FROM_J9PORT(compInfoPT->getJitConfig()->javaVM->portLibrary), compInfo);3357entry->_compErrCode = compilationFailure;3358compiler->failCompilation<JITServer::ServerCompilationFailure>("JITServer compilation thread has crashed.");3359}3360else3361{3362TR_ASSERT(JITServer::MessageType::compilationFailure == response,3363"Received %u %s but expected JITServer::MessageType::compilationFailure message type",3364response, JITServer::messageNames[response]);3365auto recv = client->getRecvData<uint32_t, uint64_t>();3366statusCode = std::get<0>(recv);3367uint64_t otherData = std::get<1>(recv);3368if (statusCode == compilationLowPhysicalMemory && otherData != -1) // if failed due to low memory, should've received an updated memory state3369updateCompThreadActivationPolicy(compInfoPT, (JITServer::ServerMemoryState) otherData, JITServer::ServerActiveThreadsState::NORMAL_THREAD);3370if (TR::Options::getVerboseOption(TR_VerboseJITServer))3371TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "remoteCompile: compilationFailure statusCode %u\n", statusCode);33723373Trc_JITServerRemoteCompilationFailure(vmThread, statusCode);3374}33753376if (statusCode >= compilationMaxError)3377throw JITServer::StreamTypeMismatch("Did not receive a valid TR_CompilationErrorCode as the final message on the stream.");3378else if (statusCode == compilationStreamVersionIncompatible)3379throw JITServer::StreamVersionIncompatible();3380else if (statusCode == compilationStreamMessageTypeMismatch)3381throw JITServer::StreamMessageTypeMismatch();3382client->setVersionCheckStatus();3383}3384catch (const JITServer::StreamFailure &e)3385{3386JITServerHelpers::postStreamFailure(OMRPORT_FROM_J9PORT(compInfoPT->getJitConfig()->javaVM->portLibrary), compInfo);33873388if (!details.isJitDumpMethod())3389{3390client->~ClientStream();3391TR_Memory::jitPersistentFree(client);3392compInfoPT->setClientStream(NULL);3393}33943395if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompilationDispatch))3396TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,3397"JITServer::StreamFailure: %s for %s @ %s", e.what(), compiler->signature(), compiler->getHotnessName());33983399Trc_JITServerStreamFailure(vmThread, compInfoPT->getCompThreadId(), __FUNCTION__,3400compiler->signature(), compiler->getHotnessName(), e.what());34013402compiler->failCompilation<JITServer::StreamFailure>(e.what());3403}3404catch (const JITServer::StreamVersionIncompatible &e)3405{3406if (!details.isJitDumpMethod())3407{3408client->~ClientStream();3409TR_Memory::jitPersistentFree(client);3410compInfoPT->setClientStream(NULL);3411JITServer::ClientStream::incrementIncompatibilityCount(OMRPORT_FROM_J9PORT(compInfoPT->getJitConfig()->javaVM->portLibrary));3412}34133414if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompilationDispatch))3415TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,3416"JITServer::StreamVersionIncompatible: %s for %s @ %s", e.what(), compiler->signature(), compiler->getHotnessName());34173418Trc_JITServerStreamVersionIncompatible(vmThread, compInfoPT->getCompThreadId(), __FUNCTION__,3419compiler->signature(), compiler->getHotnessName(), e.what());34203421compiler->failCompilation<JITServer::StreamVersionIncompatible>(e.what());3422}3423catch (const JITServer::StreamMessageTypeMismatch &e)3424{3425if (!details.isJitDumpMethod())3426{3427client->~ClientStream();3428TR_Memory::jitPersistentFree(client);3429compInfoPT->setClientStream(NULL);3430}34313432if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompilationDispatch))3433TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,3434"JITServer::StreamMessageTypeMismatch: %s for %s @ %s", e.what(), compiler->signature(), compiler->getHotnessName());34353436Trc_JITServerStreamMessageTypeMismatch(vmThread, compInfoPT->getCompThreadId(), __FUNCTION__,3437compiler->signature(), compiler->getHotnessName(), e.what());34383439compiler->failCompilation<JITServer::StreamMessageTypeMismatch>(e.what());3440}3441catch (const J9::AOTCacheDeserializationFailure &e)3442{3443throw;3444}3445catch (...)3446{3447if (!details.isJitDumpMethod())3448{3449// For any other type of exception disconnect the socket3450client->~ClientStream();3451TR_Memory::jitPersistentFree(client);3452compInfoPT->setClientStream(NULL);3453}3454throw; // rethrow the exception3455}34563457TR_MethodMetaData *metaData = NULL;3458// If a JitDump recompilation succeeded,3459// return before performing relocations and adding runtime assumptions,3460// since the compilation will be failed anyway.3461if (details.isJitDumpMethod())3462return NULL;34633464if (statusCode == compilationOK || statusCode == compilationNotNeeded)3465{3466try3467{3468TR_IProfiler *iProfiler = compiler->fej9vm()->getIProfiler();3469for (TR_ResolvedJ9Method* mirror : resolvedMirrorMethodsPersistIPInfo)3470iProfiler->persistIprofileInfo(NULL, mirror, compiler);34713472if (compiler->getOption(TR_UseSymbolValidationManager))3473{3474// Compilation is done, now we need client to validate all of the records accumulated by the server,3475// so need to exit heuristic region.3476compiler->exitHeuristicRegion();3477// Populate symbol to id map3478compiler->getSymbolValidationManager()->deserializeValueToSymbolMap(svmValueToSymbolStr);3479}34803481TR_ASSERT(codeCacheStr.size(), "must have code cache");3482TR_ASSERT(dataCacheStr.size(), "must have data cache");34833484entry->_optimizationPlan->clone(&modifiedOptPlan);34853486// Relocate the received compiled code3487metaData = remoteCompilationEnd(vmThread, compiler, compilee, method, compInfoPT, codeCacheStr, dataCacheStr);3488if (metaData)3489{3490// Must add the runtime assumptions received from the server to the RAT and3491// update the list in the comp object with persistent entries. A pointer to3492// this list will be copied into the metadata3493for (auto& it : serializedRuntimeAssumptions)3494{3495uint8_t *basePtr = it.isOffsetFromMetaDataBase() ? (uint8_t*)metaData : (uint8_t*)(metaData->codeCacheAlloc);3496uint8_t *addrToPatch = (uint8_t*)(basePtr + it.getOffset());3497switch (it.getKind())3498{3499case RuntimeAssumptionOnRegisterNative:3500{3501TR_PatchJNICallSite::make(compiler->fej9vm(), compiler->trPersistentMemory(), it.getKey(), addrToPatch, compiler->getMetadataAssumptionList());3502break;3503}3504case RuntimeAssumptionOnClassRedefinitionPIC:3505{3506createClassRedefinitionPicSite((void*)it.getKey(), addrToPatch, it.getSize(), false, compiler->getMetadataAssumptionList());3507compiler->setHasClassRedefinitionAssumptions();3508break;3509}3510case RuntimeAssumptionOnClassRedefinitionUPIC:3511{3512createClassRedefinitionPicSite((void*)it.getKey(), addrToPatch, it.getSize(), true, compiler->getMetadataAssumptionList());3513compiler->setHasClassRedefinitionAssumptions();3514break;3515}3516case RuntimeAssumptionOnClassUnload:3517{3518createClassUnloadPicSite((void*)it.getKey(), addrToPatch, it.getSize(), compiler->getMetadataAssumptionList());3519compiler->setHasClassUnloadAssumptions();3520break;3521}3522default:3523TR_ASSERT_FATAL(false, "Runtime assumption of kind %d is not handled by JITClient\n", it.getKind());3524} // end switch (it->getKind())3525}3526metaData->runtimeAssumptionList = *(compiler->getMetadataAssumptionList());35273528for (auto& it : methodsRequiringTrampolines)3529{3530if (compInfoPT->reloRuntime()->codeCache()->reserveResolvedTrampoline(it, true) != OMR::CodeCacheErrorCode::ERRORCODE_SUCCESS)3531compiler->failCompilation<TR::RecoverableTrampolineError>("Failed to allocate trampoline in the code cache");3532}3533}35343535if (!compiler->getOption(TR_DisableCHOpts) && !useAotCompilation && !compiler->isDeserializedAOTMethod())3536{3537TR::ClassTableCriticalSection commit(compiler->fe());35383539// Intersect classesThatShouldNotBeNewlyExtended with newlyExtendedClasses3540// and abort on overlap3541auto newlyExtendedClasses = compInfo->getNewlyExtendedClasses();3542for (TR_OpaqueClassBlock* clazz : classesThatShouldNotBeNewlyExtended)3543{3544auto it = newlyExtendedClasses->find(clazz);3545if (it != newlyExtendedClasses->end() && (it->second & (1 << TR::compInfoPT->getCompThreadId())))3546{3547if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompileEnd, TR_VerbosePerformance, TR_VerboseCompFailure))3548TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE, "Class that should not be newly extended was extended when compiling %s", compiler->signature());3549compiler->failCompilation<J9::CHTableCommitFailure>("Class that should not be newly extended was extended");3550}3551}35523553if (!JITClientCHTableCommit(compiler, metaData, chTableData))3554{3555#if defined(COLLECT_CHTABLE_STATS)3556chTable->_numCommitFailures += 1;3557#endif /* COLLECT_CHTABLE_STATS */3558if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompileEnd, TR_VerbosePerformance, TR_VerboseCompFailure))3559{3560TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE, "JITClient: Failure while committing chtable for %s", compiler->signature());3561}3562Trc_JITServerCommitCHTableFailed(vmThread, compiler->signature());3563compiler->failCompilation<J9::CHTableCommitFailure>("CHTable commit failure");3564}3565}35663567TR_ASSERT(!metaData || !metaData->startColdPC, "coldPC should be null");3568// As a debugging feature, a local compilation can be performed immediately after a remote compilation.3569// Each of them has logs with the same compilationSequenceNumber3570int compilationSequenceNumber = compiler->getOptions()->writeLogFileFromServer(logFileStr);3571if (compiler->getOption(TR_JITServerFollowRemoteCompileWithLocalCompile) && compilationSequenceNumber)3572{3573intptr_t rtn = 0;3574compiler->getOptions()->setLogFileForClientOptions(compilationSequenceNumber);3575releaseVMAccess(vmThread);3576if ((rtn = compiler->compile()) != COMPILATION_SUCCEEDED)3577{3578TR_ASSERT(false, "Compiler returned non zero return code %d\n", rtn);3579compiler->failCompilation<TR::CompilationException>("Compilation Failure");3580}3581acquireVMAccessNoSuspend(vmThread);3582compiler->getOptions()->closeLogFileForClientOptions();3583}35843585if (TR::Options::getVerboseOption(TR_VerboseJITServer))3586{3587TR_VerboseLog::writeLineLocked(3588TR_Vlog_JITServer,3589"Client successfully loaded method %s @ %s following compilation request. [metaData=%p, startPC=%p]",3590compiler->signature(),3591compiler->getHotnessName(),3592metaData, (metaData) ? (void *)metaData->startPC : NULL3593);3594}3595Trc_JITServerMethodSuccessfullyLoaded(vmThread, compiler->signature(),compiler->getHotnessName(),3596metaData, (metaData) ? (void *)metaData->startPC : NULL);3597}3598catch (const std::exception &e)3599{3600// Log for JITClient mode and re-throw3601if (TR::Options::getVerboseOption(TR_VerboseJITServer))3602{3603TR_VerboseLog::writeLineLocked(3604TR_Vlog_JITServer,3605"Client failed to load method %s @ %s following compilation request.",3606compiler->signature(),3607compiler->getHotnessName()3608);3609}3610Trc_JITServerMethodFailedToLoad(vmThread, compiler->signature(),compiler->getHotnessName());3611throw;3612}3613}3614else3615{3616entry->_compErrCode = statusCode;36173618if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompilationDispatch))3619TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,3620"JITServer::ServerCompilationFailure: errCode %u for %s @ %s", statusCode, compiler->signature(), compiler->getHotnessName());36213622Trc_JITServerServerCompilationFailure(vmThread, statusCode, compiler->signature(), compiler->getHotnessName());36233624compiler->failCompilation<JITServer::ServerCompilationFailure>("JITServer compilation failed.");3625}36263627if (enableJITServerPerCompConn && client && !details.isJitDumpMethod())3628{3629client->~ClientStream();3630TR_Memory::jitPersistentFree(client);3631}3632return metaData;3633}363436353636