Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/codert_vm/decomp.cpp
5986 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 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 <string.h>
24
#include "j9.h"
25
#include "j9protos.h"
26
#include "j9consts.h"
27
#include "j9cp.h"
28
#include "rommeth.h"
29
#include "jilconsts.h"
30
#include "jitprotos.h"
31
#include "j9protos.h"
32
#include "stackwalk.h"
33
#include "MethodMetaData.h"
34
#include "pcstack.h"
35
#include "ut_j9codertvm.h"
36
#include "jitregmap.h"
37
#include "pcstack.h"
38
#include "VMHelpers.hpp"
39
#include "OMR/Bytes.hpp"
40
41
#if defined(OSX) && defined(AARCH64)
42
#include <pthread.h> // for pthread_jit_write_protect_np
43
#endif
44
45
extern "C" {
46
47
/* Generic rounding macro - result is a UDATA */
48
#define ROUND_TO(granularity, number) OMR::align((UDATA)(number), granularity)
49
50
typedef struct {
51
J9JITExceptionTable * metaData;
52
J9Method * method;
53
UDATA * bp;
54
UDATA * a0;
55
UDATA * unwindSP;
56
UDATA * sp;
57
UDATA argCount;
58
J9Method * literals;
59
J9I2JState i2jState;
60
UDATA * j2iFrame;
61
UDATA preservedRegisterValues[J9SW_JIT_CALLEE_PRESERVED_SIZE];
62
UDATA previousFrameBytecodes;
63
UDATA notifyFramePop;
64
UDATA resolveFrameFlags;
65
} J9JITDecompileState;
66
67
/* OSR result codes */
68
#define OSR_OK 0
69
#define OSR_OUT_OF_MEMORY 1
70
71
/* Bit values for J9OSRFrame->flags */
72
#define J9OSRFRAME_NOTIFY_FRAME_POP 1
73
74
typedef struct {
75
J9VMThread *targetThread;
76
J9JITExceptionTable *metaData;
77
void *jitPC;
78
UDATA resolveFrameFlags;
79
UDATA *objectArgScanCursor;
80
UDATA *objectTempScanCursor;
81
J9JITStackAtlas *gcStackAtlas;
82
J9Method *method;
83
U_8 *liveMonitorMap;
84
U_16 numberOfMapBits;
85
void *inlineMap;
86
void *inlinedCallSite;
87
J9OSRFrame *osrFrame;
88
} J9OSRData;
89
90
extern void _fsdSwitchToInterpPatchEntry(void *);
91
extern void _fsdRestoreToJITPatchEntry(void *);
92
93
J9_EXTERN_BUILDER_SYMBOL(jitExitInterpreter0);
94
J9_EXTERN_BUILDER_SYMBOL(jitExitInterpreter1);
95
J9_EXTERN_BUILDER_SYMBOL(jitExitInterpreterD);
96
J9_EXTERN_BUILDER_SYMBOL(jitExitInterpreterF);
97
J9_EXTERN_BUILDER_SYMBOL(jitExitInterpreterJ);
98
J9_EXTERN_BUILDER_SYMBOL(jitDecompileOnReturn0);
99
J9_EXTERN_BUILDER_SYMBOL(jitDecompileOnReturn1);
100
J9_EXTERN_BUILDER_SYMBOL(jitDecompileOnReturnD);
101
J9_EXTERN_BUILDER_SYMBOL(jitDecompileOnReturnF);
102
J9_EXTERN_BUILDER_SYMBOL(jitDecompileOnReturnJ);
103
J9_EXTERN_BUILDER_SYMBOL(jitDecompileOnReturnL);
104
J9_EXTERN_BUILDER_SYMBOL(jitReportExceptionCatch);
105
J9_EXTERN_BUILDER_SYMBOL(jitDecompileAtExceptionCatch);
106
J9_EXTERN_BUILDER_SYMBOL(jitDecompileAtCurrentPC);
107
J9_EXTERN_BUILDER_SYMBOL(jitDecompileBeforeMethodMonitorEnter);
108
J9_EXTERN_BUILDER_SYMBOL(jitDecompileBeforeReportMethodEnter);
109
J9_EXTERN_BUILDER_SYMBOL(jitDecompileAfterAllocation);
110
J9_EXTERN_BUILDER_SYMBOL(jitDecompileAfterMonitorEnter);
111
J9_EXTERN_BUILDER_SYMBOL(executeCurrentBytecodeFromJIT);
112
J9_EXTERN_BUILDER_SYMBOL(enterMethodMonitorFromJIT);
113
J9_EXTERN_BUILDER_SYMBOL(reportMethodEnterFromJIT);
114
J9_EXTERN_BUILDER_SYMBOL(handlePopFramesFromJIT);
115
116
static J9OSRFrame* findOSRFrameAtInlineDepth(J9OSRBuffer *osrBuffer, UDATA inlineDepth);
117
static void jitFramePopNotificationAdded(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA inlineDepth);
118
static void decompPrintMethod(J9VMThread * currentThread, J9Method * method);
119
static UDATA decompileAllFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkState);
120
static J9JITDecompilationInfo * deleteDecompilationForExistingFrame(J9VMThread * decompileThread, J9JITDecompilationInfo * info);
121
static J9JITDecompilationInfo * addDecompilation(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA reason);
122
static void removeAllBreakpoints(J9VMThread * currentThread);
123
static void buildBytecodeFrame(J9VMThread *currentThread, J9OSRFrame *osrFrame);
124
static void buildInlineStackFrames(J9VMThread *currentThread, J9JITDecompileState *decompileState, J9JITDecompilationInfo *decompRecord, UDATA inlineDepth, J9OSRFrame *osrFrame);
125
static void performDecompile(J9VMThread * currentThread, J9JITDecompileState * decompileState, J9JITDecompilationInfo * decompRecord, J9OSRFrame *osrFrame, UDATA numberOfFrames);
126
static void decompileOuterFrame(J9VMThread * currentThread, J9JITDecompileState * decompileState, J9JITDecompilationInfo * decompRecord, J9OSRFrame *osrFrame);
127
static void markMethodBreakpointed(J9VMThread * currentThread, J9JITBreakpointedMethod * breakpointedMethod);
128
static UDATA codeBreakpointAddedFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkState);
129
static void decompileAllMethodsInAllStacks(J9VMThread * currentThread, UDATA reason);
130
static void markMethodUnbreakpointed(J9VMThread * currentThread, J9JITBreakpointedMethod * breakpointedMethod);
131
static void reinstallAllBreakpoints(J9VMThread * currentThread);
132
static UDATA decompileMethodFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkState);
133
static void deleteAllDecompilations(J9VMThread * currentThread, UDATA reason, J9Method * method);
134
static void freeDecompilationRecord(J9VMThread * decompileThread, J9JITDecompilationInfo * info, UDATA retain);
135
static UDATA osrAllFramesSize(J9VMThread *currentThread, J9JITExceptionTable *metaData, void *jitPC, UDATA resolveFrameFlags);
136
static UDATA performOSR(J9VMThread *currentThread, J9StackWalkState *walkState, J9OSRBuffer *osrBuffer, U_8 *osrScratchBuffer, UDATA scratchBufferSize, UDATA jitStackFrameSize, UDATA *mustDecompile);
137
static UDATA* jitLocalSlotAddress(J9VMThread * currentThread, J9StackWalkState *walkState, UDATA slot, UDATA inlineDepth);
138
static void jitResetAllMethods(J9VMThread *currentThread);
139
static void fixStackForNewDecompilation(J9VMThread * currentThread, J9StackWalkState * walkState, J9JITDecompilationInfo *info, UDATA reason, J9JITDecompilationInfo **link);
140
static UDATA roundedOSRScratchBufferSize(J9VMThread * currentThread, J9JITExceptionTable *metaData, void *jitPC);
141
static j9object_t* getObjectSlotAddress(J9OSRData *osrData, U_16 slot);
142
static UDATA createMonitorEnterRecords(J9VMThread *currentThread, J9OSRData *osrData);
143
static UDATA initializeOSRFrame(J9VMThread *currentThread, J9OSRData *osrData);
144
static UDATA initializeOSRBuffer(J9VMThread *currentThread, J9OSRBuffer *osrBuffer, J9OSRData *osrData);
145
static UDATA getPendingStackHeight(J9VMThread *currentThread, U_8 *interpreterPC, J9Method *ramMethod, UDATA resolveFrameFlags);
146
static J9JITDecompilationInfo* jitAddDecompilationForFramePop(J9VMThread * currentThread, J9StackWalkState * walkState);
147
static J9JITDecompilationInfo* fetchAndUnstackDecompilationInfo(J9VMThread *currentThread);
148
static void fixSavedPC(J9VMThread *currentThread, J9JITDecompilationInfo *decompRecord);
149
static void dumpStack(J9VMThread *currentThread, char const *msg);
150
static J9ROMNameAndSignature* getNASFromInvoke(U_8 *bytecodePC, J9ROMClass *romClass);
151
152
153
/**
154
* Get the J9ROMNameAndSignature for an invoke bytecode.
155
*
156
* @param[in] bytecodePC the PC of the invoke
157
* @param[in] romClass the J9ROMClass containing the invoke bytecode
158
*
159
* @return the J9ROMNameAndSignature referenced by the invoke
160
*/
161
static J9ROMNameAndSignature*
162
getNASFromInvoke(U_8 *bytecodePC, J9ROMClass *romClass)
163
{
164
U_16 cpIndex = *(U_16*)(bytecodePC + 1);
165
J9ROMNameAndSignature* nameAndSig = NULL;
166
U_8 bytecode = *bytecodePC;
167
if (JBinvokedynamic == bytecode) {
168
/* Convert from callSites table index to actual cpIndex by probing the
169
* J9ROMClass->callSiteData table. That data is layed out as:
170
* callSiteCount x SRP to: J9ROMNameAndSignature, callSiteCount x U16, bsmCount x J9BSMData
171
*/
172
J9SRP *callSiteData = (J9SRP *) J9ROMCLASS_CALLSITEDATA(romClass);
173
nameAndSig = SRP_PTR_GET(callSiteData + cpIndex, J9ROMNameAndSignature*);
174
} else {
175
switch(bytecode) {
176
case JBinvokeinterface2:
177
cpIndex = *(U_16*)(bytecodePC + 3);
178
break;
179
case JBinvokestaticsplit:
180
cpIndex = *(J9ROMCLASS_STATICSPLITMETHODREFINDEXES(romClass) + cpIndex);
181
break;
182
case JBinvokespecialsplit:
183
cpIndex = *(J9ROMCLASS_SPECIALSPLITMETHODREFINDEXES(romClass) + cpIndex);
184
break;
185
}
186
J9ROMMethodRef * romMethodRef = ((J9ROMMethodRef *) &(J9_ROM_CP_FROM_ROM_CLASS(romClass)[cpIndex]));
187
nameAndSig = J9ROMMETHODREF_NAMEANDSIGNATURE(romMethodRef);
188
}
189
return nameAndSig;
190
}
191
192
193
/**
194
* Pop the top of the decompilation stack.
195
*
196
* @param[in] currentThread the current J9VMThread
197
*
198
* @return the top element from the decompilation stack
199
*/
200
static J9JITDecompilationInfo*
201
fetchAndUnstackDecompilationInfo(J9VMThread *currentThread)
202
{
203
J9JITDecompilationInfo *decompRecord = currentThread->decompilationStack;
204
currentThread->decompilationStack = decompRecord->next;
205
return decompRecord;
206
}
207
208
209
/**
210
* Restore the PC from a decompilation record to its original location.
211
*
212
* @param[in] currentThread the current J9VMThread
213
* @param[in] decompRecord the decompilation record
214
*/
215
static void
216
fixSavedPC(J9VMThread *currentThread, J9JITDecompilationInfo *decompRecord)
217
{
218
*decompRecord->pcAddress = decompRecord->pc;
219
}
220
221
/**
222
* If the verbose stack dumper is enabled, dump the stack of the current thread.
223
*
224
* @param[in] currentThread the current J9VMThread
225
* @param[in] msg the header message for the stack dump
226
*/
227
static void
228
dumpStack(J9VMThread *currentThread, char const *msg)
229
{
230
J9JavaVM *vm = currentThread->javaVM;
231
if (NULL != vm->verboseStackDump) {
232
vm->verboseStackDump(currentThread, msg);
233
}
234
}
235
236
237
static void
238
decompPrintMethod(J9VMThread * currentThread, J9Method * method)
239
{
240
PORT_ACCESS_FROM_VMC(currentThread);
241
J9UTF8 * className = J9ROMCLASS_CLASSNAME(UNTAGGED_METHOD_CP(method)->ramClass->romClass);
242
J9ROMMethod * romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);
243
J9UTF8 * name = J9ROMMETHOD_NAME(romMethod);
244
J9UTF8 * sig = J9ROMMETHOD_SIGNATURE(romMethod);
245
246
Trc_Decomp_printMethod(currentThread, method, J9UTF8_LENGTH(className), J9UTF8_DATA(className), J9UTF8_LENGTH(name), J9UTF8_DATA(name), J9UTF8_LENGTH(sig), J9UTF8_DATA(sig));
247
}
248
249
250
static void
251
jitResetAllMethods(J9VMThread *currentThread)
252
{
253
J9JavaVM * vm = currentThread->javaVM;
254
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
255
J9Class * clazz = NULL;
256
J9ClassWalkState state;
257
258
/* First mark every compiled method for retranslation and invalidate the translation */
259
260
clazz = vmFuncs->allClassesStartDo(&state, vm, NULL);
261
while (clazz != NULL) {
262
J9Method *method = clazz->ramMethods;
263
U_32 methodCount = clazz->romClass->romMethodCount;
264
265
#if defined(OSX) && defined(AARCH64)
266
pthread_jit_write_protect_np(0);
267
#endif
268
269
while (methodCount != 0) {
270
UDATA extra = (UDATA)method->extra;
271
if (0 == (extra & J9_STARTPC_NOT_TRANSLATED)) {
272
/* Do not reset JIT INLs (currently in FSD there are no compiled JNI natives) */
273
if (0 == (J9_ROM_METHOD_FROM_RAM_METHOD(method)->modifiers & J9AccNative)) {
274
J9JITExceptionTable *metaData = vm->jitConfig->jitGetExceptionTableFromPC(currentThread, extra);
275
if (NULL != metaData) {
276
/* 0xCC is the "int3" instruction on x86.
277
* This will cause a crash if this instruction is executed.
278
* On other platforms, this will have unknown behaviour (likely a crash).
279
*/
280
*(U_8*)method->extra = 0xCC;
281
}
282
vmFuncs->initializeMethodRunAddress(currentThread, method);
283
}
284
}
285
method += 1;
286
methodCount -= 1;
287
}
288
289
#if defined(OSX) && defined(AARCH64)
290
pthread_jit_write_protect_np(1);
291
#endif
292
293
clazz = vmFuncs->allClassesNextDo(&state);
294
}
295
vmFuncs->allClassesEndDo(&state);
296
297
/* Now fix all the JIT vTables */
298
299
clazz = vmFuncs->allClassesStartDo(&state, vm, NULL);
300
while (clazz != NULL) {
301
/* Interface classes do not have vTables, so skip them */
302
if (!J9ROMCLASS_IS_INTERFACE(clazz->romClass)) {
303
UDATA *vTableWriteCursor = JIT_VTABLE_START_ADDRESS(clazz);
304
305
J9VTableHeader *vTableHeader = J9VTABLE_HEADER_FROM_RAM_CLASS(clazz);
306
J9Method **vTableReadCursor = J9VTABLE_FROM_HEADER(vTableHeader);
307
UDATA vTableSize = vTableHeader->size;
308
309
/* Put invalid entries in the obsolete JIT vTables and reinitialize the current ones */
310
if (J9_IS_CLASS_OBSOLETE(clazz)) {
311
while (0 != vTableSize) {
312
*vTableWriteCursor = (UDATA)-1;
313
vTableWriteCursor -= 1;
314
vTableSize -= 1;
315
}
316
} else {
317
while (0 != vTableSize) {
318
J9Method *method = *vTableReadCursor;
319
vTableReadCursor += 1;
320
vmFuncs->fillJITVTableSlot(currentThread, vTableWriteCursor, method);
321
vTableWriteCursor -= 1;
322
vTableSize -= 1;
323
}
324
}
325
}
326
clazz = vmFuncs->allClassesNextDo(&state);
327
}
328
vmFuncs->allClassesEndDo(&state);
329
}
330
331
332
333
#if (defined(J9VM_INTERP_HOT_CODE_REPLACEMENT)) /* priv. proto (autogen) */
334
335
J9JITDecompilationInfo *
336
jitCleanUpDecompilationStack(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA dropCurrentFrame)
337
{
338
PORT_ACCESS_FROM_VMC(currentThread);
339
J9JITDecompilationInfo * current;
340
J9JITDecompilationInfo * currentFrameDecompile = NULL;
341
342
current = currentThread->decompilationStack;
343
while (current != walkState->decompilationStack) {
344
J9JITDecompilationInfo * temp = current;
345
346
if (!dropCurrentFrame) {
347
if (current->bp == walkState->bp) {
348
currentFrameDecompile = current;
349
break;
350
}
351
}
352
current = current->next;
353
freeDecompilationRecord(currentThread, temp, FALSE);
354
}
355
currentThread->decompilationStack = current;
356
357
return currentFrameDecompile;
358
}
359
360
#endif /* J9VM_INTERP_HOT_CODE_REPLACEMENT (autogen) */
361
362
363
void
364
jitCodeBreakpointAdded(J9VMThread * currentThread, J9Method * method)
365
{
366
PORT_ACCESS_FROM_VMC(currentThread);
367
J9JITConfig * jitConfig = currentThread->javaVM->jitConfig;
368
J9JITBreakpointedMethod * breakpointedMethod;
369
J9JITBreakpointedMethod * breakpointedMethods = jitConfig->breakpointedMethods;
370
J9VMThread * loopThread;
371
372
/* Called under exclusive access, so no mutex required */
373
374
Trc_Decomp_jitCodeBreakpointAdded_Entry(currentThread, method);
375
decompPrintMethod(currentThread, method);
376
377
breakpointedMethod = breakpointedMethods;
378
while (breakpointedMethod) {
379
if (breakpointedMethod->method == method) {
380
++(breakpointedMethod->count);
381
Trc_Decomp_jitCodeBreakpointAdded_incCount(currentThread, breakpointedMethod->count);
382
return;
383
}
384
breakpointedMethod = breakpointedMethod->link;
385
}
386
387
Trc_Decomp_jitCodeBreakpointAdded_newEntry(currentThread);
388
389
breakpointedMethod = (J9JITBreakpointedMethod *) j9mem_allocate_memory(sizeof(J9JITBreakpointedMethod), OMRMEM_CATEGORY_JIT);
390
if (!breakpointedMethod) {
391
j9tty_printf(PORTLIB, "\n*** alloc failure in jitPermanentBreakpointAdded ***\n");
392
Assert_Decomp_breakpointFailed();
393
}
394
395
breakpointedMethod->link = breakpointedMethods;
396
jitConfig->breakpointedMethods = breakpointedMethod;
397
398
breakpointedMethod->method = method;
399
breakpointedMethod->count = 1;
400
markMethodBreakpointed(currentThread, breakpointedMethod);
401
402
Trc_Decomp_jitCodeBreakpointAdded_hasBeenTranslated(currentThread, breakpointedMethod->hasBeenTranslated);
403
404
loopThread = currentThread;
405
do {
406
J9StackWalkState walkState;
407
408
walkState.userData1 = method;
409
walkState.flags = J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES | J9_STACKWALK_VISIBLE_ONLY | J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_MAINTAIN_REGISTER_MAP;
410
walkState.skipCount = 0;
411
walkState.frameWalkFunction = codeBreakpointAddedFrameIterator;
412
walkState.walkThread = loopThread;
413
currentThread->javaVM->walkStackFrames(currentThread, &walkState);
414
} while ((loopThread = loopThread->linkNext) != currentThread);
415
416
Trc_Decomp_jitCodeBreakpointAdded_Exit(currentThread);
417
}
418
419
420
void
421
jitCodeBreakpointRemoved(J9VMThread * currentThread, J9Method * method)
422
{
423
PORT_ACCESS_FROM_VMC(currentThread);
424
J9JITConfig * jitConfig = currentThread->javaVM->jitConfig;
425
J9JITBreakpointedMethod ** previous = &(jitConfig->breakpointedMethods);
426
J9JITBreakpointedMethod * breakpointedMethod;
427
428
/* Called under exclusive access, so no mutex required */
429
430
Trc_Decomp_jitCodeBreakpointRemoved_Entry(currentThread, method);
431
decompPrintMethod(currentThread, method);
432
433
while ((breakpointedMethod = *previous) != NULL) {
434
if (breakpointedMethod->method == method) {
435
UDATA count;
436
437
if ( (count = --(breakpointedMethod->count)) == 0) {
438
Trc_Decomp_jitCodeBreakpointAdded_fixingMethods(currentThread);
439
markMethodUnbreakpointed(currentThread, breakpointedMethod);
440
*previous = breakpointedMethod->link;
441
j9mem_free_memory(breakpointedMethod);
442
deleteAllDecompilations(currentThread, JITDECOMP_CODE_BREAKPOINT, method);
443
}
444
445
Trc_Decomp_jitCodeBreakpointRemoved_decCount(currentThread, count);
446
447
return;
448
}
449
previous = &(breakpointedMethod->link);
450
}
451
452
Trc_Decomp_jitCodeBreakpointAdded_Failed(currentThread);
453
}
454
455
456
static UDATA
457
codeBreakpointAddedFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkState)
458
{
459
/* Decompile JIT frames running the breakpointed method */
460
461
if (walkState->jitInfo && (walkState->method == (J9Method *) walkState->userData1)) {
462
addDecompilation(currentThread, walkState, JITDECOMP_CODE_BREAKPOINT);
463
}
464
465
return J9_STACKWALK_KEEP_ITERATING;
466
}
467
468
469
#if (defined(J9VM_INTERP_HOT_CODE_REPLACEMENT)) /* priv. proto (autogen) */
470
471
void
472
jitHotswapOccurred(J9VMThread * currentThread)
473
{
474
/* We have exclusive */
475
476
Trc_Decomp_jitHotswapOccurred_Entry(currentThread);
477
478
/* Remove all breakpoints before resetting the methods */
479
480
removeAllBreakpoints(currentThread);
481
482
/* Find every method which has been translated and mark it for retranslation */
483
484
jitResetAllMethods(currentThread);
485
486
/* Reinstall the breakpoints */
487
488
reinstallAllBreakpoints(currentThread);
489
490
/* Mark every JIT method in every stack for decompilation */
491
492
decompileAllMethodsInAllStacks(currentThread, JITDECOMP_HOTSWAP);
493
494
Trc_Decomp_jitHotswapOccurred_Exit(currentThread);
495
}
496
497
#endif /* J9VM_INTERP_HOT_CODE_REPLACEMENT (autogen) */
498
499
500
void
501
jitDecompileMethod(J9VMThread * currentThread, J9JITDecompilationInfo * decompRecord)
502
{
503
J9JITDecompileState decompileState;
504
J9StackWalkState walkState;
505
J9OSRBuffer *osrBuffer = &decompRecord->osrBuffer;
506
UDATA numberOfFrames = osrBuffer->numberOfFrames;
507
J9OSRFrame *osrFrame = (J9OSRFrame*)(osrBuffer + 1);
508
509
/* Collect the required information from the stack - top visible frame is the decompile frame */
510
walkState.flags = J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES | J9_STACKWALK_VISIBLE_ONLY | J9_STACKWALK_MAINTAIN_REGISTER_MAP | J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_SAVE_STACKED_REGISTERS;
511
walkState.skipCount = 0;
512
walkState.frameWalkFunction = decompileMethodFrameIterator;
513
walkState.walkThread = currentThread;
514
walkState.userData1 = &decompileState;
515
walkState.userData2 = NULL;
516
currentThread->javaVM->walkStackFrames(currentThread, &walkState);
517
518
performDecompile(currentThread, &decompileState, decompRecord, osrFrame, numberOfFrames);
519
520
freeDecompilationRecord(currentThread, decompRecord, TRUE);
521
}
522
523
/**
524
* Find the pending stack height for a frame.
525
*
526
* @param[in] *currentThread current thread
527
* @param[in] *interpreterP the bytecoded PC
528
* @param[in] *method the J9Method
529
* @param[in] resolveFrameFlags the flags of the preceding resolve frame, or 0 if not preceded by a resolve frame
530
*
531
* @return the pending stack height
532
*/
533
534
static UDATA
535
getPendingStackHeight(J9VMThread *currentThread, U_8 *interpreterPC, J9Method *ramMethod, UDATA resolveFrameFlags)
536
{
537
UDATA pendingStackHeight = 0;
538
539
/* If the JIT frame has not been built, the pending stack height is 0. If we're at an exception catch,
540
* the height is 0 because the decompile return point will push the pending exception.
541
*/
542
UDATA resolveFrameType = resolveFrameFlags & J9_STACK_FLAGS_JIT_FRAME_SUB_TYPE_MASK;
543
switch(resolveFrameType) {
544
case J9_STACK_FLAGS_JIT_STACK_OVERFLOW_RESOLVE_FRAME:
545
case J9_STACK_FLAGS_JIT_EXCEPTION_CATCH_RESOLVE:
546
break;
547
default:
548
J9ROMClass *romClass = J9_CLASS_FROM_METHOD(ramMethod)->romClass;
549
J9ROMMethod * originalROMMethod = getOriginalROMMethod(ramMethod);
550
UDATA offsetPC = interpreterPC - J9_BYTECODE_START_FROM_RAM_METHOD(ramMethod);
551
J9JavaVM *vm = currentThread->javaVM;
552
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
553
J9PortLibrary *portLibrary = vm->portLibrary;
554
U_8 bytecode = *interpreterPC;
555
/* Use the stack mapper to determine the pending stack height */
556
pendingStackHeight = (UDATA)vmFuncs->j9stackmap_StackBitsForPC(portLibrary, offsetPC, romClass, originalROMMethod, NULL, 0, NULL, NULL, NULL);
557
/* All invokes consider their arguments not to be pending - remove the arguments from the pending stack */
558
switch(bytecode) {
559
case JBinvokevirtual:
560
case JBinvokespecial:
561
case JBinvokespecialsplit:
562
case JBinvokeinterface:
563
case JBinvokeinterface2:
564
case JBinvokehandle:
565
case JBinvokehandlegeneric:
566
/* Remove implicit receiver from pending stack */
567
pendingStackHeight -= 1;
568
/* Intentional fall-through */
569
case JBinvokedynamic:
570
case JBinvokestatic:
571
case JBinvokestaticsplit:
572
/* Remove arguments from pending stack */
573
pendingStackHeight -= getSendSlotsFromSignature(J9UTF8_DATA(J9ROMNAMEANDSIGNATURE_SIGNATURE(getNASFromInvoke(interpreterPC, romClass))));
574
break;
575
}
576
/* Reduce the pending stack height for the resolve special cases */
577
switch (resolveFrameType) {
578
case J9_STACK_FLAGS_JIT_MONITOR_ENTER_RESOLVE:
579
/* Decompile after monitorenter completes. Remove the object from the pending stack. */
580
pendingStackHeight -= 1;
581
break;
582
case J9_STACK_FLAGS_JIT_ALLOCATION_RESOLVE:
583
/* Decompile after allocation completes. The JIT has not mapped the bytecode parameters in the pending stack */
584
switch (bytecode) {
585
case JBanewarray:
586
case JBnewarray: /* 1 slot (size) stacked */
587
pendingStackHeight -= 1;
588
break;
589
case JBmultianewarray: /* Dimensions stacked (number of dimensions is 3 bytes from the multianewarray) */
590
pendingStackHeight -= interpreterPC[3];
591
break;
592
case JBwithfield:
593
/* it will always be two slots since we only ever need to allocate qtype */
594
pendingStackHeight -= 2;
595
break;
596
case JBgetfield:
597
pendingStackHeight -= 1;
598
break;
599
default: /* JBnew/JBaconst_init - no stacked parameters*/
600
break;
601
}
602
}
603
}
604
Assert_CodertVM_true((IDATA)pendingStackHeight >= 0);
605
Trc_Decomp_decompileMethodFrameIterator_pendingCount(currentThread, pendingStackHeight);
606
return pendingStackHeight;
607
}
608
609
610
static UDATA
611
decompileMethodFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkState)
612
{
613
J9JITDecompileState * decompileState = (J9JITDecompileState *) walkState->userData1;
614
615
Trc_Decomp_decompileMethodFrameIterator_Entry(currentThread);
616
617
/* If the decompile frame has already been passed, record the final information and stop walking */
618
619
if (walkState->userData2) {
620
if (walkState->jitInfo) {
621
UDATA * valueCursor = decompileState->preservedRegisterValues;
622
UDATA ** mapCursor = (UDATA **) &(walkState->registerEAs);
623
UDATA i;
624
625
decompileState->previousFrameBytecodes = FALSE;
626
627
for (i = 0; i < J9SW_JIT_CALLEE_PRESERVED_SIZE; ++i) {
628
UDATA regNumber = jitCalleeSavedRegisterList[i];
629
630
*(valueCursor++) = *(mapCursor[regNumber]);
631
}
632
633
Trc_Decomp_decompileMethodFrameIterator_previousIsJIT(currentThread);
634
635
} else {
636
Trc_Decomp_decompileMethodFrameIterator_previousIsBC(currentThread);
637
decompileState->previousFrameBytecodes = TRUE;
638
}
639
return J9_STACKWALK_STOP_ITERATING;
640
} else {
641
/* Current frame is the decompile frame - collect the preliminary info */
642
J9JITExceptionTable *metaData = walkState->jitInfo;
643
J9Method *method = walkState->method;
644
645
decompileState->metaData = metaData;
646
decompileState->method = method;
647
decompileState->sp = walkState->sp;
648
decompileState->argCount = walkState->outgoingArgCount;
649
Trc_Decomp_decompileMethodFrameIterator_outgoingArgCount(currentThread, decompileState->argCount);
650
decompileState->bp = walkState->bp;
651
decompileState->a0 = walkState->arg0EA;
652
decompileState->literals = method;
653
decompileState->unwindSP = walkState->unwindSP;
654
decompileState->j2iFrame = walkState->j2iFrame;
655
memcpy(&(decompileState->i2jState), walkState->i2jState, sizeof(J9I2JState));
656
decompileState->resolveFrameFlags = walkState->resolveFrameFlags;
657
658
/* Walk the next frame regardless of its visibility */
659
660
walkState->userData2 = (void *) 1;
661
walkState->flags &= ~J9_STACKWALK_VISIBLE_ONLY;
662
}
663
664
Trc_Decomp_decompileMethodFrameIterator_Exit(currentThread);
665
666
return J9_STACKWALK_KEEP_ITERATING;
667
}
668
669
670
/**
671
* Push a bytecode frame based on an OSR frame. Assumes that a bytecode frame
672
* (either pure or J2I) is already on the top of stack.
673
*
674
* @param[in] *currentThread current thread
675
* @param[in] *osrFrame the OSR frame from which to copy the information
676
*/
677
static void
678
buildBytecodeFrame(J9VMThread *currentThread, J9OSRFrame *osrFrame)
679
{
680
J9Method *method = osrFrame->method;
681
U_8 *bytecodePC = osrFrame->bytecodePCOffset + J9_BYTECODE_START_FROM_RAM_METHOD(method);
682
UDATA numberOfLocals = osrFrame->numberOfLocals;
683
UDATA maxStack = osrFrame->maxStack;
684
UDATA pendingStackHeight = osrFrame->pendingStackHeight;
685
UDATA *locals = ((UDATA*)(osrFrame + 1)) + maxStack;
686
UDATA *pending = locals - pendingStackHeight;
687
UDATA *sp = currentThread->sp;
688
UDATA *a0 = currentThread->arg0EA;
689
U_8 *pc = currentThread->pc;
690
J9Method *literals = currentThread->literals;
691
UDATA *newA0 = sp - 1;
692
J9SFStackFrame *stackFrame = NULL;
693
694
/* Push the locals */
695
sp -= numberOfLocals;
696
memcpy(sp, locals, numberOfLocals * sizeof(UDATA));
697
698
/* Push the stack frame */
699
stackFrame = (J9SFStackFrame*)sp - 1;
700
stackFrame->savedPC = pc;
701
stackFrame->savedCP = literals;
702
stackFrame->savedA0 = a0;
703
704
/* Push the pendings */
705
sp = (UDATA*)stackFrame - pendingStackHeight;
706
memcpy(sp, pending, pendingStackHeight * sizeof(UDATA));
707
708
/* Update the root values in the J9VMThread */
709
currentThread->arg0EA = newA0;
710
currentThread->pc = bytecodePC;
711
currentThread->literals = method;
712
currentThread->sp = sp;
713
}
714
715
716
/**
717
* Recursive helper for decompiling inlined frames.
718
*
719
* @param[in] *currentThread current thread
720
* @param[in] *decompileState the decompilation state copied from the stack walk
721
* @param[in] *decompRecord the decompilation record
722
* @param[in] inlineDepth the depth of inlining, 0 for the outer frame
723
* @param[in] *osrFrame the OSR frame from which to copy the information
724
*/
725
static void
726
buildInlineStackFrames(J9VMThread *currentThread, J9JITDecompileState *decompileState, J9JITDecompilationInfo *decompRecord, UDATA inlineDepth, J9OSRFrame *osrFrame)
727
{
728
J9JavaVM *vm = currentThread->javaVM;
729
J9MonitorEnterRecord *firstEnterRecord = osrFrame->monitorEnterRecords;
730
J9Method *method = osrFrame->method;
731
if (0 == inlineDepth) {
732
decompileOuterFrame(currentThread, decompileState, decompRecord, osrFrame);
733
} else {
734
J9OSRFrame *nextOSRFrame = (J9OSRFrame*)((U_8*)osrFrame + osrFrameSize(method));
735
buildInlineStackFrames(currentThread, decompileState, decompRecord, inlineDepth - 1, nextOSRFrame);
736
buildBytecodeFrame(currentThread, osrFrame);
737
}
738
/* Fix all of the monitor enter records for this frame to point to the new arg0EA.
739
* Filter out the record for the syncObject in synchronized methods. Only one such
740
* record will ever be detected in any frame. Link the remaining records into the list.
741
*/
742
if (NULL != firstEnterRecord) {
743
J9MonitorEnterRecord listHead;
744
J9MonitorEnterRecord *lastEnterRecord = &listHead;
745
J9MonitorEnterRecord *enterRecord = firstEnterRecord;
746
UDATA *arg0EA = currentThread->arg0EA;
747
j9object_t syncObject = NULL;
748
if (J9_ROM_METHOD_FROM_RAM_METHOD(method)->modifiers & J9AccSynchronized) {
749
syncObject = *(j9object_t*)(arg0EA - osrFrame->numberOfLocals + 1);
750
}
751
listHead.next = firstEnterRecord;
752
do {
753
J9MonitorEnterRecord *nextRecord = enterRecord->next;
754
if (enterRecord->object == syncObject) {
755
syncObject = NULL; /* Make sure syncObject isn't matched more than once */
756
lastEnterRecord->next = nextRecord;
757
pool_removeElement(currentThread->monitorEnterRecordPool, enterRecord);
758
} else {
759
enterRecord->arg0EA = CONVERT_TO_RELATIVE_STACK_OFFSET(currentThread, arg0EA);
760
lastEnterRecord = enterRecord;
761
}
762
enterRecord = nextRecord;
763
} while (NULL != enterRecord);
764
lastEnterRecord->next = currentThread->monitorEnterRecords;
765
currentThread->monitorEnterRecords = listHead.next;
766
}
767
768
/* If this frame has a notify frame pop pending, set the bit */
769
770
if (osrFrame->flags & J9OSRFRAME_NOTIFY_FRAME_POP) {
771
UDATA *bp = currentThread->arg0EA - osrFrame->numberOfLocals;
772
Trc_Decomp_performDecompile_addedPopNotification(currentThread, bp);
773
*bp |= J9SF_A0_REPORT_FRAME_POP_TAG;
774
}
775
}
776
777
778
/**
779
* Perform decompilation after gather information from the stack walk.
780
*
781
* @param[in] *currentThread current thread
782
* @param[in] *decompileState the decompilation state copied from the stack walk
783
* @param[in] *decompRecord the decompilation record
784
* @param[in] *osrFrame the first OSR frame to rebuild
785
* @param[in] numberOfFrames the total number of frames to rebuild
786
*/
787
static void
788
performDecompile(J9VMThread *currentThread, J9JITDecompileState *decompileState, J9JITDecompilationInfo *decompRecord, J9OSRFrame *osrFrame, UDATA numberOfFrames)
789
{
790
J9JavaVM *vm = currentThread->javaVM;
791
UDATA outgoingArgs[255];
792
UDATA outgoingArgCount = decompileState->argCount;
793
UDATA inlineDepth = numberOfFrames - 1;
794
795
Trc_Decomp_performDecompile_Entry(currentThread);
796
797
dumpStack(currentThread, "before decompilation");
798
799
if (FALSE == decompRecord->usesOSR) {
800
/* Not compiled with OSR - copy stack slots from JIT frame into OSR frame */
801
UDATA *jitTempBase = ((UDATA *) (((U_8 *) decompileState->bp) + ((J9JITStackAtlas *) decompileState->metaData->gcStackAtlas)->localBaseOffset)) + decompileState->metaData->tempOffset;
802
UDATA *osrTempBase = ((UDATA*)(osrFrame + 1)) + osrFrame->maxStack;
803
J9ROMMethod * romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(osrFrame->method);
804
UDATA argCount = J9_ARG_COUNT_FROM_ROM_METHOD(romMethod);
805
UDATA tempCount = osrFrame->numberOfLocals - argCount;
806
UDATA pendingStackHeight = osrFrame->pendingStackHeight;
807
808
/* Decompiling without OSR means old-style single-frame FSD */
809
Assert_CodertVM_true(vm->jitConfig->fsdEnabled);
810
Assert_CodertVM_true(1 == numberOfFrames);
811
812
/* The pending slots immediately precede the temps in both the OSR frame and the JIT frame, so copy them all at once */
813
memcpy(osrTempBase - pendingStackHeight, jitTempBase - pendingStackHeight, (tempCount + pendingStackHeight) * sizeof(UDATA));
814
}
815
816
/* Temporarily copy the outgoing arguments to the C stack */
817
memcpy(outgoingArgs, decompileState->sp, outgoingArgCount * sizeof(UDATA));
818
819
/* Rebuild the interpreter stack frames */
820
buildInlineStackFrames(currentThread, decompileState, decompRecord, inlineDepth, osrFrame);
821
822
/* Push the outgoing arguments onto the java stack */
823
currentThread->sp -= outgoingArgCount;
824
memcpy(currentThread->sp, outgoingArgs, outgoingArgCount * sizeof(UDATA));
825
826
Trc_Decomp_performDecompile_Exit(currentThread, currentThread->sp, currentThread->literals, currentThread->pc);
827
}
828
829
830
/**
831
* Decompile the outer (and possibly only) frame.
832
*
833
* @param[in] *currentThread current thread
834
* @param[in] *decompileState the decompilation state copied from the stack walk
835
* @param[in] *decompRecord the decompilation record
836
* @param[in] *osrFrame the OSR frame from which to copy the information
837
*/
838
static void
839
decompileOuterFrame(J9VMThread * currentThread, J9JITDecompileState * decompileState, J9JITDecompilationInfo * decompRecord, J9OSRFrame *osrFrame)
840
{
841
UDATA * newTempBase;
842
UDATA * oldTempBase;
843
UDATA * newPendingBase;
844
UDATA * oldPendingBase;
845
UDATA * stackFrame;
846
UDATA * newSP;
847
J9Method *method = osrFrame->method;
848
J9ROMMethod * romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);
849
UDATA argCount = J9_ARG_COUNT_FROM_ROM_METHOD(romMethod);
850
UDATA numberOfLocals = osrFrame->numberOfLocals;
851
UDATA tempCount = numberOfLocals - argCount;
852
U_8 ** jitReturnPCAddress = (U_8 **) &(((J9JITFrame *) (decompileState->bp))->returnPC);
853
U_8 * jitReturnPC = *jitReturnPCAddress;
854
UDATA * currentJ2iFrame = decompileState->j2iFrame;
855
UDATA pendingStackHeight = osrFrame->pendingStackHeight;
856
857
oldTempBase = ((UDATA*)(osrFrame + 1)) + osrFrame->maxStack;
858
859
/* Determine the shape of the new stack frame */
860
861
newTempBase = decompileState->a0 - numberOfLocals + 1;
862
if (decompileState->previousFrameBytecodes) {
863
/* Use the I2J returnSP in this case in order to account for the possible 8-alignment of the I2J args */
864
UDATA * correctTempBase = UNTAG2(decompileState->i2jState.returnSP, UDATA *) - numberOfLocals;
865
866
/* If the args were moved for alignment, copy them back to their original position */
867
if (newTempBase != correctTempBase) {
868
UDATA * newA0 = correctTempBase + numberOfLocals - 1;
869
memmove(correctTempBase + tempCount, newTempBase + tempCount, argCount * sizeof(UDATA));
870
newTempBase = correctTempBase;
871
decompileState->a0 = newA0;
872
}
873
stackFrame = (UDATA *) (((U_8 *) newTempBase) - sizeof(J9SFStackFrame));
874
} else {
875
stackFrame = (UDATA *) (((U_8 *) newTempBase) - sizeof(J9SFJ2IFrame));
876
}
877
newPendingBase = stackFrame - pendingStackHeight;
878
oldPendingBase = oldTempBase - pendingStackHeight;
879
newSP = newPendingBase;
880
881
/* If the JIT stack frame has not been constructed, don't attempt to read from it */
882
883
UDATA resolveFrameType = decompileState->resolveFrameFlags & J9_STACK_FLAGS_JIT_FRAME_SUB_TYPE_MASK;
884
if (J9_STACK_FLAGS_JIT_STACK_OVERFLOW_RESOLVE_FRAME == resolveFrameType) {
885
Trc_Decomp_performDecompile_monitorNotEntered(currentThread);
886
887
/* Temps have not been pushed yet - zero them and set up the sync object (if any) */
888
889
memset(newTempBase, 0, tempCount * sizeof(UDATA));
890
if (romMethod->modifiers & J9AccSynchronized) {
891
if (romMethod->modifiers & J9AccStatic) {
892
newTempBase[0] = (UDATA)J9VM_J9CLASS_TO_HEAPCLASS(J9_CLASS_FROM_METHOD(method));
893
} else {
894
newTempBase[0] = *(decompileState->a0);
895
}
896
} else if (J9ROMMETHOD_IS_NON_EMPTY_OBJECT_CONSTRUCTOR(romMethod)) {
897
newTempBase[0] = *(decompileState->a0);
898
}
899
} else {
900
/* Copy the temps to their new location */
901
902
memcpy(newTempBase, oldTempBase, tempCount * sizeof(UDATA));
903
}
904
905
/* Copy pending pushes */
906
907
memcpy(newPendingBase, oldPendingBase, pendingStackHeight * sizeof(UDATA));
908
909
/* Create the stack frame, either a pure bytecode frame or a J2I frame, depending on the previous frame. */
910
911
if (decompileState->previousFrameBytecodes) {
912
J9SFStackFrame * bytecodeFrame = (J9SFStackFrame *) stackFrame;
913
914
Trc_Decomp_performDecompile_buildingBCFrame(currentThread, stackFrame);
915
916
bytecodeFrame->savedPC = decompileState->i2jState.pc;
917
bytecodeFrame->savedCP = decompileState->i2jState.literals;
918
bytecodeFrame->savedA0 = decompileState->i2jState.a0;
919
} else {
920
J9SFJ2IFrame * j2iFrame = (J9SFJ2IFrame *) stackFrame;
921
char * returnChar;
922
J9JITDecompilationInfo * info;
923
924
Trc_Decomp_performDecompile_buildingJ2IFrame(currentThread, stackFrame);
925
926
memcpy(&(j2iFrame->i2jState), &(decompileState->i2jState), sizeof(J9I2JState));
927
memcpy(&(j2iFrame->J9SW_LOWEST_MEMORY_PRESERVED_REGISTER), decompileState->preservedRegisterValues, J9SW_JIT_CALLEE_PRESERVED_SIZE * sizeof(UDATA));
928
j2iFrame->specialFrameFlags = J9_STACK_FLAGS_JIT_CALL_IN_FRAME | J9_STACK_FLAGS_JIT_CALL_IN_TYPE_J2_I;
929
j2iFrame->returnAddress = jitReturnPC;
930
j2iFrame->previousJ2iFrame = currentJ2iFrame;
931
currentJ2iFrame = (UDATA *) &(j2iFrame->taggedReturnSP);
932
933
returnChar = (char *) J9UTF8_DATA(J9ROMMETHOD_SIGNATURE(romMethod));
934
while (*returnChar++ != ')') ;
935
switch(*returnChar) {
936
case 'V':
937
j2iFrame->exitPoint = J9_BUILDER_SYMBOL(jitExitInterpreter0);
938
break;
939
case 'D':
940
j2iFrame->exitPoint = J9_BUILDER_SYMBOL(jitExitInterpreterD);
941
break;
942
case 'F':
943
j2iFrame->exitPoint = J9_BUILDER_SYMBOL(jitExitInterpreterF);
944
break;
945
case 'J':
946
#ifdef J9VM_ENV_DATA64
947
case '[':
948
case 'L':
949
#endif
950
j2iFrame->exitPoint = J9_BUILDER_SYMBOL(jitExitInterpreterJ);
951
break;
952
default:
953
j2iFrame->exitPoint = J9_BUILDER_SYMBOL(jitExitInterpreter1);
954
break;
955
}
956
957
#ifdef J9SW_NEEDS_JIT_2_INTERP_CALLEE_ARG_POP
958
j2iFrame->taggedReturnSP = (UDATA *) (((U_8 *) (((UDATA *) (j2iFrame + 1)) + argCount + tempCount)));
959
#else
960
j2iFrame->taggedReturnSP = (UDATA *) (((U_8 *) (((UDATA *) (j2iFrame + 1)) + tempCount)));
961
#endif
962
963
/* If the next thing on the decompilation stack used to point to the return address save slot in the decompiled JIT frame, point it to the slot in the J2I frame. */
964
965
if ((info = currentThread->decompilationStack) != NULL) {
966
if (info->pcAddress == jitReturnPCAddress) {
967
Trc_Decomp_performDecompile_fixingDecompStack(currentThread, info, info->pcAddress, &(j2iFrame->returnAddress), info->pc);
968
info->pcAddress = &(j2iFrame->returnAddress);
969
}
970
}
971
972
}
973
974
/* Fill in vmThread values for bytecode execution */
975
976
currentThread->pc = osrFrame->bytecodePCOffset + J9_BYTECODE_START_FROM_RAM_METHOD(osrFrame->method);
977
currentThread->literals = decompileState->literals;
978
currentThread->arg0EA = decompileState->a0;
979
currentThread->sp = newSP;
980
currentThread->j2iFrame = currentJ2iFrame;
981
982
/* If the outer framed failed a method monitor enter, hide the interpreted version to prevent exception throw
983
* from exiting the monitor that was never entered.
984
*/
985
if (J9_STACK_FLAGS_JIT_FAILED_METHOD_MONITOR_ENTER_RESOLVE == resolveFrameType) {
986
newTempBase[-1] |= J9SF_A0_INVISIBLE_TAG;
987
}
988
}
989
990
991
/**
992
* Fix the java stack to account for a newly-added decompilation. This involves modifying
993
* the return address in the stack which would be used to return to the frame for which the
994
* decompilation was added.
995
*
996
* @param[in] *currentThread current thread
997
* @param[in] *walkState stack walk state (already at the OSR point)
998
* @param[in] *info the new decompilation record
999
* @param[in] reason the reason for the decompilation
1000
* @param[in] **link pointer to the next pointer of the previous decompilation record
1001
* (this may be the root of the decompilation stack)
1002
*/
1003
static void
1004
fixStackForNewDecompilation(J9VMThread * currentThread, J9StackWalkState * walkState, J9JITDecompilationInfo *info, UDATA reason, J9JITDecompilationInfo **link)
1005
{
1006
J9JavaVM* vm = currentThread->javaVM;
1007
U_8 ** pcStoreAddress = walkState->pcAddress;
1008
1009
/* Fill in the decompilation record and link it into the stack */
1010
1011
info->pcAddress = walkState->pcAddress;
1012
info->bp = walkState->bp;
1013
info->method = walkState->method;
1014
info->reason = reason;
1015
info->pc = walkState->pc;
1016
info->next = *link;
1017
*link = info;
1018
1019
/* Slam the return address to point to the appropriate decompile */
1020
1021
if (0 != walkState->resolveFrameFlags) {
1022
UDATA resolveFrameType = walkState->resolveFrameFlags & J9_STACK_FLAGS_JIT_FRAME_SUB_TYPE_MASK;
1023
switch(resolveFrameType) {
1024
case J9_STACK_FLAGS_JIT_STACK_OVERFLOW_RESOLVE_FRAME:
1025
if (J9_ARE_ANY_BITS_SET(J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method)->modifiers, J9AccSynchronized)) {
1026
Trc_Decomp_addDecompilation_beforeSyncMonitorEnter(currentThread);
1027
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileBeforeMethodMonitorEnter);
1028
break;
1029
}
1030
/* Intentional fall-through */
1031
case J9_STACK_FLAGS_JIT_METHOD_MONITOR_ENTER_RESOLVE:
1032
Trc_Decomp_addDecompilation_beforeReportMethodEnter(currentThread);
1033
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileBeforeReportMethodEnter);
1034
break;
1035
case J9_STACK_FLAGS_JIT_MONITOR_ENTER_RESOLVE:
1036
Trc_Decomp_addDecompilation_atMonitorEnter(currentThread);
1037
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileAfterMonitorEnter);
1038
break;
1039
case J9_STACK_FLAGS_JIT_ALLOCATION_RESOLVE:
1040
Trc_Decomp_addDecompilation_atAllocate(currentThread);
1041
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileAfterAllocation);
1042
break;
1043
case J9_STACK_FLAGS_JIT_EXCEPTION_CATCH_RESOLVE:
1044
/* Decompile during jitReportExceptionCatch */
1045
Trc_Decomp_addDecompilation_atExceptionCatch(currentThread);
1046
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileAtExceptionCatch);
1047
break;
1048
default:
1049
Trc_Decomp_addDecompilation_atCurrentPC(currentThread);
1050
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileAtCurrentPC);
1051
break;
1052
}
1053
} else {
1054
J9UTF8 * sig, *name;
1055
char * returnChar;
1056
J9OSRBuffer *osrBuffer = &info->osrBuffer;
1057
J9OSRFrame *osrFrame = (J9OSRFrame*)(osrBuffer + 1);
1058
U_8 * bytecodePC = osrFrame->bytecodePCOffset + J9_BYTECODE_START_FROM_RAM_METHOD(osrFrame->method);
1059
1060
Trc_Decomp_addDecompilation_atInvoke(currentThread);
1061
1062
/* PC points at an invoke - fetch the name and signature it references */
1063
J9ROMNameAndSignature *nameAndSig = getNASFromInvoke(bytecodePC, J9_CLASS_FROM_METHOD(osrFrame->method)->romClass);
1064
sig = J9ROMNAMEANDSIGNATURE_SIGNATURE(nameAndSig);
1065
name = J9ROMNAMEANDSIGNATURE_NAME(nameAndSig);
1066
Trc_Decomp_addDecompilation_explainInvoke(currentThread, J9UTF8_LENGTH(name), J9UTF8_DATA(name), J9UTF8_LENGTH(sig), J9UTF8_DATA(sig));
1067
1068
returnChar = (char *) J9UTF8_DATA(sig);
1069
while (*returnChar++ != ')') ;
1070
switch(*returnChar) {
1071
case 'V':
1072
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileOnReturn0);
1073
break;
1074
case 'D':
1075
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileOnReturnD);
1076
break;
1077
case 'F':
1078
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileOnReturnF);
1079
break;
1080
case 'J':
1081
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileOnReturnJ);
1082
break;
1083
#ifdef J9VM_ENV_DATA64
1084
case '[':
1085
case 'L':
1086
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileOnReturnL);
1087
break;
1088
#endif
1089
default:
1090
*pcStoreAddress = (U_8 *) J9_BUILDER_SYMBOL(jitDecompileOnReturn1);
1091
break;
1092
}
1093
}
1094
1095
/* Enable stack dump after linking the decompilation into the stack if -verbose:stackwalk=0 is specified */
1096
dumpStack(walkState->walkThread, "after fixStackForNewDecompilation");
1097
}
1098
1099
1100
static J9JITDecompilationInfo *
1101
addDecompilation(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA reason)
1102
{
1103
PORT_ACCESS_FROM_VMC(currentThread);
1104
J9JavaVM* vm = currentThread->javaVM;
1105
J9VMThread * decompileThread = walkState->walkThread;
1106
J9JITDecompilationInfo * info;
1107
J9JITDecompilationInfo ** previous;
1108
J9JITDecompilationInfo * current;
1109
J9JITExceptionTable *metaData = walkState->jitInfo;
1110
UDATA allocSize = sizeof(J9JITDecompilationInfo);
1111
UDATA osrFrame = FALSE;
1112
J9OSRData osrData;
1113
1114
Trc_Decomp_addDecompilation_Entry(currentThread, walkState->method);
1115
decompPrintMethod(currentThread, walkState->method);
1116
Trc_Decomp_addDecompilation_walkStateInfo(currentThread, walkState->bp, walkState->arg0EA, walkState->constantPool, walkState->pc);
1117
Trc_Decomp_addDecompilation_reason(currentThread, reason,
1118
(reason & JITDECOMP_CODE_BREAKPOINT) ? " CODE_BREAKPOINT" : "",
1119
(reason & JITDECOMP_DATA_BREAKPOINT) ? " DATA_BREAKPOINT" : "",
1120
(reason & JITDECOMP_HOTSWAP) ? " HOTSWAP" : "",
1121
(reason & JITDECOMP_POP_FRAMES) ? " POP_FRAMES" : "",
1122
(reason & JITDECOMP_SINGLE_STEP) ? " SINGLE_STEP" : "",
1123
(reason & JITDECOMP_STACK_LOCALS_MODIFIED) ? " STACK_LOCALS_MODIFIED" : "",
1124
(reason & JITDECOMP_FRAME_POP_NOTIFICATION) ? " FRAME_POP_NOTIFICATION" : "");
1125
1126
/* addDecompilation must be called only when the walkState represents a compiled frame */
1127
Assert_CodertVM_true(NULL != metaData);
1128
1129
/* The decompilation is ordered by frame, with lesser frame values appearing at the beginning */
1130
1131
previous = &(decompileThread->decompilationStack);
1132
while ((current = *previous) != NULL) {
1133
/* If a decompilation for this frame already exists, tag it with the new reason and return */
1134
1135
if (current->bp == walkState->bp) {
1136
Trc_Decomp_addDecompilation_existingRecord(currentThread, current);
1137
current->reason |= reason;
1138
return current;
1139
}
1140
if (current->bp > walkState->bp) break;
1141
previous = &(current->next);
1142
}
1143
1144
/* OSR is not appropriate for frames whose stack frame has not been created */
1145
UDATA resolveFrameFlags = walkState->resolveFrameFlags;
1146
UDATA resolveFrameType = resolveFrameFlags & J9_STACK_FLAGS_JIT_FRAME_SUB_TYPE_MASK;
1147
if (J9_STACK_FLAGS_JIT_STACK_OVERFLOW_RESOLVE_FRAME != resolveFrameType) {
1148
if (usesOSR(currentThread, metaData)) {
1149
Trc_Decomp_addDecompilation_osrFrame(currentThread);
1150
osrFrame = TRUE;
1151
}
1152
}
1153
1154
/* Allocate and zero the decompilation record, taking the OSR buffer into account */
1155
allocSize += osrAllFramesSize(currentThread, metaData, walkState->pc, resolveFrameFlags);
1156
info = (J9JITDecompilationInfo *) j9mem_allocate_memory(allocSize, OMRMEM_CATEGORY_JIT);
1157
if (!info) {
1158
Trc_Decomp_addDecompilation_allocFailed(currentThread);
1159
return NULL;
1160
}
1161
memset(info, 0, allocSize);
1162
Trc_Decomp_addDecompilation_allocRecord(currentThread, info);
1163
info->usesOSR = osrFrame;
1164
1165
/* Fill in the interpreter values in the OSR buffer */
1166
osrData.targetThread = walkState->walkThread;
1167
osrData.metaData = metaData;
1168
osrData.jitPC = walkState->pc;
1169
osrData.resolveFrameFlags = walkState->resolveFrameFlags;
1170
osrData.objectArgScanCursor = getObjectArgScanCursor(walkState);
1171
osrData.objectTempScanCursor = getObjectTempScanCursor(walkState);
1172
if (OSR_OK != initializeOSRBuffer(currentThread, &info->osrBuffer, &osrData)) {
1173
Trc_Decomp_addDecompilation_allocFailed(currentThread);
1174
j9mem_free_memory(info);
1175
return NULL;
1176
}
1177
1178
if (osrFrame) {
1179
UDATA scratchBufferSize = roundedOSRScratchBufferSize(currentThread, metaData, walkState->pc);
1180
UDATA jitStackFrameSize = (UDATA)(walkState->arg0EA + 1) - (UDATA)walkState->unwindSP;
1181
void *osrScratchBuffer = j9mem_allocate_memory(scratchBufferSize + jitStackFrameSize, OMRMEM_CATEGORY_JIT);
1182
UDATA mustDecompile = FALSE;
1183
UDATA osrResultCode = OSR_OK;
1184
1185
/* TODO: use global buffer here? */
1186
if (NULL == osrScratchBuffer) {
1187
Trc_Decomp_addDecompilation_allocFailed(currentThread);
1188
j9mem_free_memory(info);
1189
return NULL;
1190
}
1191
1192
osrResultCode = performOSR(currentThread, walkState, &info->osrBuffer, (U_8*)osrScratchBuffer, scratchBufferSize, jitStackFrameSize, &mustDecompile);
1193
if (OSR_OK != osrResultCode) {
1194
Trc_Decomp_addDecompilation_osrFailed(currentThread);
1195
j9mem_free_memory(osrScratchBuffer);
1196
j9mem_free_memory(info);
1197
return NULL;
1198
}
1199
if (mustDecompile) {
1200
Trc_Decomp_addDecompilation_osrMustDecompile(currentThread);
1201
reason |= JITDECOMP_ON_STACK_REPLACEMENT;
1202
}
1203
j9mem_free_memory(osrScratchBuffer);
1204
}
1205
1206
/* Add the decompilation to the stack */
1207
fixStackForNewDecompilation(currentThread, walkState, info, reason, previous);
1208
1209
Trc_Decomp_addDecompilation_Exit(currentThread, info);
1210
1211
return info;
1212
}
1213
1214
void
1215
c_jitDecompileAtExceptionCatch(J9VMThread * currentThread)
1216
{
1217
/* Fetch the exception from the JIT */
1218
j9object_t exception = (j9object_t)currentThread->jitException;
1219
/* Fetch and unstack the decompilation information for this frame */
1220
J9JITDecompilationInfo *decompRecord = fetchAndUnstackDecompilationInfo(currentThread);
1221
U_8 *jitPC = decompRecord->pc;
1222
1223
Trc_Decomp_DecompileAtExceptionCatch_Entry(currentThread, jitPC, exception);
1224
1225
/* Simulate a call to a resolve helper to make the stack walkable */
1226
buildBranchJITResolveFrame(currentThread, jitPC, J9_STACK_FLAGS_JIT_EXCEPTION_CATCH_RESOLVE);
1227
1228
J9JavaVM *vm = currentThread->javaVM;
1229
J9JITDecompileState decompileState;
1230
J9StackWalkState walkState;
1231
J9OSRBuffer *osrBuffer = &decompRecord->osrBuffer;
1232
UDATA numberOfFrames = osrBuffer->numberOfFrames;
1233
J9OSRFrame *osrFrame = (J9OSRFrame*)(osrBuffer + 1);
1234
J9JITExceptionTable *metaData = NULL;
1235
1236
/* Collect the required information from the stack - top visible frame is the decompile frame */
1237
walkState.flags = J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES | J9_STACKWALK_VISIBLE_ONLY | J9_STACKWALK_MAINTAIN_REGISTER_MAP | J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_SAVE_STACKED_REGISTERS;
1238
walkState.skipCount = 0;
1239
walkState.frameWalkFunction = decompileMethodFrameIterator;
1240
walkState.walkThread = currentThread;
1241
walkState.userData1 = &decompileState;
1242
walkState.userData2 = NULL;
1243
vm->walkStackFrames(currentThread, &walkState);
1244
metaData = decompileState.metaData;
1245
1246
/* Determine in which inlined frame the exception is being caught */
1247
UDATA newNumberOfFrames = 1;
1248
void *stackMap = NULL;
1249
void *inlineMap = NULL;
1250
void *inlinedCallSite = NULL;
1251
/* Note we need to add 1 to the JIT PC here in order to get the correct map at the exception handler
1252
* because jitGetMapsFromPC is expecting a return address, so it subtracts 1. The value stored in the
1253
* decomp record is the start address of the compiled exception handler.
1254
*/
1255
jitGetMapsFromPC(currentThread, vm, metaData, (UDATA)jitPC + 1, &stackMap, &inlineMap);
1256
Assert_CodertVM_false(NULL == inlineMap);
1257
if (NULL != getJitInlinedCallInfo(metaData)) {
1258
inlinedCallSite = getFirstInlinedCallSite(metaData, inlineMap);
1259
if (inlinedCallSite != NULL) {
1260
newNumberOfFrames = getJitInlineDepthFromCallSite(metaData, inlinedCallSite) + 1;
1261
}
1262
}
1263
Assert_CodertVM_true(numberOfFrames >= newNumberOfFrames);
1264
J9Pool *monitorEnterRecordPool = currentThread->monitorEnterRecordPool;
1265
while (numberOfFrames != newNumberOfFrames) {
1266
/* Discard the monitor records for the popped frames */
1267
J9MonitorEnterRecord *enterRecord = osrFrame->monitorEnterRecords;
1268
while (NULL != enterRecord) {
1269
J9MonitorEnterRecord *recordToFree = enterRecord;
1270
enterRecord = enterRecord->next;
1271
pool_removeElement(monitorEnterRecordPool, recordToFree);
1272
}
1273
osrFrame->monitorEnterRecords = NULL;
1274
osrFrame = (J9OSRFrame*)((U_8*)osrFrame + osrFrameSize(osrFrame->method));
1275
numberOfFrames -= 1;
1276
}
1277
1278
/* Fix the OSR frame to resume at the catch point with an empty pending stack (the caught exception
1279
* is pushed after decompilation completes).
1280
*/
1281
osrFrame->bytecodePCOffset = getCurrentByteCodeIndexAndIsSameReceiver(metaData, inlineMap, inlinedCallSite, NULL);
1282
Trc_Decomp_jitInterpreterPCFromWalkState_Entry(jitPC);
1283
Trc_Decomp_jitInterpreterPCFromWalkState_exHandler(osrFrame->bytecodePCOffset);
1284
osrFrame->pendingStackHeight = 0;
1285
1286
performDecompile(currentThread, &decompileState, decompRecord, osrFrame, numberOfFrames);
1287
1288
freeDecompilationRecord(currentThread, decompRecord, TRUE);
1289
1290
/* Push the exception */
1291
UDATA *sp = currentThread->sp - 1;
1292
*(j9object_t*)sp = exception;
1293
currentThread->sp = sp;
1294
dumpStack(currentThread, "after jitDecompileAtExceptionCatch");
1295
currentThread->tempSlot = (UDATA)J9_BUILDER_SYMBOL(executeCurrentBytecodeFromJIT);
1296
1297
Trc_Decomp_DecompileAtExceptionCatch_Exit(currentThread, currentThread->sp, currentThread->literals, currentThread->pc);
1298
}
1299
1300
#if (defined(J9VM_INTERP_HOT_CODE_REPLACEMENT)) /* priv. proto (autogen) */
1301
1302
void
1303
jitDecompileMethodForFramePop(J9VMThread * currentThread, UDATA skipCount)
1304
{
1305
J9JITDecompileState decompileState;
1306
J9StackWalkState walkState;
1307
J9JITDecompilationInfo * decompRecord = currentThread->decompilationStack;
1308
J9JavaVM *vm = currentThread->javaVM;
1309
J9OSRBuffer *osrBuffer = &decompRecord->osrBuffer;
1310
UDATA numberOfFrames = osrBuffer->numberOfFrames;
1311
J9OSRFrame *osrFrame = (J9OSRFrame*)(osrBuffer + 1);
1312
1313
Trc_Decomp_DecompileMethodForFramePop_Entry(currentThread, decompRecord->pc);
1314
1315
/* Unstack the decomp record and fix the stacked PC */
1316
1317
*(decompRecord->pcAddress) = decompRecord->pc;
1318
currentThread->decompilationStack = decompRecord->next;
1319
1320
/* Collect the required information from the stack */
1321
1322
walkState.flags = J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES | J9_STACKWALK_VISIBLE_ONLY | J9_STACKWALK_MAINTAIN_REGISTER_MAP;
1323
walkState.skipCount = skipCount;
1324
walkState.frameWalkFunction = decompileMethodFrameIterator;
1325
walkState.walkThread = currentThread;
1326
walkState.userData1 = &decompileState;
1327
walkState.userData2 = NULL;
1328
currentThread->javaVM->walkStackFrames(currentThread, &walkState);
1329
1330
/* Now decompile the frame */
1331
1332
performDecompile(currentThread, &decompileState, decompRecord, osrFrame, numberOfFrames);
1333
freeDecompilationRecord(currentThread, decompRecord, TRUE);
1334
1335
dumpStack(currentThread, "after jitDecompileMethodForFramePop");
1336
1337
Trc_Decomp_DecompileMethodForFramePop_Exit(currentThread);
1338
}
1339
1340
#endif /* J9VM_INTERP_HOT_CODE_REPLACEMENT (autogen) */
1341
1342
1343
static J9JITDecompilationInfo *
1344
deleteDecompilationForExistingFrame(J9VMThread * decompileThread, J9JITDecompilationInfo * info)
1345
{
1346
PORT_ACCESS_FROM_VMC(decompileThread);
1347
J9JITDecompilationInfo * next = info->next;
1348
1349
Trc_Decomp_deleteDecompilationForExistingFrame_Entry();
1350
1351
*(info->pcAddress) = info->pc;
1352
1353
Trc_Decomp_deleteDecompilationForExistingFrame_freeDecomp(info, info->bp);
1354
1355
freeDecompilationRecord(decompileThread, info, FALSE);
1356
1357
Trc_Decomp_deleteDecompilationForExistingFrame_Exit();
1358
1359
return next;
1360
}
1361
1362
1363
static void
1364
freeDecompilationRecord(J9VMThread * decompileThread, J9JITDecompilationInfo * info, UDATA retain)
1365
{
1366
PORT_ACCESS_FROM_VMC(decompileThread);
1367
1368
j9mem_free_memory(decompileThread->lastDecompilation);
1369
decompileThread->lastDecompilation = NULL;
1370
if (info->reason & JITDECOMP_OSR_GLOBAL_BUFFER_USED) {
1371
omrthread_monitor_exit(decompileThread->javaVM->osrGlobalBufferLock);
1372
} else {
1373
if (retain) {
1374
decompileThread->lastDecompilation = info;
1375
} else {
1376
j9mem_free_memory(info);
1377
}
1378
}
1379
}
1380
1381
1382
void
1383
jitDataBreakpointAdded(J9VMThread * currentThread)
1384
{
1385
J9JavaVM *vm = currentThread->javaVM;
1386
J9JITConfig *jitConfig = vm->jitConfig;
1387
1388
/* We have exclusive */
1389
1390
Trc_Decomp_jitDataBreakpointAdded_Entry(currentThread);
1391
1392
++(jitConfig->dataBreakpointCount);
1393
1394
/* In normal mode (where the JIT does not generate code to trigger field watch events), every addition
1395
* of a watch must discard all compiled code. In the new mode where the JIT does generate watch triggers,
1396
* Only the addition of the first watch requires discarding compiled code. From then on, the JIT will
1397
* generate the appropriate code, so no discarding is required. See jitDataBreakpointAdded regarding
1398
* transitioning back out of this mode.
1399
*/
1400
bool inlineWatches = J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags, J9_EXTENDED_RUNTIME_JIT_INLINE_WATCHES);
1401
if (!inlineWatches || !jitConfig->inlineFieldWatches) {
1402
/* Remove all breakpoints before resetting the methods */
1403
1404
removeAllBreakpoints(currentThread);
1405
1406
/* Toss the compilation queue */
1407
1408
if (inlineWatches) {
1409
jitConfig->jitFlushCompilationQueue(currentThread, J9FlushCompQueueDataBreakpoint);
1410
/* Make all future compilations inline the field watch code */
1411
jitConfig->inlineFieldWatches = TRUE;
1412
} else {
1413
jitConfig->jitClassesRedefined(currentThread, 0, NULL, 0);
1414
}
1415
1416
/* Find every method which has been translated and mark it for retranslation */
1417
1418
jitResetAllMethods(currentThread);
1419
1420
/* Reinstall the breakpoints */
1421
1422
reinstallAllBreakpoints(currentThread);
1423
1424
/* Mark every JIT method in every stack for decompilation */
1425
1426
decompileAllMethodsInAllStacks(currentThread, JITDECOMP_DATA_BREAKPOINT);
1427
}
1428
1429
Trc_Decomp_jitDataBreakpointAdded_Exit(currentThread);
1430
}
1431
1432
1433
void
1434
jitDataBreakpointRemoved(J9VMThread * currentThread)
1435
{
1436
J9JavaVM *vm = currentThread->javaVM;
1437
1438
/* We have exclusive */
1439
1440
Trc_Decomp_jitDataBreakpointRemoved_Entry(currentThread);
1441
1442
--(vm->jitConfig->dataBreakpointCount);
1443
1444
/* For now, once the JIT is in field watch mode, it stays that way forever, even if all current
1445
* watches are removed. This may change in the future.
1446
*/
1447
if (J9_ARE_NO_BITS_SET(vm->extendedRuntimeFlags, J9_EXTENDED_RUNTIME_JIT_INLINE_WATCHES)) {
1448
/* Remove all breakpoints before resetting the methods */
1449
1450
removeAllBreakpoints(currentThread);
1451
1452
/* Find every method which has been prevented from being translated and mark it for retranslation */
1453
1454
jitResetAllUntranslateableMethods(currentThread);
1455
1456
/* Reinstall the breakpoints */
1457
1458
reinstallAllBreakpoints(currentThread);
1459
}
1460
1461
Trc_Decomp_jitDataBreakpointRemoved_Exit(currentThread);
1462
}
1463
1464
1465
static void
1466
decompileAllMethodsInAllStacks(J9VMThread * currentThread, UDATA reason)
1467
{
1468
J9VMThread * loopThread;
1469
1470
/* Mark every JIT method in every stack for decompilation */
1471
1472
loopThread = currentThread;
1473
do {
1474
J9StackWalkState walkState;
1475
1476
walkState.flags = J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES | J9_STACKWALK_VISIBLE_ONLY | J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_MAINTAIN_REGISTER_MAP;
1477
walkState.skipCount = 0;
1478
walkState.frameWalkFunction = decompileAllFrameIterator;
1479
walkState.walkThread = loopThread;
1480
walkState.userData1 = (void *) reason;
1481
currentThread->javaVM->walkStackFrames(currentThread, &walkState);
1482
} while ((loopThread = loopThread->linkNext) != currentThread);
1483
}
1484
1485
1486
static UDATA
1487
decompileAllFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkState)
1488
{
1489
/* Decompile all JIT frames */
1490
1491
if (walkState->jitInfo) {
1492
addDecompilation(currentThread, walkState, (UDATA) walkState->userData1);
1493
}
1494
1495
return J9_STACKWALK_KEEP_ITERATING;
1496
}
1497
1498
1499
static void
1500
deleteAllDecompilations(J9VMThread * currentThread, UDATA reason, J9Method * method)
1501
{
1502
J9VMThread * loopThread;
1503
1504
Trc_Decomp_deleteAllDecompilations_Entry(currentThread);
1505
1506
loopThread = currentThread;
1507
do {
1508
J9JITDecompilationInfo ** previous;
1509
J9JITDecompilationInfo * current;
1510
1511
previous = &(loopThread->decompilationStack);
1512
while ((current = *previous) != NULL) {
1513
if ((current->reason & reason) && (!method || (current->method == method))) {
1514
current->reason &= ~reason;
1515
if (current->reason) {
1516
Trc_Decomp_deleteAllDecompilations_notFreeingRecord(currentThread, current, current->reason);
1517
previous = &(current->next);
1518
} else {
1519
*previous = deleteDecompilationForExistingFrame(loopThread, current);
1520
}
1521
} else {
1522
previous = &(current->next);
1523
}
1524
}
1525
} while ((loopThread = loopThread->linkNext) != currentThread);
1526
1527
Trc_Decomp_deleteAllDecompilations_Exit(currentThread);
1528
}
1529
1530
1531
void
1532
jitExceptionCaught(J9VMThread * currentThread)
1533
{
1534
J9StackWalkState * walkState = currentThread->stackWalkState;
1535
1536
Trc_Decomp_jitExceptionCaught_Entry(currentThread, walkState->arg0EA);
1537
1538
/* Called when an exception is caught, the thread's walkState knows how far to pop */
1539
1540
J9JITDecompilationInfo *catchDecompile = jitCleanUpDecompilationStack(currentThread, walkState, FALSE);
1541
void *handlerPC = walkState->userData2;
1542
1543
/* If the catch frame is not JIT, nothing more needs to be done */
1544
1545
if (!walkState->jitInfo) {
1546
Trc_Decomp_jitExceptionCaught_notJITFrame(currentThread);
1547
return;
1548
}
1549
1550
/* userData4 indicates whether or not the handler is synthetic */
1551
if (NULL != walkState->userData4) {
1552
/* The exception handler has been inserted by the JIT in order to exit the monitor
1553
* for an inlined synchronized method - do not report the exception catch event or
1554
* attempt to decompile at this point. The handler will rethrow the exception after
1555
* the monitor exit and the catch will be reported when the real catch block that came
1556
* from the bytecodes is reached.
1557
*/
1558
Trc_Decomp_jitExceptionCaught_SyntheticHandler(currentThread);
1559
} else {
1560
Trc_Decomp_jitExceptionCaught_JITFrame(currentThread);
1561
1562
/* If a decompilation record exists for the catch frame, update the PC to be the exception handler PC */
1563
1564
if (NULL != catchDecompile) {
1565
Trc_Decomp_jitExceptionCaught_frameMarked(currentThread, walkState->bp);
1566
catchDecompile->pc = (U_8 *)handlerPC;
1567
}
1568
1569
/* Report the exception catch event if hooked */
1570
1571
if (J9_EVENT_IS_HOOKED(currentThread->javaVM->hookInterface, J9HOOK_VM_EXCEPTION_CATCH)) {
1572
Trc_Decomp_jitExceptionCaught_mustReportNormal(currentThread, walkState->arg0EA);
1573
1574
if (catchDecompile) {
1575
Trc_Decomp_jitExceptionCaught_decompileRequested(currentThread);
1576
currentThread->floatTemp4 = J9_BUILDER_SYMBOL(jitDecompileAtExceptionCatch);
1577
} else {
1578
Trc_Decomp_jitExceptionCaught_notDecompiling(currentThread);
1579
currentThread->floatTemp4 = handlerPC;
1580
}
1581
walkState->userData2 = J9_BUILDER_SYMBOL(jitReportExceptionCatch);
1582
} else {
1583
Trc_Decomp_jitExceptionCaught_notReportingCatch(currentThread);
1584
if (catchDecompile) {
1585
Trc_Decomp_jitExceptionCaught_decompileRequested(currentThread);
1586
walkState->userData2 = J9_BUILDER_SYMBOL(jitDecompileAtExceptionCatch);
1587
} else {
1588
Trc_Decomp_jitExceptionCaught_notDecompiling(currentThread);
1589
}
1590
}
1591
}
1592
1593
Trc_Decomp_jitExceptionCaught_Exit(currentThread);
1594
}
1595
1596
1597
static void
1598
markMethodBreakpointed(J9VMThread * currentThread, J9JITBreakpointedMethod * breakpointedMethod)
1599
{
1600
J9Method * method = breakpointedMethod->method;
1601
void * extra = method->extra;
1602
1603
breakpointedMethod->hasBeenTranslated = FALSE;
1604
if ((((UDATA) extra) & J9_STARTPC_NOT_TRANSLATED) == 0) {
1605
breakpointedMethod->hasBeenTranslated = TRUE;
1606
_fsdSwitchToInterpPatchEntry(extra);
1607
}
1608
1609
method->constantPool = (J9ConstantPool *) ((UDATA) method->constantPool | (UDATA)J9_STARTPC_METHOD_BREAKPOINTED);
1610
if (NULL != currentThread->javaVM->jitConfig->jitMethodBreakpointed) { // TODO: remove once JIT is updated
1611
currentThread->javaVM->jitConfig->jitMethodBreakpointed(currentThread, method);
1612
}
1613
}
1614
1615
1616
static void
1617
markMethodUnbreakpointed(J9VMThread * currentThread, J9JITBreakpointedMethod * breakpointedMethod)
1618
{
1619
J9Method * method = breakpointedMethod->method;
1620
1621
method->constantPool = (J9ConstantPool *) ((UDATA) method->constantPool & ~(UDATA)J9_STARTPC_METHOD_BREAKPOINTED);
1622
if (breakpointedMethod->hasBeenTranslated) {
1623
_fsdRestoreToJITPatchEntry(method->extra);
1624
}
1625
if (NULL != currentThread->javaVM->jitConfig->jitMethodUnbreakpointed) { // TODO: remove once JIT is updated
1626
currentThread->javaVM->jitConfig->jitMethodUnbreakpointed(currentThread, method);
1627
}
1628
}
1629
1630
1631
static void
1632
removeAllBreakpoints(J9VMThread * currentThread)
1633
{
1634
J9JITBreakpointedMethod * breakpointedMethod = currentThread->javaVM->jitConfig->breakpointedMethods;
1635
1636
while (breakpointedMethod) {
1637
markMethodUnbreakpointed(currentThread, breakpointedMethod);
1638
breakpointedMethod = breakpointedMethod->link;
1639
}
1640
}
1641
1642
1643
static void
1644
reinstallAllBreakpoints(J9VMThread * currentThread)
1645
{
1646
J9JITBreakpointedMethod * breakpointedMethod = currentThread->javaVM->jitConfig->breakpointedMethods;
1647
1648
while (breakpointedMethod) {
1649
markMethodBreakpointed(currentThread, breakpointedMethod);
1650
breakpointedMethod = breakpointedMethod->link;
1651
}
1652
}
1653
1654
1655
void
1656
jitSingleStepAdded(J9VMThread * currentThread)
1657
{
1658
/* We have exclusive */
1659
1660
Trc_Decomp_jitSingleStepAdded_Entry(currentThread);
1661
1662
if (++(currentThread->javaVM->jitConfig->singleStepCount) == 1) {
1663
1664
/* Mark every JIT method in every stack for decompilation */
1665
1666
decompileAllMethodsInAllStacks(currentThread, JITDECOMP_SINGLE_STEP);
1667
}
1668
1669
Trc_Decomp_jitSingleStepAdded_Exit(currentThread);
1670
}
1671
1672
1673
void
1674
jitSingleStepRemoved(J9VMThread * currentThread)
1675
{
1676
/* We have exclusive */
1677
1678
Trc_Decomp_jitSingleStepRemoved_Entry(currentThread);
1679
1680
if (--(currentThread->javaVM->jitConfig->singleStepCount) == 0) {
1681
1682
/* Remove the single step decompilations */
1683
1684
deleteAllDecompilations(currentThread, JITDECOMP_SINGLE_STEP, NULL);
1685
}
1686
1687
Trc_Decomp_jitSingleStepRemoved_Exit(currentThread);
1688
}
1689
1690
1691
UDATA
1692
initializeFSD(J9JavaVM * vm)
1693
{
1694
J9JITConfig * jitConfig = vm->jitConfig;
1695
1696
jitConfig->jitCodeBreakpointAdded = jitCodeBreakpointAdded;
1697
jitConfig->jitCodeBreakpointRemoved = jitCodeBreakpointRemoved;
1698
jitConfig->jitDataBreakpointAdded = jitDataBreakpointAdded;
1699
jitConfig->jitDataBreakpointRemoved = jitDataBreakpointRemoved;
1700
jitConfig->jitSingleStepAdded = jitSingleStepAdded;
1701
jitConfig->jitSingleStepRemoved = jitSingleStepRemoved;
1702
jitConfig->jitExceptionCaught = jitExceptionCaught;
1703
jitConfig->jitCleanUpDecompilationStack = jitCleanUpDecompilationStack;
1704
#ifdef J9VM_INTERP_HOT_CODE_REPLACEMENT
1705
jitConfig->jitHotswapOccurred = jitHotswapOccurred;
1706
jitConfig->jitDecompileMethodForFramePop = jitDecompileMethodForFramePop;
1707
#endif
1708
#ifdef J9VM_OPT_JVMTI
1709
jitConfig->jitFramePopNotificationAdded = jitFramePopNotificationAdded;
1710
#endif
1711
jitConfig->jitStackLocalsModified = jitStackLocalsModified;
1712
jitConfig->jitLocalSlotAddress = jitLocalSlotAddress;
1713
jitConfig->jitAddDecompilationForFramePop = jitAddDecompilationForFramePop;
1714
1715
jitConfig->fsdEnabled = TRUE;
1716
1717
return 0;
1718
}
1719
1720
static J9OSRFrame *
1721
findOSRFrameAtInlineDepth(J9OSRBuffer *osrBuffer, UDATA inlineDepth)
1722
{
1723
J9OSRFrame *osrFrame = (J9OSRFrame*)(osrBuffer + 1);
1724
UDATA osrFrameInlineDepth = osrBuffer->numberOfFrames - 1;
1725
Assert_CodertVM_true(osrFrameInlineDepth >= inlineDepth);
1726
while (osrFrameInlineDepth != inlineDepth) {
1727
osrFrame = (J9OSRFrame*)((U_8*)osrFrame + osrFrameSize(osrFrame->method));
1728
osrFrameInlineDepth -= 1;
1729
}
1730
return osrFrame;
1731
}
1732
1733
#if (defined(J9VM_OPT_JVMTI)) /* priv. proto (autogen) */
1734
1735
static void
1736
jitFramePopNotificationAdded(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA inlineDepth)
1737
{
1738
J9JITDecompilationInfo *decompilationInfo = NULL;
1739
1740
Trc_Decomp_jitFramePopNotificationAdded_Entry(currentThread, walkState->walkThread, walkState->arg0EA, walkState->method);
1741
decompPrintMethod(currentThread, walkState->method);
1742
1743
decompilationInfo = addDecompilation(currentThread, walkState, JITDECOMP_FRAME_POP_NOTIFICATION);
1744
if (NULL != decompilationInfo) {
1745
J9OSRFrame *osrFrame = findOSRFrameAtInlineDepth(&decompilationInfo->osrBuffer, inlineDepth);
1746
osrFrame->flags |= J9OSRFRAME_NOTIFY_FRAME_POP;
1747
}
1748
1749
Trc_Decomp_jitFramePopNotificationAdded_Exit(currentThread);
1750
}
1751
#endif /* J9VM_OPT_JVMTI (autogen) */
1752
1753
static J9JITDecompilationInfo*
1754
jitAddDecompilationForFramePop(J9VMThread * currentThread, J9StackWalkState * walkState)
1755
{
1756
return addDecompilation(currentThread, walkState, JITDECOMP_POP_FRAMES);
1757
}
1758
1759
1760
void
1761
jitStackLocalsModified(J9VMThread * currentThread, J9StackWalkState * walkState)
1762
{
1763
Trc_Decomp_jitStackLocalsModified_Entry(currentThread);
1764
1765
if (walkState->jitInfo == NULL) {
1766
Trc_Decomp_jitStackLocalsModified_notJIT(currentThread);
1767
} else {
1768
addDecompilation(currentThread, walkState, JITDECOMP_STACK_LOCALS_MODIFIED);
1769
}
1770
1771
Trc_Decomp_jitStackLocalsModified_Exit(currentThread);
1772
}
1773
1774
1775
void
1776
jitBreakpointedMethodCompiled(J9VMThread * currentThread, J9Method * method, void * startAddress)
1777
{
1778
J9JITConfig * jitConfig = currentThread->javaVM->jitConfig;
1779
J9JITBreakpointedMethod * breakpointedMethod = jitConfig->breakpointedMethods;
1780
1781
Trc_Decomp_jitBreakpointedMethodCompiled_Entry(currentThread, method, startAddress);
1782
decompPrintMethod(currentThread, method);
1783
1784
while (breakpointedMethod) {
1785
if (breakpointedMethod->method == method) {
1786
/* Assert breakpointedMethod->hasBeenTranslated == FALSE */
1787
breakpointedMethod->hasBeenTranslated = TRUE;
1788
_fsdSwitchToInterpPatchEntry(startAddress);
1789
Trc_Decomp_jitBreakpointedMethodCompiled_Exit_success(currentThread, breakpointedMethod);
1790
return;
1791
}
1792
breakpointedMethod = breakpointedMethod->link;
1793
}
1794
Trc_Decomp_jitBreakpointedMethodCompiled_Exit_fail(currentThread);
1795
}
1796
1797
1798
/**
1799
* Compute the number of bytes required for a single OSR frame.
1800
*
1801
* @param[in] *method the J9Method for which to compute the OSR frame size
1802
*
1803
* @return byte size of the OSR frame
1804
*/
1805
UDATA
1806
osrFrameSize(J9Method *method)
1807
{
1808
J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);
1809
return osrFrameSizeRomMethod(romMethod);
1810
}
1811
1812
1813
/**
1814
* Compute the number of bytes required for a single OSR frame.
1815
*
1816
* @param[in] *romMethod the J9ROMMethod for which to compute the OSR frame size
1817
*
1818
* @return byte size of the OSR frame
1819
*/
1820
UDATA
1821
osrFrameSizeRomMethod(J9ROMMethod *romMethod)
1822
{
1823
U_32 numberOfLocals = J9_ARG_COUNT_FROM_ROM_METHOD(romMethod) + J9_TEMP_COUNT_FROM_ROM_METHOD(romMethod);
1824
U_32 maxStack = J9_MAX_STACK_FROM_ROM_METHOD(romMethod);
1825
1826
/* Adjust the number of locals to account for any hidden slots */
1827
if ((romMethod->modifiers & J9AccSynchronized) || (J9ROMMETHOD_IS_NON_EMPTY_OBJECT_CONSTRUCTOR(romMethod))) {
1828
numberOfLocals += 1;
1829
}
1830
1831
/* Account for the fixed size structure and each UDATA slot required */
1832
1833
return sizeof(J9OSRFrame) + (sizeof(UDATA) * (maxStack + numberOfLocals));
1834
}
1835
1836
1837
/**
1838
* Compute the number of bytes required for all OSR frames in the buffer
1839
* representing the stack information at the current method in the walk state.
1840
*
1841
* @param[in] *currentThread the current J9VMThread
1842
* @param[in] *metaData the JIT metadata for the compilation
1843
* @param[in] *jitPC the compiled PC at which to decompile
1844
* @param[in] resolveFrameFlags the flags from the previous resolve frame (0 if no resolve frame)
1845
*
1846
* @return byte size of the OSR frames
1847
*/
1848
static UDATA
1849
osrAllFramesSize(J9VMThread *currentThread, J9JITExceptionTable *metaData, void *jitPC, UDATA resolveFrameFlags)
1850
{
1851
UDATA totalSize = 0;
1852
void * stackMap = NULL;
1853
void * inlineMap = NULL;
1854
1855
/* Count the inlined methods */
1856
jitGetMapsFromPC(currentThread, currentThread->javaVM, metaData, (UDATA)jitPC, &stackMap, &inlineMap);
1857
Assert_CodertVM_false(NULL == inlineMap);
1858
if (NULL != getJitInlinedCallInfo(metaData)) {
1859
void *inlinedCallSite = getFirstInlinedCallSite(metaData, inlineMap);
1860
if (inlinedCallSite != NULL) {
1861
UDATA inlineDepth = getJitInlineDepthFromCallSite(metaData, inlinedCallSite);
1862
do {
1863
J9Method * inlinedMethod = (J9Method *)getInlinedMethod(inlinedCallSite);
1864
totalSize += osrFrameSize(inlinedMethod);
1865
inlinedCallSite = getNextInlinedCallSite(metaData, inlinedCallSite);
1866
inlineDepth -= 1;
1867
} while (0 != inlineDepth);
1868
}
1869
}
1870
1871
/* Count the outer method */
1872
totalSize += osrFrameSize(metaData->ramMethod);
1873
1874
return totalSize;
1875
}
1876
1877
1878
/**
1879
* Perform an OSR (fill in the OSR buffer) for the frame represented in the stack walk state.
1880
*
1881
* Note that the JITted stack frame will be copied to (osrScratchBuffer + osrScratchBufferSize).
1882
* This function assumes that the buffer has been allocated large enough.
1883
*
1884
* @param[in] *currentThread current thread
1885
* @param[in] *walkState stack walk state (already at the OSR point)
1886
* @param[in] *osrBuffer pointer to correctly-allocated OSR buffer
1887
* @param[in] *osrScratchBuffer pointer to scratch buffer
1888
* @param[in] osrScratchBufferSize size of the scratch buffer
1889
* @param[in] jitStackFrameSize the number of bytes in the JITted stack frame
1890
* @param[out] mustDecompile if non-NULL, set to TRUE or FALSE to indicate if the OSR has performed a destructive action
1891
*
1892
* @return an OSR result code
1893
*/
1894
static UDATA
1895
performOSR(J9VMThread *currentThread, J9StackWalkState *walkState, J9OSRBuffer *osrBuffer, U_8 *osrScratchBuffer, UDATA scratchBufferSize, UDATA jitStackFrameSize, UDATA *mustDecompile)
1896
{
1897
J9JavaVM *vm = currentThread->javaVM;
1898
PORT_ACCESS_FROM_JAVAVM(vm);
1899
J9VMThread *targetThread = walkState->walkThread;
1900
J9JITExceptionTable *metaData = walkState->jitInfo;
1901
void *pc = walkState->pc;
1902
void *osrBlock = NULL;
1903
UDATA result = OSR_OK;
1904
UDATA forceDecompile = FALSE;
1905
UDATA *osrJittedFrameCopy = (UDATA*)(osrScratchBuffer + scratchBufferSize);
1906
1907
/* Assert that this frame has been compiled using OSR */
1908
Assert_CodertVM_true(usesOSR(currentThread, metaData));
1909
1910
/* Assert that the live registers have been tracked */
1911
Assert_CodertVM_true(walkState->flags & J9_STACKWALK_MAINTAIN_REGISTER_MAP);
1912
1913
/* Copy the stack frame after the scratch buffer (assume it's been allocated correctly).
1914
* Assert the number of bytes provided matches the expected frame size from the metadata
1915
* (arguments + return address + totalFrameSize slots).
1916
*/
1917
Assert_CodertVM_true(jitStackFrameSize == ((J9_ARG_COUNT_FROM_ROM_METHOD(J9_ROM_METHOD_FROM_RAM_METHOD(metaData->ramMethod)) + 1 + metaData->totalFrameSize) * sizeof(UDATA)));
1918
memcpy(osrJittedFrameCopy, walkState->unwindSP, jitStackFrameSize);
1919
1920
/* Perform the OSR */
1921
osrBlock = preOSR(currentThread, metaData, pc);
1922
/* Ensure the OSR block is within either the warm or cold region of the compilation */
1923
Assert_CodertVM_true(
1924
(((UDATA)osrBlock > metaData->startPC) && ((UDATA)osrBlock < metaData->endWarmPC)) ||
1925
((0 != metaData->startColdPC) && (((UDATA)osrBlock >= metaData->startColdPC) && ((UDATA)osrBlock < metaData->endPC)))
1926
);
1927
currentThread->osrBuffer = osrBuffer;
1928
currentThread->osrScratchBuffer = osrScratchBuffer;
1929
currentThread->osrJittedFrameCopy = osrJittedFrameCopy;
1930
currentThread->osrFrameIndex = sizeof(J9OSRBuffer);
1931
currentThread->privateFlags |= J9_PRIVATE_FLAGS_OSR_IN_PROGRESS;
1932
currentThread->javaVM->internalVMFunctions->jitFillOSRBuffer(currentThread, osrBlock);
1933
currentThread->privateFlags &= ~J9_PRIVATE_FLAGS_OSR_IN_PROGRESS;
1934
currentThread->osrBuffer = NULL;
1935
currentThread->osrJittedFrameCopy = NULL;
1936
if (0 != postOSR(currentThread, metaData, pc)) {
1937
forceDecompile = TRUE;
1938
}
1939
1940
if (NULL != mustDecompile) {
1941
*mustDecompile = forceDecompile;
1942
}
1943
return result;
1944
}
1945
1946
1947
/**
1948
* Find the address of a local variable slot for a compiled method. Requires that the target frame
1949
* be compiled with either FSD or OSR (or both).
1950
*
1951
* @param[in] *currentThread current thread
1952
* @param[in] *walkState stack walk state (already at the OSR point)
1953
* @param[in] slot the slot number to query
1954
* @param[in] inlineDepth the inline depth of the frame being queried
1955
*
1956
* @return the address of the local slot, NULL if a native out of memory occurs
1957
*/
1958
static UDATA *
1959
jitLocalSlotAddress(J9VMThread * currentThread, J9StackWalkState *walkState, UDATA slot, UDATA inlineDepth)
1960
{
1961
J9JITExceptionTable *metaData = walkState->jitInfo;
1962
UDATA *slotAddress = NULL;
1963
1964
/* If this frame has been OSR-compiled, add a decompilation record (to perform the OSR) and return a pointer
1965
* into the appropriate frame in the buffer.
1966
*/
1967
if (usesOSR(currentThread, metaData)) {
1968
J9JITDecompilationInfo *decompilationInfo = addDecompilation(currentThread, walkState, 0);
1969
1970
if (NULL != decompilationInfo) {
1971
J9OSRBuffer *osrBuffer = &decompilationInfo->osrBuffer;
1972
J9OSRFrame *osrFrame = (J9OSRFrame*)(osrBuffer + 1);
1973
UDATA osrFrameInlineDepth = osrBuffer->numberOfFrames - 1;
1974
while (osrFrameInlineDepth != inlineDepth) {
1975
osrFrame = (J9OSRFrame*)((U_8*)osrFrame + osrFrameSize(osrFrame->method));
1976
osrFrameInlineDepth -= 1;
1977
}
1978
slotAddress = ((UDATA*)(osrFrame + 1)) + osrFrame->maxStack + osrFrame->numberOfLocals - 1 - slot;
1979
}
1980
} else {
1981
J9ROMMethod * romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(walkState->method);
1982
1983
/* OSR not in use in this frame - look up the stack slot using the FSD metadata */
1984
1985
Assert_CodertVM_true(0 == inlineDepth);
1986
if (slot >= romMethod->argCount) {
1987
J9JITStackAtlas * stackAtlas = (J9JITStackAtlas *) (metaData->gcStackAtlas);
1988
1989
slotAddress = (UDATA *) (((UDATA) walkState->bp) + stackAtlas->localBaseOffset);
1990
if (romMethod->modifiers & J9AccSynchronized) {
1991
/* Synchronized methods have one hidden temp to hold the sync object */
1992
++slotAddress;
1993
} else if (J9ROMMETHOD_IS_NON_EMPTY_OBJECT_CONSTRUCTOR(romMethod)) {
1994
/* Non-empty java.lang.Object.<init> has one hidden temp to hold a copy of the receiver */
1995
++slotAddress;
1996
}
1997
slotAddress += metaData->tempOffset; /* skip pending push area */
1998
slotAddress += ((romMethod->tempCount - 1) - (slot - romMethod->argCount));
1999
} else {
2000
slotAddress = walkState->arg0EA - slot;
2001
}
2002
}
2003
2004
return slotAddress;
2005
}
2006
2007
2008
/**
2009
* Compute the required size of the OSR scratch buffer.
2010
*
2011
* @param[in] *currentThread current thread
2012
* @param[in] *metadata JIT metadata for this compilation
2013
* @param[in] *jitPC compiled PC at which to OSR
2014
*
2015
* @return the scratch buffer size
2016
*/
2017
static UDATA
2018
roundedOSRScratchBufferSize(J9VMThread * currentThread, J9JITExceptionTable *metaData, void *jitPC)
2019
{
2020
J9JavaVM *vm = currentThread->javaVM;
2021
UDATA scratchBufferSize = osrScratchBufferSize(currentThread, metaData, jitPC);
2022
2023
/* Ensure a minimum size for the scratch buffer to allow for possible calls while the stack is active
2024
* (in particular, Linux on x86 performs a call in order to compute the GOT). Currently, the minimum
2025
* size is 8 UDATAs. Round the size of the scratch buffer up to UDATA.
2026
*/
2027
scratchBufferSize = OMR_MAX(scratchBufferSize, (8 * sizeof(UDATA)));
2028
scratchBufferSize = ROUND_TO(sizeof(UDATA), scratchBufferSize);
2029
return scratchBufferSize;
2030
}
2031
2032
2033
/**
2034
* Determine the address of an numbered object slot in a compiled stack frame.
2035
*
2036
* @param[in] *osrData the OSR data block
2037
* @param[in] slot the slot index, numbered from 0
2038
*
2039
* @return the address of the object slot in the compiled stack frame
2040
*/
2041
static j9object_t*
2042
getObjectSlotAddress(J9OSRData *osrData, U_16 slot)
2043
{
2044
UDATA *slotAddress = NULL;
2045
U_16 numParms = getJitNumberOfParmSlots(osrData->gcStackAtlas);
2046
2047
/* The base address depends on the range of the slot index */
2048
if (slot < numParms) {
2049
slotAddress = osrData->objectArgScanCursor;
2050
} else {
2051
slotAddress = osrData->objectTempScanCursor;
2052
slot -= numParms;
2053
}
2054
slotAddress += slot;
2055
return (j9object_t*)slotAddress;
2056
}
2057
2058
2059
/**
2060
* Create a monitor enter record for each object locked in the OSR frame. The records are linked
2061
* together and stored in the J9OSRFrame.
2062
*
2063
* @param[in] *currentThread current thread
2064
* @param[in] *osrData the OSR data block
2065
*
2066
* @return an OSR result code
2067
*/
2068
static UDATA
2069
createMonitorEnterRecords(J9VMThread *currentThread, J9OSRData *osrData)
2070
{
2071
UDATA result = OSR_OK;
2072
J9Pool *monitorEnterRecordPool = osrData->targetThread->monitorEnterRecordPool;
2073
if (NULL != monitorEnterRecordPool) {
2074
J9JITStackAtlas *gcStackAtlas = osrData->gcStackAtlas;
2075
void *inlinedCallSite = osrData->inlinedCallSite;
2076
U_8 *monitorMask = getMonitorMask(gcStackAtlas, inlinedCallSite);
2077
if (NULL != monitorMask) {
2078
J9MonitorEnterRecord listHead;
2079
J9MonitorEnterRecord *lastEnterRecord = &listHead;
2080
U_8 *liveMonitorMap = osrData->liveMonitorMap;
2081
U_16 numberOfMapBits = osrData->numberOfMapBits;
2082
U_16 i = 0;
2083
listHead.next = NULL;
2084
for (i = 0; i < numberOfMapBits; ++i) {
2085
U_8 bit = liveMonitorMap[i >> 3] & monitorMask[i >> 3] & (1 << (i & 7));
2086
if (0 != bit) {
2087
J9MonitorEnterRecord *newEnterRecord = NULL;
2088
j9object_t object = *getObjectSlotAddress(osrData, i);
2089
/* Assert that the mapped object is not stack-allocated */
2090
Assert_CodertVM_false(NULL == object);
2091
newEnterRecord = (J9MonitorEnterRecord*)pool_newElement(monitorEnterRecordPool);
2092
if (NULL == newEnterRecord) {
2093
/* Discard any records created up to this point */
2094
J9MonitorEnterRecord *freeRecord = listHead.next;
2095
while (NULL != freeRecord) {
2096
J9MonitorEnterRecord *nextRecord = freeRecord->next;
2097
pool_removeElement(monitorEnterRecordPool, freeRecord);
2098
freeRecord = nextRecord;
2099
}
2100
result = OSR_OUT_OF_MEMORY;
2101
break;
2102
}
2103
lastEnterRecord->next = newEnterRecord;
2104
lastEnterRecord = newEnterRecord;
2105
newEnterRecord->object = object;
2106
newEnterRecord->dropEnterCount = 1;
2107
newEnterRecord->arg0EA = NULL;
2108
newEnterRecord->next = NULL;
2109
}
2110
}
2111
osrData->osrFrame->monitorEnterRecords = listHead.next;
2112
}
2113
}
2114
return result;
2115
}
2116
2117
2118
/**
2119
* Initialize an OSR frame.
2120
*
2121
* @param[in] *currentThread the current J9VMThread
2122
* @param[in] *osrData the OSR data block
2123
*
2124
* @return an OSR result code
2125
*/
2126
static UDATA
2127
initializeOSRFrame(J9VMThread *currentThread, J9OSRData *osrData)
2128
{
2129
UDATA result = OSR_OK;
2130
J9OSRFrame *osrFrame = osrData->osrFrame;
2131
J9JITExceptionTable *metaData = osrData->metaData;
2132
void *inlineMap = osrData->inlineMap;
2133
void *inlinedCallSite = osrData->inlinedCallSite;
2134
J9Method *method = osrData->method;
2135
UDATA resolveFrameFlags = osrData->resolveFrameFlags;
2136
UDATA bytecodePCOffset = getCurrentByteCodeIndexAndIsSameReceiver(metaData, inlineMap, inlinedCallSite, NULL);
2137
U_8 *bytecodePC = J9_BYTECODE_START_FROM_RAM_METHOD(method) + bytecodePCOffset;
2138
UDATA pendingStackHeight = getPendingStackHeight(currentThread, bytecodePC, method, resolveFrameFlags);
2139
J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);
2140
U_8 argCount = J9_ARG_COUNT_FROM_ROM_METHOD(romMethod);
2141
U_32 numberOfLocals = argCount + J9_TEMP_COUNT_FROM_ROM_METHOD(romMethod);
2142
U_32 maxStack = J9_MAX_STACK_FROM_ROM_METHOD(romMethod);
2143
2144
Trc_Decomp_jitInterpreterPCFromWalkState_Entry(osrData->jitPC);
2145
Trc_Decomp_jitInterpreterPCFromWalkState_stackMap(bytecodePC);
2146
2147
/* Create monitor enter records */
2148
if (NULL != osrData->liveMonitorMap) {
2149
result = createMonitorEnterRecords(currentThread, osrData);
2150
if (OSR_OK != result) {
2151
goto done;
2152
}
2153
}
2154
/* Adjust the number of locals to account for any hidden slots */
2155
if ((romMethod->modifiers & J9AccSynchronized) || (J9ROMMETHOD_IS_NON_EMPTY_OBJECT_CONSTRUCTOR(romMethod))) {
2156
numberOfLocals += 1;
2157
}
2158
osrFrame->method = method;
2159
osrFrame->bytecodePCOffset = bytecodePC - J9_BYTECODE_START_FROM_RAM_METHOD(method);
2160
osrFrame->numberOfLocals = numberOfLocals;
2161
osrFrame->maxStack = maxStack;
2162
osrFrame->pendingStackHeight = pendingStackHeight;
2163
/* Move to the next frame */
2164
osrData->osrFrame = (J9OSRFrame*)(((UDATA*)(osrFrame + 1)) + maxStack + numberOfLocals);
2165
done:
2166
return result;
2167
}
2168
2169
2170
/**
2171
* Initialize the OSR buffer and frames.
2172
*
2173
* @param[in] *currentThread current thread
2174
* @param[in] *osrBuffer OSR buffer
2175
* @param[in] *osrData the OSR data block
2176
*/
2177
static UDATA
2178
initializeOSRBuffer(J9VMThread *currentThread, J9OSRBuffer *osrBuffer, J9OSRData *osrData)
2179
{
2180
UDATA result = OSR_OK;
2181
J9JITExceptionTable *metaData = osrData->metaData;
2182
void *jitPC = osrData->jitPC;
2183
UDATA resolveFrameFlags = osrData->resolveFrameFlags;
2184
UDATA numberOfFrames = 1; /* count the outer method now */
2185
J9Method *outerMethod = metaData->ramMethod;
2186
void *stackMap = NULL;
2187
void *inlineMap = NULL;
2188
J9JITStackAtlas *gcStackAtlas = NULL;
2189
U_8 *liveMonitorMap = NULL;
2190
U_16 numberOfMapBits = 0;
2191
2192
/* Get the stack map, inline map and live monitor metadata */
2193
jitGetMapsFromPC(currentThread, currentThread->javaVM, metaData, (UDATA)jitPC, &stackMap, &inlineMap);
2194
liveMonitorMap = getJitLiveMonitors(metaData, stackMap);
2195
gcStackAtlas = (J9JITStackAtlas *)getJitGCStackAtlas(metaData);
2196
numberOfMapBits = getJitNumberOfMapBytes(gcStackAtlas) << 3;
2197
osrData->gcStackAtlas = gcStackAtlas;
2198
osrData->liveMonitorMap = liveMonitorMap;
2199
osrData->numberOfMapBits = numberOfMapBits;
2200
osrData->inlineMap = inlineMap;
2201
osrData->osrFrame = (J9OSRFrame*)(osrBuffer + 1);
2202
2203
/* Fill in the data for the inlined methods */
2204
Assert_CodertVM_false(NULL == inlineMap);
2205
if (NULL != getJitInlinedCallInfo(metaData)) {
2206
void *inlinedCallSite = getFirstInlinedCallSite(metaData, inlineMap);
2207
if (inlinedCallSite != NULL) {
2208
UDATA inlineDepth = getJitInlineDepthFromCallSite(metaData, inlinedCallSite);
2209
numberOfFrames += inlineDepth;
2210
do {
2211
J9Method *inlinedMethod = (J9Method *)getInlinedMethod(inlinedCallSite);
2212
osrData->inlinedCallSite = inlinedCallSite;
2213
osrData->method = inlinedMethod;
2214
result = initializeOSRFrame(currentThread, osrData);
2215
if (OSR_OK != result) {
2216
goto done;
2217
}
2218
osrData->resolveFrameFlags = 0;
2219
inlinedCallSite = getNextInlinedCallSite(metaData, inlinedCallSite);
2220
inlineDepth -= 1;
2221
} while (0 != inlineDepth);
2222
Assert_CodertVM_true(NULL == inlinedCallSite);
2223
}
2224
}
2225
2226
/* Fill in the frame for the outer method */
2227
osrData->inlinedCallSite = NULL;
2228
osrData->method = outerMethod;
2229
result = initializeOSRFrame(currentThread, osrData);
2230
if (OSR_OK != result) {
2231
goto done;
2232
}
2233
2234
/* Fill in the OSR buffer header */
2235
osrBuffer->numberOfFrames = numberOfFrames;
2236
osrBuffer->jitPC = jitPC;
2237
done:
2238
return result;
2239
}
2240
2241
2242
/**
2243
* Induce OSR on the current thread.
2244
*
2245
* @param[in] *currentThread current thread
2246
* @param[in] *jitPC compiled PC at which to OSR
2247
*/
2248
void
2249
induceOSROnCurrentThread(J9VMThread * currentThread)
2250
{
2251
J9JavaVM * vm = currentThread->javaVM;
2252
PORT_ACCESS_FROM_JAVAVM(vm);
2253
J9JITExceptionTable *metaData = NULL;
2254
void *jitPC = NULL;
2255
UDATA decompRecordSize = 0;
2256
UDATA scratchBufferSize = 0;
2257
UDATA jitStackFrameSize = 0;
2258
UDATA totalSize = 0;
2259
J9JITDecompilationInfo *decompilationRecord = NULL;
2260
UDATA reason = JITDECOMP_ON_STACK_REPLACEMENT;
2261
void *osrBlock = NULL;
2262
U_8 *osrScratchBuffer = NULL;
2263
UDATA osrReturnCode = OSR_OK;
2264
J9StackWalkState walkState;
2265
J9OSRData osrData;
2266
2267
dumpStack(currentThread, "induceOSROnCurrentThread");
2268
2269
/* The stack currently has a resolve frame on top, followed by the JIT frame we
2270
* wish to OSR. Walk the stack down to the JIT frame to gather the data required
2271
* for decompilation.
2272
*/
2273
walkState.walkThread = currentThread;
2274
walkState.maxFrames = 2;
2275
walkState.flags = J9_STACKWALK_SKIP_INLINES | J9_STACKWALK_MAINTAIN_REGISTER_MAP | J9_STACKWALK_COUNT_SPECIFIED;
2276
currentThread->javaVM->walkStackFrames(currentThread, &walkState);
2277
jitPC = walkState.pc;
2278
metaData = walkState.jitInfo;
2279
Assert_CodertVM_true(NULL != metaData);
2280
Assert_CodertVM_true(usesOSR(currentThread, metaData));
2281
2282
/* Determine the required sizes of:
2283
* a) a decompilation record (fixed size - a J9JITDecompilationInfo)
2284
* b) the OSR frames
2285
* c) the OSR scratch buffer
2286
* d) the copy of the stack frame being OSRed
2287
*/
2288
decompRecordSize = osrAllFramesSize(currentThread, metaData, jitPC, walkState.resolveFrameFlags);
2289
decompRecordSize += sizeof(J9JITDecompilationInfo);
2290
scratchBufferSize = roundedOSRScratchBufferSize(currentThread, metaData, jitPC);
2291
jitStackFrameSize = (UDATA)(walkState.arg0EA + 1) - (UDATA)walkState.unwindSP;
2292
totalSize = decompRecordSize + scratchBufferSize + jitStackFrameSize;
2293
Assert_CodertVM_true(totalSize <= vm->osrGlobalBufferSize);
2294
2295
/* Allocate the buffer, falling back to the global one if the allocation fails */
2296
decompilationRecord = (J9JITDecompilationInfo*)j9mem_allocate_memory(totalSize, OMRMEM_CATEGORY_JIT);
2297
if (NULL == decompilationRecord) {
2298
/* Trc_Decomp_induceOSROnCurrentThread_usingGlobalBuffer(currentThread); */
2299
omrthread_monitor_enter(vm->osrGlobalBufferLock);
2300
decompilationRecord = (J9JITDecompilationInfo*)vm->osrGlobalBuffer;
2301
reason |= JITDECOMP_OSR_GLOBAL_BUFFER_USED;
2302
}
2303
memset(decompilationRecord, 0, totalSize);
2304
decompilationRecord->usesOSR = TRUE;
2305
/* Trc_Decomp_addDecompilation_allocRecord(currentThread, info); */
2306
2307
/* Fill in the interpreter values in the OSR buffer */
2308
osrData.targetThread = currentThread;
2309
osrData.metaData = metaData;
2310
osrData.jitPC = jitPC;
2311
osrData.resolveFrameFlags = walkState.resolveFrameFlags;
2312
osrData.objectArgScanCursor = getObjectArgScanCursor(&walkState);
2313
osrData.objectTempScanCursor = getObjectTempScanCursor(&walkState);
2314
if (OSR_OK != initializeOSRBuffer(currentThread, &decompilationRecord->osrBuffer, &osrData)) {
2315
Trc_Decomp_addDecompilation_allocFailed(currentThread);
2316
goto outOfMemory;
2317
}
2318
2319
/* Perform the OSR to fill in the buffer. On success, add the new decompilation to the stack.
2320
* If the OSR fails, discard the decompilation - this will result in OutOfMemoryError being thrown.
2321
*/
2322
osrScratchBuffer = ((U_8*)decompilationRecord) + decompRecordSize;
2323
osrReturnCode = performOSR(currentThread, &walkState, &decompilationRecord->osrBuffer, osrScratchBuffer, scratchBufferSize, jitStackFrameSize, NULL);
2324
if (OSR_OK != osrReturnCode) {
2325
outOfMemory:
2326
decompilationRecord->reason = reason;
2327
freeDecompilationRecord(currentThread, decompilationRecord, FALSE);
2328
} else {
2329
fixStackForNewDecompilation(currentThread, &walkState, decompilationRecord, reason, &currentThread->decompilationStack);
2330
}
2331
}
2332
2333
/**
2334
* Ensure that the global OSR buffer is large enough for the given
2335
* input sizes. If the buffer is too small, an attempt will be made
2336
* to grow it to the new size.
2337
*
2338
* @param[in] *vm the J9JavaVM
2339
* @param[in] osrFramesByteSize the size in bytes of the OSR frame data
2340
* @param[in] osrScratchBufferByteSize the size in bytes of the scratch buffer
2341
* @param[in] osrStackFrameByteSize the size in bytes of the JIT stack frame
2342
*
2343
* @return TRUE if the buffer is large enough, FALSE if it is not (and could not be grown)
2344
*/
2345
UDATA
2346
ensureOSRBufferSize(J9JavaVM *vm, UDATA osrFramesByteSize, UDATA osrScratchBufferByteSize, UDATA osrStackFrameByteSize)
2347
{
2348
UDATA result = TRUE;
2349
UDATA osrGlobalBufferSize = sizeof(J9JITDecompilationInfo);
2350
osrGlobalBufferSize += ROUND_TO(sizeof(UDATA), osrFramesByteSize);
2351
osrGlobalBufferSize += ROUND_TO(sizeof(UDATA), osrScratchBufferByteSize);
2352
osrGlobalBufferSize += ROUND_TO(sizeof(UDATA), osrStackFrameByteSize);
2353
if (osrGlobalBufferSize > vm->osrGlobalBufferSize) {
2354
omrthread_monitor_enter(vm->osrGlobalBufferLock);
2355
if (osrGlobalBufferSize > vm->osrGlobalBufferSize) {
2356
PORT_ACCESS_FROM_JAVAVM(vm);
2357
void *newBuffer = j9mem_reallocate_memory(vm->osrGlobalBuffer, osrGlobalBufferSize, OMRMEM_CATEGORY_JIT);
2358
if (NULL == newBuffer) {
2359
result = FALSE;
2360
} else {
2361
vm->osrGlobalBufferSize = osrGlobalBufferSize;
2362
vm->osrGlobalBuffer = newBuffer;
2363
}
2364
}
2365
omrthread_monitor_exit(vm->osrGlobalBufferLock);
2366
}
2367
return result;
2368
}
2369
2370
/* Resolve frame is already built */
2371
void
2372
c_jitDecompileAfterAllocation(J9VMThread *currentThread)
2373
{
2374
/* Allocated object stored in floatTemp1 */
2375
j9object_t const obj = (j9object_t)currentThread->floatTemp1;
2376
/* Fetch and unstack the decompilation information for this frame */
2377
2378
Trc_Decomp_DecompileAfterAllocation_Entry(currentThread, obj, currentThread->pc);
2379
2380
J9JITDecompilationInfo *decompRecord = fetchAndUnstackDecompilationInfo(currentThread);
2381
/* Fix the saved PC since the frame is still on the stack */
2382
fixSavedPC(currentThread, decompRecord);
2383
/* Decompile the method */
2384
jitDecompileMethod(currentThread, decompRecord);
2385
/* Push the newly-allocated object and advance the PC beyond the allocation bytecode */
2386
UDATA *sp = currentThread->sp - 1;
2387
*(j9object_t*)sp = obj;
2388
currentThread->sp = sp;
2389
currentThread->pc += (J9JavaInstructionSizeAndBranchActionTable[*currentThread->pc] & 0x7);
2390
dumpStack(currentThread, "after jitDecompileAfterAllocation");
2391
currentThread->tempSlot = (UDATA)J9_BUILDER_SYMBOL(executeCurrentBytecodeFromJIT);
2392
2393
Trc_Decomp_DecompileAfterAllocation_Exit(currentThread, currentThread->sp, currentThread->pc);
2394
}
2395
2396
/* Resolve frame is already built */
2397
void
2398
c_jitDecompileAtCurrentPC(J9VMThread *currentThread)
2399
{
2400
Trc_Decomp_DecompileAtCurrentPC_Entry(currentThread);
2401
2402
/* Fetch and unstack the decompilation information for this frame */
2403
J9JITDecompilationInfo *decompRecord = fetchAndUnstackDecompilationInfo(currentThread);
2404
/* Fix the saved PC since the frame is still on the stack */
2405
fixSavedPC(currentThread, decompRecord);
2406
/* Decompile the method */
2407
jitDecompileMethod(currentThread, decompRecord);
2408
dumpStack(currentThread, "after jitDecompileAtCurrentPC");
2409
currentThread->tempSlot = (UDATA)J9_BUILDER_SYMBOL(executeCurrentBytecodeFromJIT);
2410
2411
Trc_Decomp_DecompileAtCurrentPC_Exit(currentThread);
2412
}
2413
2414
/* Resolve frame is already built */
2415
void
2416
c_jitDecompileBeforeMethodMonitorEnter(J9VMThread *currentThread)
2417
{
2418
Trc_Decomp_DecompileBeforeMethodMonitorEnter_Entry(currentThread);
2419
2420
/* Fetch and unstack the decompilation information for this frame */
2421
J9JITDecompilationInfo *decompRecord = fetchAndUnstackDecompilationInfo(currentThread);
2422
J9Method * const method = decompRecord->method;
2423
/* Fix the saved PC since the frame is still on the stack */
2424
fixSavedPC(currentThread, decompRecord);
2425
/* Decompile the method */
2426
jitDecompileMethod(currentThread, decompRecord);
2427
dumpStack(currentThread, "after jitDecompileBeforeMethodMonitorEnter");
2428
currentThread->floatTemp1 = (void*)method;
2429
currentThread->tempSlot = (UDATA)J9_BUILDER_SYMBOL(enterMethodMonitorFromJIT);
2430
2431
Trc_Decomp_DecompileBeforeMethodMonitorEnter_Exit(currentThread);
2432
}
2433
2434
/* Resolve frame is already built */
2435
void
2436
c_jitDecompileBeforeReportMethodEnter(J9VMThread *currentThread)
2437
{
2438
Trc_Decomp_DecompileBeforeReportMethodEnter_Entry(currentThread);
2439
2440
/* Fetch and unstack the decompilation information for this frame */
2441
J9JITDecompilationInfo *decompRecord = fetchAndUnstackDecompilationInfo(currentThread);
2442
J9Method * const method = decompRecord->method;
2443
/* Fix the saved PC since the frame is still on the stack */
2444
fixSavedPC(currentThread, decompRecord);
2445
/* Decompile the method */
2446
jitDecompileMethod(currentThread, decompRecord);
2447
dumpStack(currentThread, "after jitDecompileBeforeReportMethodEnter");
2448
currentThread->floatTemp1 = (void*)method;
2449
currentThread->tempSlot = (UDATA)J9_BUILDER_SYMBOL(reportMethodEnterFromJIT);
2450
2451
Trc_Decomp_DecompileBeforeReportMethodEnter_Exit(currentThread, method);
2452
}
2453
2454
/* Resolve frame is already built */
2455
void
2456
c_jitDecompileAfterMonitorEnter(J9VMThread *currentThread)
2457
{
2458
Trc_Decomp_DecompileAfterMonitorEnter_Entry(currentThread, currentThread->pc);
2459
2460
/* Fetch and unstack the decompilation information for this frame */
2461
J9JITDecompilationInfo *decompRecord = fetchAndUnstackDecompilationInfo(currentThread);
2462
/* Fix the saved PC since the frame is still on the stack */
2463
fixSavedPC(currentThread, decompRecord);
2464
/* Decompile the method */
2465
jitDecompileMethod(currentThread, decompRecord);
2466
/* See if this was actually the monitor enter for an inlined synchronized method. If the current
2467
* bytecode is not JBmonitorenter, we are at the start of a method (JBmonitorenter can not appear
2468
* at bytecode 0 in any verified method).
2469
*/
2470
if (JBmonitorenter != *currentThread->pc) {
2471
dumpStack(currentThread, "after jitDecompileAfterMonitorEnter - inlined sync method");
2472
currentThread->floatTemp1 = (void*)currentThread->literals;
2473
currentThread->tempSlot = (UDATA)J9_BUILDER_SYMBOL(reportMethodEnterFromJIT);
2474
} else {
2475
/* Advance the PC past the monitorenter and resume execution */
2476
currentThread->pc += 1;
2477
dumpStack(currentThread, "after jitDecompileAfterMonitorEnter - JBmonitorenter");
2478
currentThread->tempSlot = (UDATA)J9_BUILDER_SYMBOL(executeCurrentBytecodeFromJIT);
2479
}
2480
2481
Trc_Decomp_DecompileAfterMonitorEnter_Exit(currentThread, currentThread->pc, currentThread->literals);
2482
}
2483
2484
void
2485
c_jitDecompileOnReturn(J9VMThread *currentThread)
2486
{
2487
Trc_Decomp_DecompileOnReturn_Entry(currentThread, currentThread->pc, currentThread->sp);
2488
2489
UDATA const slots = currentThread->tempSlot;
2490
/* Fetch and unstack the decompilation information for this frame */
2491
J9JITDecompilationInfo *decompRecord = fetchAndUnstackDecompilationInfo(currentThread);
2492
/* Simulate a call to a resolve helper to make the stack walkable */
2493
buildBranchJITResolveFrame(currentThread, decompRecord->pc, 0);
2494
/* Decompile the method */
2495
jitDecompileMethod(currentThread, decompRecord);
2496
/* Copy return value to stack */
2497
currentThread->sp -= slots;
2498
memmove(currentThread->sp, &currentThread->returnValue, slots * sizeof(UDATA));
2499
/* Advance the PC past the invoke and resume execution */
2500
currentThread->pc += 3;
2501
dumpStack(currentThread, "after jitDecompileOnReturn");
2502
currentThread->tempSlot = (UDATA)J9_BUILDER_SYMBOL(executeCurrentBytecodeFromJIT);
2503
2504
Trc_Decomp_DecompileOnReturn_Exit(currentThread, currentThread->pc, currentThread->sp, currentThread->returnValue);
2505
}
2506
2507
void
2508
c_jitReportExceptionCatch(J9VMThread *currentThread)
2509
{
2510
void *jitPC = currentThread->floatTemp4;
2511
J9JavaVM * const vm = currentThread->javaVM;
2512
/* Simulate a call to a resolve helper to make the stack walkable */
2513
buildBranchJITResolveFrame(currentThread, jitPC, J9_STACK_FLAGS_JIT_EXCEPTION_CATCH_RESOLVE);
2514
/* If there was a decompilation record for the frame which is catching the exception, the PC will be
2515
* pointing to jitDecompileAtExceptionCatch. In this case, update the decompilation record so that the
2516
* pcAddress points to the PC save location in the newly-pushed resolve frame.
2517
*/
2518
if (J9_BUILDER_SYMBOL(jitDecompileAtExceptionCatch) == jitPC) {
2519
currentThread->decompilationStack->pcAddress = (U_8**)&(((J9SFJITResolveFrame*)currentThread->sp)->returnAddress);
2520
}
2521
/* Report the event */
2522
if (J9_EVENT_IS_HOOKED(vm->hookInterface, J9HOOK_VM_EXCEPTION_CATCH)) {
2523
j9object_t exception = ((J9SFJITResolveFrame*)currentThread->sp)->savedJITException;
2524
ALWAYS_TRIGGER_J9HOOK_VM_EXCEPTION_CATCH(vm->hookInterface, currentThread, exception, NULL);
2525
if (VM_VMHelpers::immediateAsyncPending(currentThread)) {
2526
if (J9_CHECK_ASYNC_POP_FRAMES == vm->internalVMFunctions->javaCheckAsyncMessages(currentThread, FALSE)) {
2527
jitPC = J9_BUILDER_SYMBOL(handlePopFramesFromJIT);
2528
goto done;
2529
}
2530
}
2531
/* Do not cache the resolve frame pointer as the hook call may modify the SP value */
2532
jitPC = ((J9SFJITResolveFrame*)currentThread->sp)->returnAddress;
2533
}
2534
/* Continue running */
2535
restoreBranchJITResolveFrame(currentThread);
2536
done:
2537
currentThread->tempSlot = (UDATA)jitPC;
2538
}
2539
2540
UDATA
2541
jitIsMethodBreakpointed(J9VMThread *currentThread, J9Method *method)
2542
{
2543
return J9_ARE_ANY_BITS_SET((UDATA)method->constantPool, J9_STARTPC_METHOD_BREAKPOINTED);
2544
}
2545
2546
} /* extern "C" */
2547
2548
2549