Path: blob/master/runtime/compiler/codegen/J9CodeGenerator.hpp
6000 views
/*******************************************************************************1* Copyright (c) 2000, 2022 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#ifndef J9_CODEGENERATOR_INCL23#define J9_CODEGENERATOR_INCL2425/*26* The following #define and typedef must appear before any #includes in this file27*/28#ifndef J9_CODEGENERATOR_CONNECTOR29#define J9_CODEGENERATOR_CONNECTOR3031namespace J9 { class CodeGenerator; }32namespace J9 { typedef J9::CodeGenerator CodeGeneratorConnector; }33#endif3435#include "codegen/OMRCodeGenerator.hpp"3637#include <stdint.h>38#include "env/IO.hpp"39#include "env/jittypes.h"40#include "infra/List.hpp"41#include "infra/HashTab.hpp"42#include "codegen/RecognizedMethods.hpp"43#if defined(J9VM_OPT_JITSERVER)44#include "control/CompilationRuntime.hpp"45#endif /* defined(J9VM_OPT_JITSERVER) */46#include "control/Recompilation.hpp"47#include "control/RecompilationInfo.hpp"48#include "optimizer/Dominators.hpp"49#include "cs2/arrayof.h"5051class NVVMIRBuffer;52class TR_BitVector;53class TR_SharedMemoryAnnotations;54class TR_J9VMBase;55namespace TR { class Block; }56namespace TR { class Node; }57namespace TR { class SymbolReference; }58namespace TR { class TreeTop; }5960namespace J961{6263class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGeneratorConnector64{6566protected:6768CodeGenerator(TR::Compilation *comp);6970public:7172void initialize();7374TR_J9VMBase *fej9();7576TR::TreeTop *lowerTree(TR::Node *root, TR::TreeTop *treeTop);7778void preLowerTrees();7980void lowerTreesPreTreeTopVisit(TR::TreeTop *tt, vcount_t visitCount);8182void lowerTreesPreChildrenVisit(TR::Node * parent, TR::TreeTop * treeTop, vcount_t visitCount);8384void lowerTreeIfNeeded(TR::Node *node, int32_t childNumber, TR::Node *parent, TR::TreeTop *tt);8586void lowerDualOperator(TR::Node *parent, int32_t childNumber, TR::TreeTop *treeTop);8788public:8990bool collectSymRefs(TR::Node *node, TR_BitVector *symRefs, vcount_t secondVisitCount);9192void moveUpArrayLengthStores(TR::TreeTop *insertionPoint);9394void doInstructionSelection();9596void createReferenceReadBarrier(TR::TreeTop* treeTop, TR::Node* parent);9798TR::list<TR_Pair<TR_ResolvedMethod,TR::Instruction> *> &getJNICallSites() { return _jniCallSites; } // registerAssumptions()99100// OSR, not code generator101void populateOSRBuffer();102103void lowerCompressedRefs(TR::TreeTop *, TR::Node*, vcount_t, TR_BitVector *);104void compressedReferenceRematerialization(); // J9105void rematerializeCompressedRefs(TR::SymbolReference * &, TR::TreeTop *, TR::Node*, int32_t, TR::Node*, vcount_t, List<TR::Node> *);106void anchorRematNodesIfNeeded(TR::Node*, TR::TreeTop *, List<TR::Node> *);107void yankCompressedRefs(TR::TreeTop *, TR::Node *, int32_t, TR::Node *, vcount_t, vcount_t);108109void setUpForInstructionSelection();110111void insertEpilogueYieldPoints();112113void allocateLinkageRegisters();114115void fixUpProfiledInterfaceGuardTest();116117/**118* \brief119* This query is used by both fixUpProfiledInterfaceGuardTest (a codegen level optimization) and virtual guard evaluators120* to decide whether a NOP guard should be generated. It's used on all platforms and compilation phases so that the decision121* of generating VG NOPs is made in a consistent way.122*123* \param node124* the virtual guard node125*126* \return127* true if a NOP virtual guard should be generated. Otherwise, false.128*/129bool willGenerateNOPForVirtualGuard(TR::Node* node);130131void zeroOutAutoOnEdge(TR::SymbolReference * liveAutoSym, TR::Block *block, TR::Block *succBlock, TR::list<TR::Block*> *newBlocks, TR_ScratchList<TR::Node> *fsdStores);132133TR::Linkage *createLinkageForCompilation();134135bool enableAESInHardwareTransformations() {return false;}136137bool isMethodInAtomicLongGroup(TR::RecognizedMethod rm);138bool arithmeticNeedsLiteralFromPool(TR::Node *node) { return false; }139140// OSR141//142TR::TreeTop* genSymRefStoreToArray(TR::Node* refNode, TR::Node* arrayAddressNode, TR::Node* firstOffset,143TR::Node* symRefLoad, int32_t secondOffset, TR::TreeTop* insertionPoint);144145// --------------------------------------146// AOT Relocations147//148#if defined(J9VM_OPT_JITSERVER)149void addExternalRelocation(TR::Relocation *r, const char *generatingFileName, uintptr_t generatingLineNumber, TR::Node *node, TR::ExternalRelocationPositionRequest where = TR::ExternalRelocationAtBack);150void addExternalRelocation(TR::Relocation *r, TR::RelocationDebugInfo *info, TR::ExternalRelocationPositionRequest where = TR::ExternalRelocationAtBack);151#endif /* defined(J9VM_OPT_JITSERVER) */152153void processRelocations();154155//TR::ExternalRelocation156void addProjectSpecializedRelocation(uint8_t *location,157uint8_t *target,158uint8_t *target2, //pass in NULL when no target2159TR_ExternalRelocationTargetKind kind,160char *generatingFileName,161uintptr_t generatingLineNumber,162TR::Node *node);163//TR::ExternalOrderedPair32BitRelocation164void addProjectSpecializedPairRelocation(uint8_t *location1,165uint8_t *location2,166uint8_t *target,167TR_ExternalRelocationTargetKind kind,168char *generatingFileName,169uintptr_t generatingLineNumber,170TR::Node *node);171//TR::BeforeBinaryEncodingExternalRelocation172void addProjectSpecializedRelocation(TR::Instruction *instr,173uint8_t *target,174uint8_t *target2, //pass in NULL when no target2175TR_ExternalRelocationTargetKind kind,176char *generatingFileName,177uintptr_t generatingLineNumber,178TR::Node *node);179180bool needClassAndMethodPointerRelocations();181bool needRelocationsForLookupEvaluationData();182bool needRelocationsForStatics();183bool needRelocationsForHelpers();184bool needRelocationsForCurrentMethodPC();185#if defined(J9VM_OPT_JITSERVER)186bool needRelocationsForBodyInfoData();187bool needRelocationsForPersistentInfoData();188#endif /* defined(J9VM_OPT_JITSERVER) */189190// ----------------------------------------191TR::Node *createOrFindClonedNode(TR::Node *node, int32_t numChildren);192193void jitAddUnresolvedAddressMaterializationToPatchOnClassRedefinition(void *firstInstruction);194195uint32_t getStackLimitOffset() {return _stackLimitOffsetInMetaData;}196uint32_t setStackLimitOffset(uint32_t o) {return (_stackLimitOffsetInMetaData = o);}197198bool alwaysGeneratesAKnownCleanSign(TR::Node *node) { return false; } // no virt199bool alwaysGeneratesAKnownPositiveCleanSign(TR::Node *node) { return false; } // no virt200TR_RawBCDSignCode alwaysGeneratedSign(TR::Node *node) { return raw_bcd_sign_unknown; } // no virt201202void swapChildrenIfNeeded(TR::Node *store, char *optDetails);203204TR::AutomaticSymbol *allocateVariableSizeSymbol(int32_t size);205TR::SymbolReference *allocateVariableSizeSymRef(int32_t byteLength);206void pendingFreeVariableSizeSymRef(TR::SymbolReference *sym);207void freeVariableSizeSymRef(TR::SymbolReference *sym, bool freeAddressTakenSymbol=false);208void freeAllVariableSizeSymRefs();209210TR::SymbolReference *getFreeVariableSizeSymRef(int byteLength);211void checkForUnfreedVariableSizeSymRefs();212213bool allowGuardMerging();214void registerAssumptions();215216void jitAddPicToPatchOnClassUnload(void *classPointer, void *addressToBePatched);217void jitAdd32BitPicToPatchOnClassUnload(void *classPointer, void *addressToBePatched);218void jitAddPicToPatchOnClassRedefinition(void *classPointer, void *addressToBePatched, bool unresolved = false);219void jitAdd32BitPicToPatchOnClassRedefinition(void *classPointer, void *addressToBePatched, bool unresolved = false);220221void createHWPRecords();222223void createStackAtlas();224225// --------------------------------------------------------------------------226// GPU227//228static const int32_t GPUAlignment = 128;229uintptr_t objectLengthOffset();230uintptr_t objectHeaderInvariant();231232enum GPUScopeType233{234naturalLoopScope = 0,235singleKernelScope = 1236};237238enum GPUResult239{240GPUSuccess = 0,241GPUNullCheck = 1,242GPUBndCheck = 2,243GPUDivException = 3,244GPUInvalidProgram = 4,245GPUHelperError = 5,246GPULaunchError = 6,247GPUBadDevicePointer = 7248};249250enum GPUAccessKind {None = 0, ReadAccess= 1, WriteAccess = 2, ReadWriteAccesses = 3};251class gpuMapElement252{253public:254TR_ALLOC(TR_Memory::CodeGenerator); // dummy255256gpuMapElement() : _node(NULL), _hostSymRef(NULL), _hostSymRefTemp(NULL), _devSymRef(NULL), _hoistAccess(false), _elementSize(-1), _parmSlot(-1), _accessKind(None), _lhsAddrExpr(NULL), _rhsAddrExpr(NULL) {}257258gpuMapElement(TR::Node *node, TR::SymbolReference *hostSymRef, int32_t elementSize, int32_t parmSlot)259:260_node(node), _hostSymRef(hostSymRef), _hostSymRefTemp(NULL), _devSymRef(NULL), _hoistAccess(false),261_elementSize(elementSize), _parmSlot(parmSlot), _accessKind(None), _lhsAddrExpr(NULL), _rhsAddrExpr(NULL) {}262263TR::Node *_node;264TR::SymbolReference *_hostSymRef;265TR::SymbolReference *_hostSymRefTemp;266TR::SymbolReference *_devSymRef;267int32_t _elementSize;268int32_t _parmSlot;269uint32_t _accessKind;270bool _hoistAccess;271TR::Node *_rhsAddrExpr;272TR::Node *_lhsAddrExpr;273};274275class gpuParameter276{277public:278TR_ALLOC(TR_Memory::CodeGenerator); // dummy279280gpuParameter() : _hostSymRef(NULL), _parmSlot(-1) {}281282gpuParameter(TR::SymbolReference *hostSymRef, int32_t parmSlot)283: _hostSymRef(hostSymRef), _parmSlot(parmSlot) {}284285TR::SymbolReference *_hostSymRef;286int32_t _parmSlot;287};288289CS2::ArrayOf<gpuMapElement, TR::Allocator> _gpuSymbolMap;290291bool _gpuHasNullCheck;292bool _gpuHasBndCheck;293bool _gpuHasDivCheck;294295scount_t _gpuNodeCount;296TR::Block *_gpuCurrentBlock;297TR::DataTypes _gpuReturnType;298TR_Dominators *_gpuPostDominators;299TR::Block *_gpuStartBlock;300uint64_t _gpuNeedNullCheckArguments_vector;301bool _gpuCanUseReadOnlyCache;302bool _gpuUseOldLdgCalls;303304TR_BitVector *getLiveMonitors() {return _liveMonitors;}305TR_BitVector *setLiveMonitors(TR_BitVector *v) {return (_liveMonitors = v);}306307public:308/*309* \brief310* Get the most abstract type the monitor may be operating on.311*312* \note313* java.lang.Object is only returned when the monitor object is of type java.lang.Object but not any subclasses314*/315TR_OpaqueClassBlock* getMonClass(TR::Node* monNode);316317/*318* \brief319* Whether a monitor object is of value based class type or value type.320* This API checks if value based or value type is enabled first.321*322* \return323* TR_yes The monitor object is definitely value based class type or value type324* TR_no The monitor object is definitely not value based class type or value type325* TR_maybe It is unknown whether the monitor object is value based class type or value type326*/327TR_YesNoMaybe isMonitorValueBasedOrValueType(TR::Node* monNode);328329protected:330331typedef TR::typed_allocator<std::pair<const ncount_t , TR_OpaqueClassBlock*>, TR::Region &> MonitorMapAllocator;332typedef std::map<ncount_t , TR_OpaqueClassBlock *, std::less<ncount_t>, MonitorMapAllocator> MonitorTypeMap;333334MonitorTypeMap _monitorMapping; // map global node index to monitor object class335336void addMonClass(TR::Node* monNode, TR_OpaqueClassBlock* clazz);337338private:339340TR_HashTabInt _uncommonedNodes; // uncommoned nodes keyed by the original nodes341342TR::list<TR::Node*> _nodesSpineCheckedList;343344TR::list<TR_Pair<TR_ResolvedMethod, TR::Instruction> *> _jniCallSites; // list of instrutions representing direct jni call sites345346uint16_t changeParmLoadsToRegLoads(TR::Node*node, TR::Node **regLoads, TR_BitVector *globalRegsWithRegLoad, TR_BitVector &killedParms, vcount_t visitCount); // returns number of RegLoad nodes created347348static bool wantToPatchClassPointer(TR::Compilation *comp,349const TR_OpaqueClassBlock *allegedClassPointer,350const char *locationDescription,351const void *location)352{353// If we have a class pointer to consider, it should look like one.354const uintptr_t j9classEyecatcher = 0x99669966;355#if defined(J9VM_OPT_JITSERVER)356if (allegedClassPointer != NULL && !comp->isOutOfProcessCompilation())357#else358if (allegedClassPointer != NULL)359#endif /* defined(J9VM_OPT_JITSERVER) */360{361TR_ASSERT(*(const uintptr_t*)allegedClassPointer == j9classEyecatcher,362"expected a J9Class* for omitted runtime assumption");363}364365// Class pointer patching is restricted to HCR mode.366if (!comp->getOption(TR_EnableHCR))367return false;368369// -Xjit:HCRPatchClassPointers re-enables all class pointer assumptions370if (comp->getOption(TR_HCRPatchClassPointers))371return true;372373return !performTransformation(comp,374"O^O OMIT HCR CLASS POINTER ASSUMPTION: class=" POINTER_PRINTF_FORMAT ", %s " POINTER_PRINTF_FORMAT "\n", allegedClassPointer,375locationDescription,376location);377}378379uint32_t _stackLimitOffsetInMetaData;380381/*382* Scratch data for refined aliasing walk during383*/384struct RefinedAliasWalkCollector385{386TR_PersistentMethodInfo *methodInfo;387bool killsEverything;388bool killsAddressStatics;389bool killsIntStatics;390bool killsNonIntPrimitiveStatics;391bool killsAddressFields;392bool killsIntFields;393bool killsNonIntPrimitiveFields;394bool killsAddressArrayShadows;395bool killsIntArrayShadows;396bool killsNonIntPrimitiveArrayShadows;397};398399RefinedAliasWalkCollector _refinedAliasWalkCollector;400401TR_BitVector *_liveMonitors;402403protected:404405// isTemporaryBased storageReferences just have a symRef but some other routines expect a node so use the below to fill in this symRef on this node406TR::Node *_dummyTempStorageRefNode;407408public:409410static bool wantToPatchClassPointer(TR::Compilation *comp,411const TR_OpaqueClassBlock *allegedClassPointer,412const uint8_t *inCodeAt);413414bool wantToPatchClassPointer(const TR_OpaqueClassBlock *allegedClassPointer, const uint8_t *inCodeAt);415416bool wantToPatchClassPointer(const TR_OpaqueClassBlock *allegedClassPointer, const TR::Node *forNode);417418bool getSupportsBigDecimalLongLookasideVersioning() { return _flags3.testAny(SupportsBigDecimalLongLookasideVersioning);}419void setSupportsBigDecimalLongLookasideVersioning() { _flags3.set(SupportsBigDecimalLongLookasideVersioning);}420421bool constLoadNeedsLiteralFromPool(TR::Node *node) { return false; }422423// Java, likely Z424bool supportsTrapsInTMRegion() { return true; }425426// J9427int32_t getInternalPtrMapBit() { return 31;}428429// --------------------------------------------------------------------------430// GPU431//432void generateGPU();433434void dumpInvariant(CS2::ArrayOf<gpuParameter, TR::Allocator>::Cursor pit, NVVMIRBuffer &ir, bool isbufferalign);435436GPUResult 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);437438GPUResult printNVVMIR(NVVMIRBuffer &ir, TR::Node * node, TR_RegionStructure *loop, TR_BitVector *targetBlocks, vcount_t visitCount, TR_SharedMemoryAnnotations *sharedMemory, int32_t &nextParmNum, TR::Node * &errorNode);439440void findExtraParms(TR::Node *node, int32_t &numExtraParms, TR_SharedMemoryAnnotations *sharedMemory, vcount_t visitCount);441442bool handleRecognizedMethod(TR::Node *node, NVVMIRBuffer &ir, TR::Compilation *comp);443444bool handleRecognizedField(TR::Node *node, NVVMIRBuffer &ir);445446void printArrayCopyNVVMIR(TR::Node *node, NVVMIRBuffer &ir, TR::Compilation *comp);447448449bool hasFixedFrameC_CallingConvention() {return _j9Flags.testAny(HasFixedFrameC_CallingConvention);}450void setHasFixedFrameC_CallingConvention() {_j9Flags.set(HasFixedFrameC_CallingConvention);}451452bool supportsJitMethodEntryAlignment();453454/** \brief455* Determines whether the code generator supports inlining of java/lang/Class.isAssignableFrom456*/457bool supportsInliningOfIsAssignableFrom() { return false; } // no virt, default458459/** \brief460* Determines whether the code generator must generate the switch to interpreter snippet in the preprologue.461*/462bool mustGenerateSwitchToInterpreterPrePrologue();463464bool buildInterpreterEntryPoint() { return true; }465void generateCatchBlockBBStartPrologue(TR::Node *node, TR::Instruction *fenceInstruction);466bool supportsUnneededLabelRemoval() { return false; }467468// Determines whether high-resolution timer can be used to implement java/lang/System.currentTimeMillis()469bool getSupportsMaxPrecisionMilliTime() {return _j9Flags.testAny(SupportsMaxPrecisionMilliTime);}470void setSupportsMaxPrecisionMilliTime() {_j9Flags.set(SupportsMaxPrecisionMilliTime);}471472/** \brief473* Determines whether the code generator supports inlining of java/lang/String.toUpperCase() and toLowerCase()474*/475bool getSupportsInlineStringCaseConversion() { return _j9Flags.testAny(SupportsInlineStringCaseConversion);}476/** \brief477* The code generator supports inlining of java/lang/String.toUpperCase() and toLowerCase()478*/479void setSupportsInlineStringCaseConversion() { _j9Flags.set(SupportsInlineStringCaseConversion);}480481/** \brief482* Determines whether the code generator supports inlining of java/lang/String.indexOf()483*/484bool getSupportsInlineStringIndexOf() { return _j9Flags.testAny(SupportsInlineStringIndexOf);}485486/** \brief487* The code generator supports inlining of java/lang/String.indexOf()488*/489void setSupportsInlineStringIndexOf() { _j9Flags.set(SupportsInlineStringIndexOf);}490491/** \brief492* Determines whether the code generator supports inlining of java/lang/String.hashCode()493*/494bool getSupportsInlineStringHashCode() { return _j9Flags.testAny(SupportsInlineStringHashCode); }495496/** \brief497* The code generator supports inlining of java/lang/String.hashCode()498*/499void setSupportsInlineStringHashCode() { _j9Flags.set(SupportsInlineStringHashCode); }500501/** \brief502* Determines whether the code generator supports inlining of java/lang/StringLatin1.inflate503*/504bool getSupportsInlineStringLatin1Inflate() { return _j9Flags.testAny(SupportsInlineStringLatin1Inflate); }505506/** \brief507* The code generator supports inlining of java/lang/StringLatin1.inflate508*/509void setSupportsInlineStringLatin1Inflate() { _j9Flags.set(SupportsInlineStringLatin1Inflate); }510511/** \brief512* Determines whether the code generator supports inlining of java_util_concurrent_ConcurrentLinkedQueue_tm*513* methods514*/515bool getSupportsInlineConcurrentLinkedQueue() { return _j9Flags.testAny(SupportsInlineConcurrentLinkedQueue); }516517/** \brief518* The code generator supports inlining of java_util_concurrent_ConcurrentLinkedQueue_tm* methods519*/520void setSupportsInlineConcurrentLinkedQueue() { _j9Flags.set(SupportsInlineConcurrentLinkedQueue); }521522/** \brief523* Determines whether the code generator supports inlining of java/lang/StringCoding.encodeASCII524*/525bool getSupportsInlineEncodeASCII() { return _j9Flags.testAny(SupportsInlineEncodeASCII); }526527/** \brief528* The code generator supports inlining of java/lang/StringCoding.encodeASCII529*/530void setSupportsInlineEncodeASCII() { _j9Flags.set(SupportsInlineEncodeASCII); }531532/**533* \brief534* The number of nodes between a monext and the next monent before535* transforming a monitored region with transactional lock elision.536*/537int32_t getMinimumNumberOfNodesBetweenMonitorsForTLE() { return 15; }538539/**540* \brief Trim the size of code memory required by this method to match the541* actual code length required, allowing the reclaimed memory to be542* reused. This is needed when the conservative length estimate543* exceeds the actual memory requirement.544*/545void trimCodeMemoryToActualSize();546547548/**549* \brief Request and reserve a CodeCache for use by this compilation. Fail550* the compilation appropriately if a CodeCache cannot be allocated.551*/552void reserveCodeCache();553554555/**556* \brief Allocates code memory of the specified size in the specified area of557* the code cache. Fail the compilation on failure.558*559* \param[in] warmCodeSizeInBytes : the number of bytes to allocate in the warm area560* \param[in] coldCodeSizeInBytes : the number of bytes to allocate in the cold area561* \param[out] coldCode : address of the cold code (if allocated)562* \param[in] isMethodHeaderNeeded : boolean indicating whether space for a563* method header must be allocated564*565* \return address of the allocated warm code (if allocated)566*/567uint8_t *allocateCodeMemoryInner(568uint32_t warmCodeSizeInBytes,569uint32_t coldCodeSizeInBytes,570uint8_t **coldCode,571bool isMethodHeaderNeeded);572573574/**575* \brief Store a poison value in an auto slot that should have gone dead. Used for debugging.576*577* \param[in] currentBlock : block in which the auto slot appears578* \param[in] liveAutoSymRef : SymbolReference of auto slot to poison579*580* \return poisoned store node581*/582TR::Node *generatePoisonNode(583TR::Block *currentBlock,584TR::SymbolReference *liveAutoSymRef);585586587/**588* \brief Determines whether VM Internal Natives is supported or not589*/590bool supportVMInternalNatives();591592593/**594* \brief Determines whether the code generator supports stack allocations595*/596bool supportsStackAllocations() { return false; }597598/**599* \brief Initializes the Linkage Info word found before the interpreter entry point.600*601* \param[in] linkageInfo : pointer to the linkage info word602*603* \return Linkage Info word604*/605uint32_t initializeLinkageInfo(void *linkageInfoPtr);606607/**608* \brief Check if a profiled class is compatible with the call site609*610* \param[in] profiledClass : The J9Class obtained from profiling data611* \param[in] callSiteMethodClass : The J9Class from the J9Method of the call site target612*613* \return True if it can be determined that the profiled class is compatible, otherwise False614*/615bool isProfiledClassAndCallSiteCompatible(TR_OpaqueClassBlock *profiledClass, TR_OpaqueClassBlock *callSiteMethodClass);616617/** \brief618* Determines whether the code generator supports inlining of java/lang/Integer.stringSize() or java/lang/Long.stringSize()619*/620bool getSupportsIntegerStringSize() { return _j9Flags.testAny(SupportsIntegerStringSize); }621622/** \brief623* The code generator supports inlining of java/lang/Integer.stringSize() or java/lang/Long.stringSize()624*/625void setSupportsIntegerStringSize() {_j9Flags.set(SupportsIntegerStringSize); }626627/** \brief628* Determines whether the code generator supports inlining of629* - Integer.getChars,630* - Long.getChars,631* - StringUTF16.getChars(JI[B)I,632* - StringUTF16.getChars(II[B)I633*/634bool getSupportsIntegerToChars() { return _j9Flags.testAny(SupportsIntegerToChars); }635636/** \brief637* The code generator supports inlining of638* - Integer.getChars,639* - Long.getChars,640* - StringUTF16.getChars(JI[B)I,641* - StringUTF16.getChars(II[B)I642*/643void setSupportsIntegerToChars() {_j9Flags.set(SupportsIntegerToChars); }644645/**646* \brief Determine whether this code generator guarantees resolved direct647* dispatch under AOT with SVM.648*649* \return true if resolved direct dispatch is guaranteed, false otherwise650* \see TR_J9VMBase::isResolvedDirectDispatchGuaranteed651*/652bool guaranteesResolvedDirectDispatchForSVM() { return false; } // safe default653654/**655* \brief Determine whether this code generator guarantees resolved virtual656* dispatch under AOT with SVM.657*658* \return true if resolved virtual dispatch is guaranteed, false otherwise659* \see TR_J9VMBase::isResolvedVirtualDispatchGuaranteed660*/661bool guaranteesResolvedVirtualDispatchForSVM() { return false; } // safe default662663private:664665enum // Flags666{667HasFixedFrameC_CallingConvention = 0x00000001,668SupportsMaxPrecisionMilliTime = 0x00000002,669SupportsInlineStringCaseConversion = 0x00000004, /*! codegen inlining of Java string case conversion */670SupportsInlineStringIndexOf = 0x00000008, /*! codegen inlining of Java string index of */671SupportsInlineStringHashCode = 0x00000010, /*! codegen inlining of Java string hash code */672SupportsInlineConcurrentLinkedQueue = 0x00000020,673SupportsBigDecimalLongLookasideVersioning = 0x00000040,674SupportsInlineStringLatin1Inflate = 0x00000080, /*! codegen inlining of Java StringLatin1.inflate */675SupportsIntegerStringSize = 0x00000100,676SupportsIntegerToChars = 0x00000200,677SupportsInlineEncodeASCII = 0x00000400,678};679680flags32_t _j9Flags;681};682}683684#endif685686687