Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/codegen/J9CodeGenerator.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 J9_CODEGENERATOR_INCL
24
#define J9_CODEGENERATOR_INCL
25
26
/*
27
* The following #define and typedef must appear before any #includes in this file
28
*/
29
#ifndef J9_CODEGENERATOR_CONNECTOR
30
#define J9_CODEGENERATOR_CONNECTOR
31
32
namespace J9 { class CodeGenerator; }
33
namespace J9 { typedef J9::CodeGenerator CodeGeneratorConnector; }
34
#endif
35
36
#include "codegen/OMRCodeGenerator.hpp"
37
38
#include <stdint.h>
39
#include "env/IO.hpp"
40
#include "env/jittypes.h"
41
#include "infra/List.hpp"
42
#include "infra/HashTab.hpp"
43
#include "codegen/RecognizedMethods.hpp"
44
#if defined(J9VM_OPT_JITSERVER)
45
#include "control/CompilationRuntime.hpp"
46
#endif /* defined(J9VM_OPT_JITSERVER) */
47
#include "control/Recompilation.hpp"
48
#include "control/RecompilationInfo.hpp"
49
#include "optimizer/Dominators.hpp"
50
#include "cs2/arrayof.h"
51
52
class NVVMIRBuffer;
53
class TR_BitVector;
54
class TR_SharedMemoryAnnotations;
55
class TR_J9VMBase;
56
namespace TR { class Block; }
57
namespace TR { class Node; }
58
namespace TR { class SymbolReference; }
59
namespace TR { class TreeTop; }
60
61
namespace J9
62
{
63
64
class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGeneratorConnector
65
{
66
67
protected:
68
69
CodeGenerator(TR::Compilation *comp);
70
71
public:
72
73
void initialize();
74
75
TR_J9VMBase *fej9();
76
77
TR::TreeTop *lowerTree(TR::Node *root, TR::TreeTop *treeTop);
78
79
void preLowerTrees();
80
81
void lowerTreesPreTreeTopVisit(TR::TreeTop *tt, vcount_t visitCount);
82
83
void lowerTreesPreChildrenVisit(TR::Node * parent, TR::TreeTop * treeTop, vcount_t visitCount);
84
85
void lowerTreeIfNeeded(TR::Node *node, int32_t childNumber, TR::Node *parent, TR::TreeTop *tt);
86
87
void lowerDualOperator(TR::Node *parent, int32_t childNumber, TR::TreeTop *treeTop);
88
89
public:
90
91
bool collectSymRefs(TR::Node *node, TR_BitVector *symRefs, vcount_t secondVisitCount);
92
93
void moveUpArrayLengthStores(TR::TreeTop *insertionPoint);
94
95
void doInstructionSelection();
96
97
void createReferenceReadBarrier(TR::TreeTop* treeTop, TR::Node* parent);
98
99
TR::list<TR_Pair<TR_ResolvedMethod,TR::Instruction> *> &getJNICallSites() { return _jniCallSites; } // registerAssumptions()
100
101
// OSR, not code generator
102
void populateOSRBuffer();
103
104
void lowerCompressedRefs(TR::TreeTop *, TR::Node*, vcount_t, TR_BitVector *);
105
void compressedReferenceRematerialization(); // J9
106
void rematerializeCompressedRefs(TR::SymbolReference * &, TR::TreeTop *, TR::Node*, int32_t, TR::Node*, vcount_t, List<TR::Node> *);
107
void anchorRematNodesIfNeeded(TR::Node*, TR::TreeTop *, List<TR::Node> *);
108
void yankCompressedRefs(TR::TreeTop *, TR::Node *, int32_t, TR::Node *, vcount_t, vcount_t);
109
110
void setUpForInstructionSelection();
111
112
void insertEpilogueYieldPoints();
113
114
void allocateLinkageRegisters();
115
116
void fixUpProfiledInterfaceGuardTest();
117
118
/**
119
* \brief
120
* This query is used by both fixUpProfiledInterfaceGuardTest (a codegen level optimization) and virtual guard evaluators
121
* to decide whether a NOP guard should be generated. It's used on all platforms and compilation phases so that the decision
122
* of generating VG NOPs is made in a consistent way.
123
*
124
* \param node
125
* the virtual guard node
126
*
127
* \return
128
* true if a NOP virtual guard should be generated. Otherwise, false.
129
*/
130
bool willGenerateNOPForVirtualGuard(TR::Node* node);
131
132
void zeroOutAutoOnEdge(TR::SymbolReference * liveAutoSym, TR::Block *block, TR::Block *succBlock, TR::list<TR::Block*> *newBlocks, TR_ScratchList<TR::Node> *fsdStores);
133
134
TR::Linkage *createLinkageForCompilation();
135
136
bool enableAESInHardwareTransformations() {return false;}
137
138
bool isMethodInAtomicLongGroup(TR::RecognizedMethod rm);
139
bool arithmeticNeedsLiteralFromPool(TR::Node *node) { return false; }
140
141
// OSR
142
//
143
TR::TreeTop* genSymRefStoreToArray(TR::Node* refNode, TR::Node* arrayAddressNode, TR::Node* firstOffset,
144
TR::Node* symRefLoad, int32_t secondOffset, TR::TreeTop* insertionPoint);
145
146
// --------------------------------------
147
// AOT Relocations
148
//
149
#if defined(J9VM_OPT_JITSERVER)
150
void addExternalRelocation(TR::Relocation *r, const char *generatingFileName, uintptr_t generatingLineNumber, TR::Node *node, TR::ExternalRelocationPositionRequest where = TR::ExternalRelocationAtBack);
151
void addExternalRelocation(TR::Relocation *r, TR::RelocationDebugInfo *info, TR::ExternalRelocationPositionRequest where = TR::ExternalRelocationAtBack);
152
#endif /* defined(J9VM_OPT_JITSERVER) */
153
154
void processRelocations();
155
156
//TR::ExternalRelocation
157
void addProjectSpecializedRelocation(uint8_t *location,
158
uint8_t *target,
159
uint8_t *target2, //pass in NULL when no target2
160
TR_ExternalRelocationTargetKind kind,
161
char *generatingFileName,
162
uintptr_t generatingLineNumber,
163
TR::Node *node);
164
//TR::ExternalOrderedPair32BitRelocation
165
void addProjectSpecializedPairRelocation(uint8_t *location1,
166
uint8_t *location2,
167
uint8_t *target,
168
TR_ExternalRelocationTargetKind kind,
169
char *generatingFileName,
170
uintptr_t generatingLineNumber,
171
TR::Node *node);
172
//TR::BeforeBinaryEncodingExternalRelocation
173
void addProjectSpecializedRelocation(TR::Instruction *instr,
174
uint8_t *target,
175
uint8_t *target2, //pass in NULL when no target2
176
TR_ExternalRelocationTargetKind kind,
177
char *generatingFileName,
178
uintptr_t generatingLineNumber,
179
TR::Node *node);
180
181
bool needClassAndMethodPointerRelocations();
182
bool needRelocationsForLookupEvaluationData();
183
bool needRelocationsForStatics();
184
bool needRelocationsForHelpers();
185
bool needRelocationsForCurrentMethodPC();
186
#if defined(J9VM_OPT_JITSERVER)
187
bool needRelocationsForBodyInfoData();
188
bool needRelocationsForPersistentInfoData();
189
#endif /* defined(J9VM_OPT_JITSERVER) */
190
191
// ----------------------------------------
192
TR::Node *createOrFindClonedNode(TR::Node *node, int32_t numChildren);
193
194
void jitAddUnresolvedAddressMaterializationToPatchOnClassRedefinition(void *firstInstruction);
195
196
uint32_t getStackLimitOffset() {return _stackLimitOffsetInMetaData;}
197
uint32_t setStackLimitOffset(uint32_t o) {return (_stackLimitOffsetInMetaData = o);}
198
199
bool alwaysGeneratesAKnownCleanSign(TR::Node *node) { return false; } // no virt
200
bool alwaysGeneratesAKnownPositiveCleanSign(TR::Node *node) { return false; } // no virt
201
TR_RawBCDSignCode alwaysGeneratedSign(TR::Node *node) { return raw_bcd_sign_unknown; } // no virt
202
203
void swapChildrenIfNeeded(TR::Node *store, char *optDetails);
204
205
TR::AutomaticSymbol *allocateVariableSizeSymbol(int32_t size);
206
TR::SymbolReference *allocateVariableSizeSymRef(int32_t byteLength);
207
void pendingFreeVariableSizeSymRef(TR::SymbolReference *sym);
208
void freeVariableSizeSymRef(TR::SymbolReference *sym, bool freeAddressTakenSymbol=false);
209
void freeAllVariableSizeSymRefs();
210
211
TR::SymbolReference *getFreeVariableSizeSymRef(int byteLength);
212
void checkForUnfreedVariableSizeSymRefs();
213
214
bool allowGuardMerging();
215
void registerAssumptions();
216
217
void jitAddPicToPatchOnClassUnload(void *classPointer, void *addressToBePatched);
218
void jitAdd32BitPicToPatchOnClassUnload(void *classPointer, void *addressToBePatched);
219
void jitAddPicToPatchOnClassRedefinition(void *classPointer, void *addressToBePatched, bool unresolved = false);
220
void jitAdd32BitPicToPatchOnClassRedefinition(void *classPointer, void *addressToBePatched, bool unresolved = false);
221
222
void createHWPRecords();
223
224
void createStackAtlas();
225
226
// --------------------------------------------------------------------------
227
// GPU
228
//
229
static const int32_t GPUAlignment = 128;
230
uintptr_t objectLengthOffset();
231
uintptr_t objectHeaderInvariant();
232
233
enum GPUScopeType
234
{
235
naturalLoopScope = 0,
236
singleKernelScope = 1
237
};
238
239
enum GPUResult
240
{
241
GPUSuccess = 0,
242
GPUNullCheck = 1,
243
GPUBndCheck = 2,
244
GPUDivException = 3,
245
GPUInvalidProgram = 4,
246
GPUHelperError = 5,
247
GPULaunchError = 6,
248
GPUBadDevicePointer = 7
249
};
250
251
enum GPUAccessKind {None = 0, ReadAccess= 1, WriteAccess = 2, ReadWriteAccesses = 3};
252
class gpuMapElement
253
{
254
public:
255
TR_ALLOC(TR_Memory::CodeGenerator); // dummy
256
257
gpuMapElement() : _node(NULL), _hostSymRef(NULL), _hostSymRefTemp(NULL), _devSymRef(NULL), _hoistAccess(false), _elementSize(-1), _parmSlot(-1), _accessKind(None), _lhsAddrExpr(NULL), _rhsAddrExpr(NULL) {}
258
259
gpuMapElement(TR::Node *node, TR::SymbolReference *hostSymRef, int32_t elementSize, int32_t parmSlot)
260
:
261
_node(node), _hostSymRef(hostSymRef), _hostSymRefTemp(NULL), _devSymRef(NULL), _hoistAccess(false),
262
_elementSize(elementSize), _parmSlot(parmSlot), _accessKind(None), _lhsAddrExpr(NULL), _rhsAddrExpr(NULL) {}
263
264
TR::Node *_node;
265
TR::SymbolReference *_hostSymRef;
266
TR::SymbolReference *_hostSymRefTemp;
267
TR::SymbolReference *_devSymRef;
268
int32_t _elementSize;
269
int32_t _parmSlot;
270
uint32_t _accessKind;
271
bool _hoistAccess;
272
TR::Node *_rhsAddrExpr;
273
TR::Node *_lhsAddrExpr;
274
};
275
276
class gpuParameter
277
{
278
public:
279
TR_ALLOC(TR_Memory::CodeGenerator); // dummy
280
281
gpuParameter() : _hostSymRef(NULL), _parmSlot(-1) {}
282
283
gpuParameter(TR::SymbolReference *hostSymRef, int32_t parmSlot)
284
: _hostSymRef(hostSymRef), _parmSlot(parmSlot) {}
285
286
TR::SymbolReference *_hostSymRef;
287
int32_t _parmSlot;
288
};
289
290
CS2::ArrayOf<gpuMapElement, TR::Allocator> _gpuSymbolMap;
291
292
bool _gpuHasNullCheck;
293
bool _gpuHasBndCheck;
294
bool _gpuHasDivCheck;
295
296
scount_t _gpuNodeCount;
297
TR::Block *_gpuCurrentBlock;
298
TR::DataTypes _gpuReturnType;
299
TR_Dominators *_gpuPostDominators;
300
TR::Block *_gpuStartBlock;
301
uint64_t _gpuNeedNullCheckArguments_vector;
302
bool _gpuCanUseReadOnlyCache;
303
bool _gpuUseOldLdgCalls;
304
305
TR_BitVector *getLiveMonitors() {return _liveMonitors;}
306
TR_BitVector *setLiveMonitors(TR_BitVector *v) {return (_liveMonitors = v);}
307
308
public:
309
/*
310
* \brief
311
* Get the most abstract type the monitor may be operating on.
312
*
313
* \note
314
* java.lang.Object is only returned when the monitor object is of type java.lang.Object but not any subclasses
315
*/
316
TR_OpaqueClassBlock* getMonClass(TR::Node* monNode);
317
318
/*
319
* \brief
320
* Whether a monitor object is of value based class type or value type.
321
* This API checks if value based or value type is enabled first.
322
*
323
* \return
324
* TR_yes The monitor object is definitely value based class type or value type
325
* TR_no The monitor object is definitely not value based class type or value type
326
* TR_maybe It is unknown whether the monitor object is value based class type or value type
327
*/
328
TR_YesNoMaybe isMonitorValueBasedOrValueType(TR::Node* monNode);
329
330
protected:
331
332
typedef TR::typed_allocator<std::pair<const ncount_t , TR_OpaqueClassBlock*>, TR::Region &> MonitorMapAllocator;
333
typedef std::map<ncount_t , TR_OpaqueClassBlock *, std::less<ncount_t>, MonitorMapAllocator> MonitorTypeMap;
334
335
MonitorTypeMap _monitorMapping; // map global node index to monitor object class
336
337
void addMonClass(TR::Node* monNode, TR_OpaqueClassBlock* clazz);
338
339
private:
340
341
TR_HashTabInt _uncommonedNodes; // uncommoned nodes keyed by the original nodes
342
343
TR::list<TR::Node*> _nodesSpineCheckedList;
344
345
TR::list<TR_Pair<TR_ResolvedMethod, TR::Instruction> *> _jniCallSites; // list of instrutions representing direct jni call sites
346
347
uint16_t changeParmLoadsToRegLoads(TR::Node*node, TR::Node **regLoads, TR_BitVector *globalRegsWithRegLoad, TR_BitVector &killedParms, vcount_t visitCount); // returns number of RegLoad nodes created
348
349
static bool wantToPatchClassPointer(TR::Compilation *comp,
350
const TR_OpaqueClassBlock *allegedClassPointer,
351
const char *locationDescription,
352
const void *location)
353
{
354
// If we have a class pointer to consider, it should look like one.
355
const uintptr_t j9classEyecatcher = 0x99669966;
356
#if defined(J9VM_OPT_JITSERVER)
357
if (allegedClassPointer != NULL && !comp->isOutOfProcessCompilation())
358
#else
359
if (allegedClassPointer != NULL)
360
#endif /* defined(J9VM_OPT_JITSERVER) */
361
{
362
TR_ASSERT(*(const uintptr_t*)allegedClassPointer == j9classEyecatcher,
363
"expected a J9Class* for omitted runtime assumption");
364
}
365
366
// Class pointer patching is restricted to HCR mode.
367
if (!comp->getOption(TR_EnableHCR))
368
return false;
369
370
// -Xjit:HCRPatchClassPointers re-enables all class pointer assumptions
371
if (comp->getOption(TR_HCRPatchClassPointers))
372
return true;
373
374
return !performTransformation(comp,
375
"O^O OMIT HCR CLASS POINTER ASSUMPTION: class=" POINTER_PRINTF_FORMAT ", %s " POINTER_PRINTF_FORMAT "\n", allegedClassPointer,
376
locationDescription,
377
location);
378
}
379
380
uint32_t _stackLimitOffsetInMetaData;
381
382
/*
383
* Scratch data for refined aliasing walk during
384
*/
385
struct RefinedAliasWalkCollector
386
{
387
TR_PersistentMethodInfo *methodInfo;
388
bool killsEverything;
389
bool killsAddressStatics;
390
bool killsIntStatics;
391
bool killsNonIntPrimitiveStatics;
392
bool killsAddressFields;
393
bool killsIntFields;
394
bool killsNonIntPrimitiveFields;
395
bool killsAddressArrayShadows;
396
bool killsIntArrayShadows;
397
bool killsNonIntPrimitiveArrayShadows;
398
};
399
400
RefinedAliasWalkCollector _refinedAliasWalkCollector;
401
402
TR_BitVector *_liveMonitors;
403
404
protected:
405
406
// isTemporaryBased storageReferences just have a symRef but some other routines expect a node so use the below to fill in this symRef on this node
407
TR::Node *_dummyTempStorageRefNode;
408
409
public:
410
411
static bool wantToPatchClassPointer(TR::Compilation *comp,
412
const TR_OpaqueClassBlock *allegedClassPointer,
413
const uint8_t *inCodeAt);
414
415
bool wantToPatchClassPointer(const TR_OpaqueClassBlock *allegedClassPointer, const uint8_t *inCodeAt);
416
417
bool wantToPatchClassPointer(const TR_OpaqueClassBlock *allegedClassPointer, const TR::Node *forNode);
418
419
bool getSupportsBigDecimalLongLookasideVersioning() { return _flags3.testAny(SupportsBigDecimalLongLookasideVersioning);}
420
void setSupportsBigDecimalLongLookasideVersioning() { _flags3.set(SupportsBigDecimalLongLookasideVersioning);}
421
422
bool constLoadNeedsLiteralFromPool(TR::Node *node) { return false; }
423
424
// Java, likely Z
425
bool supportsTrapsInTMRegion() { return true; }
426
427
// J9
428
int32_t getInternalPtrMapBit() { return 31;}
429
430
// --------------------------------------------------------------------------
431
// GPU
432
//
433
void generateGPU();
434
435
void dumpInvariant(CS2::ArrayOf<gpuParameter, TR::Allocator>::Cursor pit, NVVMIRBuffer &ir, bool isbufferalign);
436
437
GPUResult dumpNVVMIR(TR::TreeTop *firstTreeTop, TR::TreeTop *lastTreeTop, TR_RegionStructure *loop, SharedSparseBitVector *blocksinLoop, ListBase<TR::AutomaticSymbol> *autos, ListBase<TR::ParameterSymbol> *parms, bool staticMethod, char * &nvvmIR, TR::Node * &errorNode, int gpuPtxCount, bool* hasExceptionChecks);
438
439
GPUResult printNVVMIR(NVVMIRBuffer &ir, TR::Node * node, TR_RegionStructure *loop, TR_BitVector *targetBlocks, vcount_t visitCount, TR_SharedMemoryAnnotations *sharedMemory, int32_t &nextParmNum, TR::Node * &errorNode);
440
441
void findExtraParms(TR::Node *node, int32_t &numExtraParms, TR_SharedMemoryAnnotations *sharedMemory, vcount_t visitCount);
442
443
bool handleRecognizedMethod(TR::Node *node, NVVMIRBuffer &ir, TR::Compilation *comp);
444
445
bool handleRecognizedField(TR::Node *node, NVVMIRBuffer &ir);
446
447
void printArrayCopyNVVMIR(TR::Node *node, NVVMIRBuffer &ir, TR::Compilation *comp);
448
449
450
bool hasFixedFrameC_CallingConvention() {return _j9Flags.testAny(HasFixedFrameC_CallingConvention);}
451
void setHasFixedFrameC_CallingConvention() {_j9Flags.set(HasFixedFrameC_CallingConvention);}
452
453
bool supportsJitMethodEntryAlignment();
454
455
/** \brief
456
* Determines whether the code generator supports inlining of java/lang/Class.isAssignableFrom
457
*/
458
bool supportsInliningOfIsAssignableFrom() { return false; } // no virt, default
459
460
/** \brief
461
* Determines whether the code generator must generate the switch to interpreter snippet in the preprologue.
462
*/
463
bool mustGenerateSwitchToInterpreterPrePrologue();
464
465
bool buildInterpreterEntryPoint() { return true; }
466
void generateCatchBlockBBStartPrologue(TR::Node *node, TR::Instruction *fenceInstruction);
467
bool supportsUnneededLabelRemoval() { return false; }
468
469
// Determines whether high-resolution timer can be used to implement java/lang/System.currentTimeMillis()
470
bool getSupportsMaxPrecisionMilliTime() {return _j9Flags.testAny(SupportsMaxPrecisionMilliTime);}
471
void setSupportsMaxPrecisionMilliTime() {_j9Flags.set(SupportsMaxPrecisionMilliTime);}
472
473
/** \brief
474
* Determines whether the code generator supports inlining of java/lang/String.toUpperCase() and toLowerCase()
475
*/
476
bool getSupportsInlineStringCaseConversion() { return _j9Flags.testAny(SupportsInlineStringCaseConversion);}
477
/** \brief
478
* The code generator supports inlining of java/lang/String.toUpperCase() and toLowerCase()
479
*/
480
void setSupportsInlineStringCaseConversion() { _j9Flags.set(SupportsInlineStringCaseConversion);}
481
482
/** \brief
483
* Determines whether the code generator supports inlining of java/lang/String.indexOf()
484
*/
485
bool getSupportsInlineStringIndexOf() { return _j9Flags.testAny(SupportsInlineStringIndexOf);}
486
487
/** \brief
488
* The code generator supports inlining of java/lang/String.indexOf()
489
*/
490
void setSupportsInlineStringIndexOf() { _j9Flags.set(SupportsInlineStringIndexOf);}
491
492
/** \brief
493
* Determines whether the code generator supports inlining of java/lang/String.hashCode()
494
*/
495
bool getSupportsInlineStringHashCode() { return _j9Flags.testAny(SupportsInlineStringHashCode); }
496
497
/** \brief
498
* The code generator supports inlining of java/lang/String.hashCode()
499
*/
500
void setSupportsInlineStringHashCode() { _j9Flags.set(SupportsInlineStringHashCode); }
501
502
/** \brief
503
* Determines whether the code generator supports inlining of java/lang/StringLatin1.inflate
504
*/
505
bool getSupportsInlineStringLatin1Inflate() { return _j9Flags.testAny(SupportsInlineStringLatin1Inflate); }
506
507
/** \brief
508
* The code generator supports inlining of java/lang/StringLatin1.inflate
509
*/
510
void setSupportsInlineStringLatin1Inflate() { _j9Flags.set(SupportsInlineStringLatin1Inflate); }
511
512
/** \brief
513
* Determines whether the code generator supports inlining of java_util_concurrent_ConcurrentLinkedQueue_tm*
514
* methods
515
*/
516
bool getSupportsInlineConcurrentLinkedQueue() { return _j9Flags.testAny(SupportsInlineConcurrentLinkedQueue); }
517
518
/** \brief
519
* The code generator supports inlining of java_util_concurrent_ConcurrentLinkedQueue_tm* methods
520
*/
521
void setSupportsInlineConcurrentLinkedQueue() { _j9Flags.set(SupportsInlineConcurrentLinkedQueue); }
522
523
/** \brief
524
* Determines whether the code generator supports inlining of java/lang/StringCoding.encodeASCII
525
*/
526
bool getSupportsInlineEncodeASCII() { return _j9Flags.testAny(SupportsInlineEncodeASCII); }
527
528
/** \brief
529
* The code generator supports inlining of java/lang/StringCoding.encodeASCII
530
*/
531
void setSupportsInlineEncodeASCII() { _j9Flags.set(SupportsInlineEncodeASCII); }
532
533
/**
534
* \brief
535
* The number of nodes between a monext and the next monent before
536
* transforming a monitored region with transactional lock elision.
537
*/
538
int32_t getMinimumNumberOfNodesBetweenMonitorsForTLE() { return 15; }
539
540
/**
541
* \brief Trim the size of code memory required by this method to match the
542
* actual code length required, allowing the reclaimed memory to be
543
* reused. This is needed when the conservative length estimate
544
* exceeds the actual memory requirement.
545
*/
546
void trimCodeMemoryToActualSize();
547
548
549
/**
550
* \brief Request and reserve a CodeCache for use by this compilation. Fail
551
* the compilation appropriately if a CodeCache cannot be allocated.
552
*/
553
void reserveCodeCache();
554
555
556
/**
557
* \brief Allocates code memory of the specified size in the specified area of
558
* the code cache. Fail the compilation on failure.
559
*
560
* \param[in] warmCodeSizeInBytes : the number of bytes to allocate in the warm area
561
* \param[in] coldCodeSizeInBytes : the number of bytes to allocate in the cold area
562
* \param[out] coldCode : address of the cold code (if allocated)
563
* \param[in] isMethodHeaderNeeded : boolean indicating whether space for a
564
* method header must be allocated
565
*
566
* \return address of the allocated warm code (if allocated)
567
*/
568
uint8_t *allocateCodeMemoryInner(
569
uint32_t warmCodeSizeInBytes,
570
uint32_t coldCodeSizeInBytes,
571
uint8_t **coldCode,
572
bool isMethodHeaderNeeded);
573
574
575
/**
576
* \brief Store a poison value in an auto slot that should have gone dead. Used for debugging.
577
*
578
* \param[in] currentBlock : block in which the auto slot appears
579
* \param[in] liveAutoSymRef : SymbolReference of auto slot to poison
580
*
581
* \return poisoned store node
582
*/
583
TR::Node *generatePoisonNode(
584
TR::Block *currentBlock,
585
TR::SymbolReference *liveAutoSymRef);
586
587
588
/**
589
* \brief Determines whether VM Internal Natives is supported or not
590
*/
591
bool supportVMInternalNatives();
592
593
594
/**
595
* \brief Determines whether the code generator supports stack allocations
596
*/
597
bool supportsStackAllocations() { return false; }
598
599
/**
600
* \brief Initializes the Linkage Info word found before the interpreter entry point.
601
*
602
* \param[in] linkageInfo : pointer to the linkage info word
603
*
604
* \return Linkage Info word
605
*/
606
uint32_t initializeLinkageInfo(void *linkageInfoPtr);
607
608
/**
609
* \brief Check if a profiled class is compatible with the call site
610
*
611
* \param[in] profiledClass : The J9Class obtained from profiling data
612
* \param[in] callSiteMethodClass : The J9Class from the J9Method of the call site target
613
*
614
* \return True if it can be determined that the profiled class is compatible, otherwise False
615
*/
616
bool isProfiledClassAndCallSiteCompatible(TR_OpaqueClassBlock *profiledClass, TR_OpaqueClassBlock *callSiteMethodClass);
617
618
/** \brief
619
* Determines whether the code generator supports inlining of java/lang/Integer.stringSize() or java/lang/Long.stringSize()
620
*/
621
bool getSupportsIntegerStringSize() { return _j9Flags.testAny(SupportsIntegerStringSize); }
622
623
/** \brief
624
* The code generator supports inlining of java/lang/Integer.stringSize() or java/lang/Long.stringSize()
625
*/
626
void setSupportsIntegerStringSize() {_j9Flags.set(SupportsIntegerStringSize); }
627
628
/** \brief
629
* Determines whether the code generator supports inlining of
630
* - Integer.getChars,
631
* - Long.getChars,
632
* - StringUTF16.getChars(JI[B)I,
633
* - StringUTF16.getChars(II[B)I
634
*/
635
bool getSupportsIntegerToChars() { return _j9Flags.testAny(SupportsIntegerToChars); }
636
637
/** \brief
638
* The code generator supports inlining of
639
* - Integer.getChars,
640
* - Long.getChars,
641
* - StringUTF16.getChars(JI[B)I,
642
* - StringUTF16.getChars(II[B)I
643
*/
644
void setSupportsIntegerToChars() {_j9Flags.set(SupportsIntegerToChars); }
645
646
/**
647
* \brief Determine whether this code generator guarantees resolved direct
648
* dispatch under AOT with SVM.
649
*
650
* \return true if resolved direct dispatch is guaranteed, false otherwise
651
* \see TR_J9VMBase::isResolvedDirectDispatchGuaranteed
652
*/
653
bool guaranteesResolvedDirectDispatchForSVM() { return false; } // safe default
654
655
/**
656
* \brief Determine whether this code generator guarantees resolved virtual
657
* dispatch under AOT with SVM.
658
*
659
* \return true if resolved virtual dispatch is guaranteed, false otherwise
660
* \see TR_J9VMBase::isResolvedVirtualDispatchGuaranteed
661
*/
662
bool guaranteesResolvedVirtualDispatchForSVM() { return false; } // safe default
663
664
private:
665
666
enum // Flags
667
{
668
HasFixedFrameC_CallingConvention = 0x00000001,
669
SupportsMaxPrecisionMilliTime = 0x00000002,
670
SupportsInlineStringCaseConversion = 0x00000004, /*! codegen inlining of Java string case conversion */
671
SupportsInlineStringIndexOf = 0x00000008, /*! codegen inlining of Java string index of */
672
SupportsInlineStringHashCode = 0x00000010, /*! codegen inlining of Java string hash code */
673
SupportsInlineConcurrentLinkedQueue = 0x00000020,
674
SupportsBigDecimalLongLookasideVersioning = 0x00000040,
675
SupportsInlineStringLatin1Inflate = 0x00000080, /*! codegen inlining of Java StringLatin1.inflate */
676
SupportsIntegerStringSize = 0x00000100,
677
SupportsIntegerToChars = 0x00000200,
678
SupportsInlineEncodeASCII = 0x00000400,
679
};
680
681
flags32_t _j9Flags;
682
};
683
}
684
685
#endif
686
687