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