Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/ilgen/J9ByteCodeIlGenerator.hpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 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
#ifndef IlGenerator_h
24
#define IlGenerator_h
25
26
#include "ilgen/J9ByteCodeIteratorWithState.hpp"
27
28
#include "env/CompilerEnv.hpp"
29
#include "env/ExceptionTable.hpp"
30
#include "env/jittypes.h"
31
#include "il/Block.hpp"
32
#include "il/Node.hpp"
33
#include "il/SymbolReference.hpp"
34
#include "ilgen/IlGen.hpp"
35
#include "infra/Checklist.hpp"
36
#include "infra/Link.hpp"
37
#include "infra/Stack.hpp"
38
#include "env/VMJ9.h"
39
40
class TR_InlineBlocks;
41
class TR_PersistentClassInfo;
42
class TR_BitVector;
43
namespace TR { class IlGeneratorMethodDetails; }
44
45
class TR_J9ByteCodeIlGenerator : public TR_IlGenerator, public TR_J9ByteCodeIteratorWithState
46
{
47
public:
48
TR_J9ByteCodeIlGenerator(TR::IlGeneratorMethodDetails & details,
49
TR::ResolvedMethodSymbol *,
50
TR_J9VMBase *fe,
51
TR::Compilation *,
52
TR::SymbolReferenceTable *,
53
bool forceClassLookahead = false,
54
TR_InlineBlocks *blocksToInline=0,
55
int32_t argPlaceholderSlot=-1);
56
57
TR_ALLOC(TR_Memory::IlGenerator)
58
59
TR::CodeGenerator * cg() { return _compilation->cg(); }
60
TR::Compilation * comp() { return _compilation; }
61
TR_J9VMBase * fej9() { return (TR_J9VMBase *)_fe; }
62
63
TR_Memory * trMemory() { return _trMemory; }
64
TR_StackMemory trStackMemory() { return _trMemory; }
65
TR_HeapMemory trHeapMemory() { return _trMemory; }
66
TR_PersistentMemory * trPersistentMemory() { return _trMemory->trPersistentMemory(); }
67
68
TR::IlGeneratorMethodDetails & methodDetails() { return _methodDetails; }
69
70
virtual bool genIL();
71
virtual int32_t currentByteCodeIndex() { return TR_J9ByteCodeIterator::currentByteCodeIndex(); }
72
virtual TR::Block * getCurrentBlock() { return _block; }
73
74
virtual void performClassLookahead(TR_PersistentClassInfo *);
75
76
bool isPeekingMethod() { return _compilation->isPeekingMethod();}
77
bool inliningCheckIfFinalizeObjectIsBeneficial()
78
{
79
return (comp()->getOption(TR_FullSpeedDebug) || comp()->getOptLevel() <= cold ||
80
(!comp()->getOption(TR_DisableInlineCheckIfFinalizeObject) && fej9()->isBenefitInliningCheckIfFinalizeObject()) ||
81
(comp()->getCurrentMethod()->isConstructor() && !comp()->getCurrentMethod()->isFinal()));
82
}
83
virtual TR::ResolvedMethodSymbol *methodSymbol() const { return _methodSymbol;}
84
85
private:
86
87
bool trace(){ return comp()->getOption(TR_TraceBC) || comp()->getOption(TR_TraceILGen); }
88
89
virtual void saveStack(int32_t);
90
void saveStack(int32_t targetIndex, bool anchorLoads);
91
92
// GenBranch
93
//
94
int32_t genGoto(int32_t);
95
int32_t genIfOneOperand(TR::ILOpCodes);
96
int32_t genIfTwoOperand(TR::ILOpCodes);
97
int32_t genIfAcmpEqNe(TR::ILOpCodes);
98
int32_t genIfImpl(TR::ILOpCodes);
99
100
/** \brief
101
* Generates IL for a return bytecode.
102
*
103
* \param nodeop
104
* The IL opcode to use for the return.
105
*
106
* \param monitorExit
107
* Determines whether the method which contains this return is synchronized in which case <c>TR::monitorExit</c>
108
* nodes may need to be generated.
109
*
110
* \return
111
* The index of the next bytecode to generate.
112
*/
113
int32_t genReturn(TR::ILOpCodes nodeop, bool monitorExit);
114
115
int32_t genLookupSwitch();
116
int32_t genTableSwitch();
117
118
// GenCall
119
//
120
void genInvokeStatic(int32_t);
121
void genInvokeSpecial(int32_t);
122
void genInvokeVirtual(int32_t);
123
void genInvokeInterface(int32_t);
124
void genInvokeDynamic(int32_t callSiteIndex);
125
TR::Node * genInvokeHandle(int32_t cpIndex);
126
TR::Node * genInvokeHandleGeneric(int32_t cpIndex);
127
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
128
/**
129
* \brief
130
* Generates IL to load elements from invokeCacheArray, resulting in load of
131
* appendix and memberName objects into the stack to be used as
132
* parameters for adapter method call node. memberName object is only required
133
* to be loaded when the invokedynamic/invokehandle is unresolved
134
*
135
* \param tableEntrySymRef the symref representing the invokeCacheArray
136
* \param invokeCacheArray the static address of the invokeCacheArray
137
* \param isUnresolved
138
*/
139
void loadInvokeCacheArrayElements(TR::SymbolReference *tableEntrySymRef, uintptr_t * invokeCacheArray, bool isUnresolved);
140
#endif
141
142
TR::Node * genHandleTypeCheck(TR::Node *handle, TR::Node *expectedType);
143
144
TR::Node * genInvokeHandle(TR::SymbolReference *invokeExactSymRef, TR::Node *invokedynamicReceiver = NULL);
145
TR::Node * genILGenMacroInvokeExact(TR::SymbolReference *invokeExactSymRef);
146
147
bool runMacro(TR::SymbolReference *);
148
bool runFEMacro(TR::SymbolReference *);
149
TR::Node * genInvoke(TR::SymbolReference *, TR::Node *indirectCallFirstChild, TR::Node *invokedynamicReceiver = NULL);
150
151
TR::Node * genInvokeDirect(TR::SymbolReference *symRef){ return genInvoke(symRef, NULL); }
152
TR::Node * genInvokeWithVFTChild(TR::SymbolReference *);
153
TR::Node * getReceiverFor(TR::SymbolReference *);
154
void stashArgumentsForOSR(TR_J9ByteCode byteCode);
155
/** \brief
156
* Tell if the current bytecode is at start of a basic block
157
*/
158
bool isAtBBStart(int32_t bcIndex);
159
160
// Placeholder manipulation
161
//
162
void genArgPlaceholderCall();
163
int32_t expandPlaceholderCall(); // TODO:JSR292: Combine these into a single function?
164
int32_t numPlaceholderCalls(int32_t depthLimit);
165
int32_t expandPlaceholderCalls(int32_t depthLimit);
166
TR::SymbolReference *expandPlaceholderSignature(TR::SymbolReference *symRef, int32_t numArgs);
167
TR::SymbolReference *expandPlaceholderSignature(TR::SymbolReference *symRef, int32_t numArgs, int32_t firstArgStackDepth);
168
TR::SymbolReference *placeholderWithDummySignature();
169
TR::SymbolReference *placeholderWithSignature(char *prefix, int prefixLength, char *middle, int middleLength, char *suffix, int suffixLength);
170
171
void chopPlaceholder(TR::Node *placeholder, int32_t firstChild, int32_t numChildren);
172
173
char *artificialSignature (TR_AllocationKind alloc, char *format, ...);
174
char *vartificialSignature(TR_AllocationKind alloc, char *format, va_list args);
175
TR::SymbolReference *symRefWithArtificialSignature(TR::SymbolReference *original, char *effectiveSigFormat, ...);
176
177
// GenLoadStore
178
//
179
void loadInstance(int32_t);
180
void loadInstance(TR::SymbolReference *);
181
void loadFlattenableInstance(int32_t);
182
void loadFlattenableInstanceWithHelper(int32_t cpIndex);
183
void loadStatic(int32_t);
184
void loadAuto(TR::DataType type, int32_t slot, bool isAdjunct = false);
185
TR::Node *loadSymbol(TR::ILOpCodes, TR::SymbolReference *);
186
void loadConstant(TR::ILOpCodes, int32_t);
187
void loadConstant(TR::ILOpCodes, int64_t);
188
void loadConstant(TR::ILOpCodes, float);
189
void loadConstant(TR::ILOpCodes, double);
190
void loadConstant(TR::ILOpCodes, void *);
191
void loadFromCP(TR::DataType, int32_t);
192
void loadFromCallSiteTable(int32_t);
193
194
void loadClassObjectAndIndirect(int32_t cpIndex);
195
196
void loadClassObject(int32_t cpIndex);
197
TR::SymbolReference *loadClassObjectForTypeTest(int32_t cpIndex, TR_CompilationOptions aotInhibit);
198
void loadClassObject(TR_OpaqueClassBlock *opaqueClass);
199
void loadArrayElement(TR::DataType dt){ loadArrayElement(dt, comp()->il.opCodeForIndirectArrayLoad(dt)); }
200
void loadArrayElement(TR::DataType dt, TR::ILOpCodes opCode, bool checks = true, bool mayBeValueType = true);
201
void loadMonitorArg();
202
203
void storeInstance(int32_t);
204
void storeInstance(TR::SymbolReference *);
205
void storeFlattenableInstance(int32_t);
206
void storeFlattenableInstanceWithHelper(int32_t);
207
void storeStatic(int32_t);
208
void storeAuto(TR::DataType type, int32_t slot, bool isAdjunct = false);
209
void storeArrayElement(TR::DataType dt){ storeArrayElement(dt, comp()->il.opCodeForIndirectArrayStore(dt)); }
210
void storeArrayElement(TR::DataType dt, TR::ILOpCodes opCode, bool checks = true);
211
212
void calculateElementAddressInContiguousArray(int32_t, int32_t);
213
void calculateIndexFromOffsetInContiguousArray(int32_t, int32_t);
214
void calculateArrayElementAddress(TR::DataType, bool checks);
215
216
// GenMisc
217
//
218
TR::TreeTop * genTreeTop(TR::Node *);
219
220
TR::Node * loadConstantValueIfPossible(TR::Node *, uintptr_t, TR::DataType type = TR::Int32, bool isArrayLength = true);
221
222
void genArrayLength();
223
void genContiguousArrayLength(int32_t width);
224
void genArrayBoundsCheck(TR::Node *, int32_t);
225
void genDivCheck();
226
void genIDiv();
227
void genLDiv();
228
void genIRem();
229
void genLRem();
230
TR::Node * genNullCheck(TR::Node *);
231
TR::Node * genResolveCheck(TR::Node *);
232
TR::Node * genResolveAndNullCheck(TR::Node *);
233
void genInc();
234
void genIncLong();
235
void genAsyncCheck();
236
void genNew(int32_t cpIndex);
237
void genNew(TR::ILOpCodes opCode=TR::New);
238
void genNewArray(int32_t typeIndex);
239
void genANewArray(int32_t cpIndex);
240
void genANewArray();
241
void genMultiANewArray(int32_t cpIndex, int32_t dims);
242
void genMultiANewArray(int32_t dims);
243
void genInstanceof(int32_t cpIndex);
244
void genCheckCast(int32_t);
245
void genCheckCast();
246
int32_t genAThrow();
247
void genMonitorEnter();
248
void genMonitorExit(bool);
249
TR_OpaqueClassBlock *loadValueClass(int32_t classCpIndex);
250
void genAconst_init(uint16_t classCpIndex);
251
void genAconst_init(TR_OpaqueClassBlock *valueTypeClass);
252
void genWithField(uint16_t fieldCpIndex);
253
void genWithField(TR::SymbolReference *, TR_OpaqueClassBlock *);
254
void genFlattenableWithField(uint16_t, TR_OpaqueClassBlock *);
255
void genFlattenableWithFieldWithHelper(uint16_t fieldCpIndex);
256
void genFlush(int32_t nargs);
257
void genFullFence(TR::Node *node);
258
void handlePendingPushSaveSideEffects(TR::Node *, int32_t stackSize = -1);
259
void handlePendingPushSaveSideEffects(TR::Node *, TR::NodeChecklist&, int32_t stackSize = -1);
260
void handleSideEffect(TR::Node *);
261
bool valueMayBeModified(TR::Node *, TR::Node *);
262
TR::Node * genCompressedRefs(TR::Node *, bool genTT = true, int32_t isLoad = 1);
263
void abortForUnresolvedValueTypeOp(const char* bytecodeName, const char* refType);
264
265
// IlGenerator
266
//
267
bool internalGenIL();
268
bool genILFromByteCodes();
269
270
void prependEntryCode(TR::Block *);
271
void prependGuardedCountForRecompilation(TR::Block * firstBlock);
272
TR::Node * genMethodEnterHook();
273
TR::Block * genExceptionHandlers(TR::Block *);
274
TR::Block * cloneHandler(TryCatchInfo *, TR::Block *, TR::Block *, TR::Block *, List<TR::Block> *);
275
void createGeneratedFirstBlock();
276
bool genJNIIL();
277
bool genNewInstanceImplThunk();
278
void genJavaLangSystemIdentityHashCode();
279
void genHWOptimizedStrProcessingAvailable();
280
void genJITIntrinsicsEnabled();
281
void genIsORBDeepCopyAvailable();
282
283
TR::Node *genNewInstanceImplCall(TR::Node *classNode);
284
//TR::Node * transformNewInstanceImplCall(TR::TreeTop *, TR::Node *);
285
286
// Dynamic Loop Transfer
287
void genDLTransfer(TR::Block *);
288
289
// OSR
290
void stashPendingPushLivenessForOSR(int32_t offset = 0);
291
292
void inlineJitCheckIfFinalizeObject(TR::Block *);
293
294
// support for dual symbols, to generate adjunct symbol of the dual
295
TR::Node* genOrFindAdjunct(TR::Node* node);
296
void storeDualAuto(TR::Node * storeValue, int32_t slot);
297
298
// Walker
299
//
300
TR::Block * walker(TR::Block *);
301
302
int32_t cmp(TR::ILOpCodes, TR::ILOpCodes *, int32_t &);
303
int32_t cmpFollowedByIf(uint8_t, TR::ILOpCodes, int32_t &);
304
305
// [PR 101228] To avoid class resolution on (null instanceof T) and (T)null.
306
void expandUnresolvedClassCheckcast(TR::TreeTop *tree);
307
void expandUnresolvedClassInstanceof(TR::TreeTop *tree);
308
309
// [PR 124693] To check types on invokespecial within interface methods.
310
bool skipInvokeSpecialInterfaceTypeChecks();
311
void expandInvokeSpecialInterface(TR::TreeTop *tree);
312
313
// Expand MethodHandle invoke
314
void expandInvokeHandle(TR::TreeTop *tree);
315
void expandInvokeExact(TR::TreeTop *tree);
316
void expandInvokeDynamic(TR::TreeTop *tree);
317
void expandInvokeHandleGeneric(TR::TreeTop *tree);
318
void expandMethodHandleInvokeCall(TR::TreeTop *tree);
319
void insertCustomizationLogicTreeIfEnabled(TR::TreeTop *tree, TR::Node* methodHandle);
320
TR::Node* loadCallSiteMethodTypeFromCP(TR::Node* methodHandleInvokeCall);
321
TR::Node* loadFromMethodTypeTable(TR::Node* methodHandleInvokeCall);
322
TR::Node* loadCallSiteMethodType(TR::Node* methodHandleInvokeCall);
323
324
// inline functions
325
//
326
TR::SymbolReferenceTable * symRefTab() { return _symRefTab; }
327
TR::CFG * cfg() { return _methodSymbol->getFlowGraph(); }
328
bool isOutermostMethod() { return comp()->isOutermostMethod(); }
329
330
bool swapChildren(TR::ILOpCodes, TR::Node *);
331
void removeIfNotOnStack(TR::Node *n);
332
void popAndDiscard(int n);
333
void discardEntireStack();
334
void startCountingStackRefs();
335
void stopCountingStackRefs();
336
void eat1()
337
{
338
popAndDiscard(1);
339
}
340
void eat2()
341
{
342
bool narrow = numberOfByteCodeStackSlots(node(_stack->topIndex())) == 4;
343
popAndDiscard(narrow ? 2 : 1);
344
}
345
346
bool fieldsAreSame(TR::SymbolReference * s1, TR::SymbolReference * s2)
347
{
348
//bool sigSame = true;
349
//return s1->getOwningMethod(_compilation)->fieldsAreSame(s1->getCPIndex(), s2->getOwningMethod(_compilation), s2->getCPIndex(), sigSame);
350
return TR::Compiler->cls.jitFieldsAreSame(_compilation, s1->getOwningMethod(_compilation), s1->getCPIndex(), s2->getOwningMethod(_compilation), s2->getCPIndex(), false);
351
}
352
353
bool staticsAreSame(TR::SymbolReference * s1, TR::SymbolReference * s2)
354
{
355
//bool sigSame = true;
356
//return s1->getOwningMethod(_compilation)->staticsAreSame(s1->getCPIndex(), s2->getOwningMethod(_compilation), s2->getCPIndex(), sigSame);
357
return TR::Compiler->cls.jitStaticsAreSame(_compilation, s1->getOwningMethod(_compilation), s1->getCPIndex(), s2->getOwningMethod(_compilation), s2->getCPIndex());
358
}
359
360
TR::Node * genNodeAndPopChildren(TR::ILOpCodes, int32_t, TR::SymbolReference *, int32_t = 0);
361
TR::Node * genNodeAndPopChildren(TR::ILOpCodes, int32_t, TR::SymbolReference *, int32_t firstIndex, int32_t lastIndex);
362
363
void genUnary(TR::ILOpCodes unaryOp, bool isForArrayAccess= false);
364
void genBinary(TR::ILOpCodes nodeop, int numChildren = 2);
365
366
bool replaceMembersOfFormat();
367
bool replaceMethods(TR::TreeTop *tt, TR::Node *node);
368
bool replaceFieldsAndStatics(TR::TreeTop *tt, TR::Node *node);
369
bool replaceField(TR::Node* node, char* destClass, char* destFieldName, char* destFieldSignature, int ParmIndex);
370
bool replaceStatic(TR::Node* node, char* dstClassName, char* staticName, char* type);
371
372
uintptr_t walkReferenceChain(TR::Node *node, uintptr_t receiver);
373
#if defined(J9VM_OPT_JITSERVER)
374
void packReferenceChainOffsets(TR::Node *node, std::vector<uintptr_t>& listOfOffsets);
375
#endif
376
377
bool hasFPU();
378
379
// data
380
//
381
TR::SymbolReferenceTable * _symRefTab;
382
TR::SymbolReferenceTable * _classLookaheadSymRefTab;
383
int32_t _firstTempCookie;
384
TR_PersistentClassInfo * _classInfo;
385
TR_ScratchList<TR::Node> _implicitMonitorExits;
386
TR_ScratchList<TR::Node> _finalizeCallsBeforeReturns;
387
TR::IlGeneratorMethodDetails &_methodDetails;
388
389
// TAROK only. Suppress spine check trees. This is a debug feature only and will be
390
// removed when full support is available.
391
//
392
bool _suppressSpineChecks;
393
394
bool _generateWriteBarriersForGC;
395
bool _generateWriteBarriersForFieldWatch;
396
bool _generateReadBarriersForFieldWatch;
397
vcount_t _blockAddedVisitCount;
398
bool _noLookahead;
399
bool _thisChanged;
400
TR_InlineBlocks *_blocksToInline;
401
bool _intrinsicErrorHandling;
402
bool _couldOSRAtNextBC;
403
404
// JSR292
405
int32_t _argPlaceholderSlot;
406
int32_t _argPlaceholderSignatureOffset;
407
TR_BitVector *_methodHandleInvokeCalls;
408
TR_BitVector *_invokeHandleCalls;
409
TR_BitVector *_invokeHandleGenericCalls;
410
TR_BitVector *_invokeDynamicCalls;
411
TR_BitVector *_ilGenMacroInvokeExactCalls;
412
413
// TenantScope field support, set to 'true' if a get/put static is encountered
414
// when option TR_DisableMultiTenancy is on and current method contains static
415
// field and method reference/invoke, skip compilation for such method
416
bool _staticFieldReferenceEncountered;
417
bool _staticMethodInvokeEncountered;
418
419
TR_OpaqueClassBlock *_invokeSpecialInterface;
420
TR_BitVector *_invokeSpecialInterfaceCalls;
421
bool _invokeSpecialSeen;
422
423
// OSR
424
TR::NodeChecklist *_processedOSRNodes;
425
426
// DecimalFormatPeephole
427
struct methodRenamePair{
428
char* srcMethodSignature;
429
char* dstMethodSignature;
430
};
431
432
static const int32_t _numDecFormatRenames = 9;
433
static struct methodRenamePair _decFormatRenames[_numDecFormatRenames];
434
TR::SymbolReference *_decFormatRenamesDstSymRef[_numDecFormatRenames];
435
};
436
437
#endif
438
439