Path: blob/master/runtime/compiler/compile/J9SymbolReferenceTable.cpp
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#include "omrformatconsts.h"23#include "codegen/CodeGenerator.hpp"24#include "env/KnownObjectTable.hpp"25#include "compile/AliasBuilder.hpp"26#include "compile/Compilation.hpp"27#include "compile/Method.hpp"28#include "compile/ResolvedMethod.hpp"29#include "compile/SymbolReferenceTable.hpp"30#include "cs2/hashtab.h"31#include "env/CHTable.hpp"32#include "env/CompilerEnv.hpp"33#include "env/PersistentInfo.hpp"34#include "env/StackMemoryRegion.hpp"35#include "env/TRMemory.hpp"36#include "env/VMAccessCriticalSection.hpp"37#include "env/VMJ9.h"38#include "env/j9method.h"39#include "env/jittypes.h"40#include "il/StaticSymbol.hpp"41#include "il/StaticSymbol_inlines.hpp"42#include "il/ParameterSymbol.hpp"43#include "il/RegisterMappedSymbol.hpp"44#include "il/ResolvedMethodSymbol.hpp"45#include "il/SymbolReference.hpp"46#include "ilgen/IlGen.hpp"47#include "ilgen/J9ByteCodeIlGenerator.hpp"48#include "infra/Assert.hpp"49#include "infra/BitVector.hpp"50#include "infra/List.hpp"51#include "infra/String.hpp"52#include "runtime/RuntimeAssumptions.hpp"53#include "env/PersistentCHTable.hpp"54#include "optimizer/TransformUtil.hpp"55#if defined(J9VM_OPT_JITSERVER)56#include "env/j9methodServer.hpp"57#endif /* defined(J9VM_OPT_JITSERVER) */5859namespace J960{61enum NonUserMethod62{63unknownNonUserMethod,64nonUser_java_util_HashMap_rehash,65nonUser_java_util_HashMap_analyzeMap,66nonUser_java_util_HashMap_calculateCapacity,67nonUser_java_util_HashMap_findNullKeyEntry,6869numNonUserMethods70};71}727374J9::SymbolReferenceTable::SymbolReferenceTable(size_t sizeHint, TR::Compilation *c) :75OMR::SymbolReferenceTableConnector(sizeHint, c),76_immutableInfo(c->trMemory()),77_immutableSymRefNumbers(c->trMemory(), _numImmutableClasses),78_dynamicMethodSymrefsByCallSiteIndex(c->trMemory()),79_unsafeJavaStaticSymRefs(NULL),80_unsafeJavaStaticVolatileSymRefs(NULL),81_currentThreadDebugEventDataSymbol(0),82_currentThreadDebugEventDataSymbolRefs(c->trMemory()),83_constantPoolAddressSymbolRefs(c->trMemory()),84_resolvedFieldShadows(85std::less<ResolvedFieldShadowKey>(),86getTypedAllocator<ResolvedFieldShadowsEntry>(c->allocator())),87_flattenedArrayElementFieldShadows(88std::less<ResolvedFieldShadowKey>(),89getTypedAllocator<FlattenedArrayElementFieldShadowsEntry>(c->allocator()))90{91for (uint32_t i = 0; i < _numImmutableClasses; i++)92_immutableSymRefNumbers[i] = new (trHeapMemory()) TR_BitVector(sizeHint, c->trMemory(), heapAlloc, growable);93}949596TR::SymbolReference *97J9::SymbolReferenceTable::findOrCreateCountForRecompileSymbolRef()98{99if (!element(countForRecompileSymbol))100{101TR::StaticSymbol * sym = TR::StaticSymbol::create(trHeapMemory(),TR::Int32);102TR::PersistentInfo *pinfo = comp()->getPersistentInfo();103sym->setStaticAddress(&(pinfo->_countForRecompile));104sym->setCountForRecompile();105sym->setNotDataAddress();106element(countForRecompileSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), countForRecompileSymbol, sym);107}108return element(countForRecompileSymbol);109}110111112TR::SymbolReference *113J9::SymbolReferenceTable::findOrCreateOSRBufferSymbolRef()114{115if (!element(osrBufferSymbol))116{117TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());118TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "OSRBuffer");119sym->setDataType(TR::Address);120sym->setNotCollected();121element(osrBufferSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), osrBufferSymbol, sym);122element(osrBufferSymbol)->setOffset(fej9->thisThreadGetOSRBufferOffset());123124// We can't let the load/store of the exception symbol swing down125aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(osrBufferSymbol)); // add the symRef to the statics list to get correct aliasing info126}127return element(osrBufferSymbol);128}129130131TR::SymbolReference *132J9::SymbolReferenceTable::findOrCreateOSRScratchBufferSymbolRef()133{134if (!element(osrScratchBufferSymbol))135{136TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());137TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "OSRScratchBuffer");138sym->setDataType(TR::Address);139sym->setNotCollected();140element(osrScratchBufferSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), osrScratchBufferSymbol, sym);141element(osrScratchBufferSymbol)->setOffset(fej9->thisThreadGetOSRScratchBufferOffset());142143// We can't let the load/store of the exception symbol swing down144aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(osrScratchBufferSymbol)); // add the symRef to the statics list to get correct aliasing info145}146return element(osrScratchBufferSymbol);147}148149150TR::SymbolReference *151J9::SymbolReferenceTable::findOrCreateOSRFrameIndexSymbolRef()152{153if (!element(osrFrameIndexSymbol))154{155TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());156TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "osrFrameIndex");157sym->setDataType(TR::Int32);158element(osrFrameIndexSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), osrFrameIndexSymbol, sym);159element(osrFrameIndexSymbol)->setOffset(fej9->thisThreadGetOSRFrameIndexOffset());160161// We can't let the load/store of the exception symbol swing down162//SD: do we need this?163aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(osrFrameIndexSymbol)); // add the symRef to the statics list to get correct aliasing info164}165return element(osrFrameIndexSymbol);166}167168169TR::SymbolReference *170J9::SymbolReferenceTable::findOrCreateAcquireVMAccessSymbolRef(TR::ResolvedMethodSymbol *)171{172return findOrCreateRuntimeHelper(TR_acquireVMAccess, true, false, true);173}174175176TR::SymbolReference *177J9::SymbolReferenceTable::findOrCreateThrowCurrentExceptionSymbolRef(TR::ResolvedMethodSymbol *)178{179return findOrCreateRuntimeHelper(TR_throwCurrentException, true, false, true);180}181182TR::SymbolReference *183J9::SymbolReferenceTable::findOrCreateThrowUnreportedExceptionSymbolRef(TR::ResolvedMethodSymbol *)184{185return findOrCreateRuntimeHelper(TR_throwUnreportedException, true /* canGCandReturn */, false /* canGCandExcept */, true /* preservesAllRegisters */);186}187188TR::SymbolReference *189J9::SymbolReferenceTable::findOrCreateReleaseVMAccessSymbolRef(TR::ResolvedMethodSymbol *)190{191return findOrCreateRuntimeHelper(TR_releaseVMAccess, true, false, true);192}193194195TR::SymbolReference *196J9::SymbolReferenceTable::findOrCreateStackOverflowSymbolRef(TR::ResolvedMethodSymbol *)197{198return findOrCreateRuntimeHelper(TR_stackOverflow, true, true, true);199}200201202TR::SymbolReference *203J9::SymbolReferenceTable::findOrCreateWriteBarrierStoreSymbolRef(TR::ResolvedMethodSymbol *)204{205return findOrCreateRuntimeHelper(TR_writeBarrierStore, false, false, true);206}207208209TR::SymbolReference *210J9::SymbolReferenceTable::findOrCreateWriteBarrierStoreGenerationalSymbolRef(TR::ResolvedMethodSymbol *)211{212return findOrCreateRuntimeHelper(TR_writeBarrierStoreGenerational, false, false, true);213}214215216TR::SymbolReference *217J9::SymbolReferenceTable::findOrCreateWriteBarrierStoreGenerationalAndConcurrentMarkSymbolRef(TR::ResolvedMethodSymbol *)218{219return findOrCreateRuntimeHelper(TR_writeBarrierStoreGenerationalAndConcurrentMark, false, false, true);220}221222223TR::SymbolReference *224J9::SymbolReferenceTable::findOrCreateWriteBarrierStoreRealTimeGCSymbolRef(TR::ResolvedMethodSymbol *)225{226return findOrCreateRuntimeHelper(TR_writeBarrierStoreRealTimeGC, true, true, true);227}228229230TR::SymbolReference *231J9::SymbolReferenceTable::findOrCreateWriteBarrierClassStoreRealTimeGCSymbolRef(TR::ResolvedMethodSymbol *)232{233return findOrCreateRuntimeHelper(TR_writeBarrierClassStoreRealTimeGC, true, true, true);234}235236237TR::SymbolReference *238J9::SymbolReferenceTable::findOrCreateWriteBarrierBatchStoreSymbolRef(TR::ResolvedMethodSymbol *)239{240return findOrCreateRuntimeHelper(TR_writeBarrierBatchStore, false, false, true);241}242243244TR::SymbolReference *245J9::SymbolReferenceTable::findOrCreateAcmpeqHelperSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)246{247return findOrCreateRuntimeHelper(TR_acmpeqHelper, true, false, true);248}249250251TR::SymbolReference *252J9::SymbolReferenceTable::findOrCreateAcmpneHelperSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)253{254return findOrCreateRuntimeHelper(TR_acmpneHelper, true, false, true);255}256257258TR::SymbolReference *259J9::SymbolReferenceTable::findOrCreateGetFlattenableFieldSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)260{261return findOrCreateRuntimeHelper(TR_getFlattenableField, true, true, true);262}263264265TR::SymbolReference *266J9::SymbolReferenceTable::findOrCreateWithFlattenableFieldSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)267{268return findOrCreateRuntimeHelper(TR_withFlattenableField, true, true, true);269}270271272TR::SymbolReference *273J9::SymbolReferenceTable::findOrCreatePutFlattenableFieldSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)274{275return findOrCreateRuntimeHelper(TR_putFlattenableField, true, true, true);276}277278279TR::SymbolReference *280J9::SymbolReferenceTable::findOrCreateGetFlattenableStaticFieldSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)281{282return findOrCreateRuntimeHelper(TR_getFlattenableStaticField, true, true, true);283}284285286TR::SymbolReference *287J9::SymbolReferenceTable::findOrCreatePutFlattenableStaticFieldSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)288{289return findOrCreateRuntimeHelper(TR_putFlattenableStaticField, true, true, true);290}291292293TR::SymbolReference *294J9::SymbolReferenceTable::findOrCreateLoadFlattenableArrayElementSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)295{296return findOrCreateRuntimeHelper(TR_ldFlattenableArrayElement, true, true, true);297}298299300TR::SymbolReference *301J9::SymbolReferenceTable::findOrCreateStoreFlattenableArrayElementSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)302{303return findOrCreateRuntimeHelper(TR_strFlattenableArrayElement, true, true, true);304}305306307TR::SymbolReference *308J9::SymbolReferenceTable::findOrCreateLookupDynamicInterfaceMethodSymbolRef()309{310return findOrCreateRuntimeHelper(TR_jitLookupDynamicInterfaceMethod, false, false, true);311}312313314TR::SymbolReference *315J9::SymbolReferenceTable::findOrCreateLookupDynamicPublicInterfaceMethodSymbolRef()316{317return findOrCreateRuntimeHelper(TR_jitLookupDynamicPublicInterfaceMethod, false, true, true);318}319320321TR::SymbolReference *322J9::SymbolReferenceTable::findOrCreateFloatSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)323{324void * dataAddress = owningMethodSymbol->getResolvedMethod()->floatConstant(cpIndex);325TR::SymbolReference * symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Float, true, dataAddress);326symRef->getSymbol()->setConst();327return symRef;328}329330331TR::SymbolReference *332J9::SymbolReferenceTable::findOrCreateDoubleSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)333{334void * dataAddress = owningMethodSymbol->getResolvedMethod()->doubleConstant(cpIndex, trMemory());335TR::SymbolReference * symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Double, true, dataAddress);336symRef->getSymbol()->setConst();337return symRef;338}339340341TR::SymbolReference *342J9::SymbolReferenceTable::createSystemRuntimeHelper(343TR_RuntimeHelper index,344bool canGCandReturn,345bool canGCandExcept,346bool preservesAllRegisters)347{348TR::SymbolReference * symRef = createRuntimeHelper(index,false,false,false);349if (symRef)350{351symRef->getSymbol()->castToMethodSymbol()->setSystemLinkageDispatch();352symRef->getSymbol()->castToMethodSymbol()->setLinkage(TR_System);353}354return symRef;355}356357TR::SymbolReference *358J9::SymbolReferenceTable::findOrCreateConstantPoolAddressSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)359{360TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());361void *cpAddress = owningMethodSymbol->getResolvedMethod()->constantPool();362ListIterator<TR::SymbolReference> i(&_constantPoolAddressSymbolRefs);363TR::SymbolReference * symRef;364for (symRef = i.getFirst(); symRef; symRef = i.getNext())365if (symRef->getSymbol()->getStaticSymbol()->getStaticAddress() == cpAddress)366return symRef;367368TR::StaticSymbol * sym = TR::StaticSymbol::create(trHeapMemory(),TR::Address);369sym->setStaticAddress(cpAddress);370sym->setConstantPoolAddress();371sym->setNotCollected();372sym->setNotDataAddress();373374symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1);375_constantPoolAddressSymbolRefs.add(symRef);376return symRef;377}378379TR::SymbolReference *380J9::SymbolReferenceTable::findOrCreateStaticMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)381{382bool isUnresolvedInCP;383TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedStaticMethod(comp(), cpIndex, &isUnresolvedInCP);384if (method)385owningMethodSymbol->setMayHaveInlineableCall(true);386387return findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::Static, isUnresolvedInCP);388}389390391TR::SymbolReference *392J9::SymbolReferenceTable::findOrCreateSpecialMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)393{394bool isUnresolvedInCP;395TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedSpecialMethod(comp(), cpIndex, &isUnresolvedInCP);396if (method)397owningMethodSymbol->setMayHaveInlineableCall(true);398399return findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::Special, isUnresolvedInCP);400}401402403TR::SymbolReference *404J9::SymbolReferenceTable::findOrCreateVirtualMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)405{406bool isUnresolvedInCP;407TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedVirtualMethod(comp(), cpIndex, false, &isUnresolvedInCP);408if (method)409owningMethodSymbol->setMayHaveInlineableCall(true);410411return findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::Virtual, false); //isUnresolvedInCP);412}413414415TR::SymbolReference *416J9::SymbolReferenceTable::findOrCreateInterfaceMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)417{418owningMethodSymbol->setMayHaveInlineableCall(true);419420TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, 0, TR::MethodSymbol::Interface);421422// javasoft.sqe.tests.vm.instr.invokeinterface.invokeinterface019.invokeinterface01910m1.invokeinterface01910m1423// has an invoke interface on a final method in object.424//425if (symRef->getSymbol()->castToMethodSymbol()->getMethod()->isFinalInObject())426{427comp()->failCompilation<TR::CompilationException>("Method symbol reference is final in object");428}429430return symRef;431}432433434TR::SymbolReference *435J9::SymbolReferenceTable::findOrCreateDynamicMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t callSiteIndex, bool * unresolvedInCP)436{437#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)438TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedDynamicMethod(comp(), callSiteIndex, unresolvedInCP);439if (method)440owningMethodSymbol->setMayHaveInlineableCall(true);441442TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), -1, method, TR::MethodSymbol::Static);443#else444List<TR::SymbolReference> *methods = dynamicMethodSymrefsByCallSiteIndex(callSiteIndex);445ListIterator<TR::SymbolReference> li(methods);446for (TR::SymbolReference *symRef = li.getFirst(); symRef; symRef = li.getNext())447{448if (symRef->getOwningMethodIndex() == owningMethodSymbol->getResolvedMethodIndex())449return symRef;450}451TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedDynamicMethod(comp(), callSiteIndex, unresolvedInCP);452TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), -1, method, TR::MethodSymbol::ComputedVirtual);453methods->add(symRef);454#endif /* J9VM_OPT_OPENJDK_METHODHANDLE */455return symRef;456}457458459TR::SymbolReference *460J9::SymbolReferenceTable::findOrCreateHandleMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, char *signature)461{462TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedHandleMethodWithSignature(comp(), cpIndex, signature);463if (method)464owningMethodSymbol->setMayHaveInlineableCall(true);465466TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::ComputedVirtual);467return symRef;468}469470471TR::SymbolReference *472J9::SymbolReferenceTable::findOrCreateHandleMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, bool * unresolvedInCP)473{474TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedHandleMethod(comp(), cpIndex, unresolvedInCP);475if (method)476owningMethodSymbol->setMayHaveInlineableCall(true);477478#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)479TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::Static);480#else481TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::ComputedVirtual);482#endif /* J9VM_OPT_OPENJDK_METHODHANDLE */483return symRef;484}485486487TR::SymbolReference *488J9::SymbolReferenceTable::findOrCreateCallSiteTableEntrySymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t callSiteIndex)489{490TR::SymbolReference *symRef;491TR_SymRefIterator i(aliasBuilder.callSiteTableEntrySymRefs(), self());492TR_ResolvedMethod *owningMethod = owningMethodSymbol->getResolvedMethod();493void *entryLocation = owningMethod->callSiteTableEntryAddress(callSiteIndex);494for (symRef = i.getNext(); symRef; symRef = i.getNext())495if ( owningMethodSymbol->getResolvedMethodIndex() == symRef->getOwningMethodIndex()496&& symRef->getSymbol()->castToStaticSymbol()->getStaticAddress() == entryLocation)497{498return symRef;499}500501TR::StaticSymbol *sym = TR::StaticSymbol::create(trHeapMemory(),TR::Address);502sym->makeCallSiteTableEntry(callSiteIndex);503sym->setStaticAddress(entryLocation);504bool isUnresolved = owningMethod->isUnresolvedCallSiteTableEntry(callSiteIndex);505506TR::KnownObjectTable::Index knownObjectIndex = TR::KnownObjectTable::UNKNOWN;507if (!isUnresolved)508{509TR::KnownObjectTable *knot = comp()->getOrCreateKnownObjectTable();510if (knot)511#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)512knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)entryLocation, true);513#else514knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)entryLocation);515#endif516}517518symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1,519(isUnresolved ? _numUnresolvedSymbols++ : 0), knownObjectIndex);520521if (isUnresolved)522{523// Resolving call site table entries causes java code to run524symRef->setUnresolved();525symRef->setCanGCandReturn();526symRef->setCanGCandExcept();527}528529aliasBuilder.callSiteTableEntrySymRefs().set(symRef->getReferenceNumber());530return symRef;531}532533TR::SymbolReference *534J9::SymbolReferenceTable::findOrCreateMethodTypeTableEntrySymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)535{536TR::SymbolReference *symRef;537TR_SymRefIterator i(aliasBuilder.methodTypeTableEntrySymRefs(), self());538TR_ResolvedMethod *owningMethod = owningMethodSymbol->getResolvedMethod();539void *entryLocation = owningMethod->methodTypeTableEntryAddress(cpIndex);540for (symRef = i.getNext(); symRef; symRef = i.getNext())541if ( owningMethodSymbol->getResolvedMethodIndex() == symRef->getOwningMethodIndex()542&& symRef->getSymbol()->castToStaticSymbol()->getStaticAddress() == entryLocation)543{544return symRef;545}546547TR::StaticSymbol *sym = TR::StaticSymbol::createMethodTypeTableEntry(trHeapMemory(),cpIndex);548sym->setStaticAddress(entryLocation);549bool isUnresolved = owningMethod->isUnresolvedMethodTypeTableEntry(cpIndex);550551TR::KnownObjectTable::Index knownObjectIndex = TR::KnownObjectTable::UNKNOWN;552if (!isUnresolved)553{554TR::KnownObjectTable *knot = comp()->getOrCreateKnownObjectTable();555if (knot)556#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)557knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)entryLocation, true);558#else559knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)entryLocation);560#endif561}562563symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1,564(isUnresolved ? _numUnresolvedSymbols++ : 0), knownObjectIndex);565566if (isUnresolved)567{568// Resolving method type table entries causes java code to run569symRef->setUnresolved();570symRef->setCanGCandReturn();571symRef->setCanGCandExcept();572}573574aliasBuilder.methodTypeTableEntrySymRefs().set(symRef->getReferenceNumber());575return symRef;576}577578#if defined(J9VM_OPT_METHOD_HANDLE)579TR::SymbolReference *580J9::SymbolReferenceTable::findOrCreateVarHandleMethodTypeTableEntrySymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)581{582// This function does the same thing as what findOrCreateMethodTypeTableEntrySymbol does except the way it gets the method type table entry address583TR::SymbolReference *symRef;584TR_SymRefIterator i(aliasBuilder.methodTypeTableEntrySymRefs(), self());585TR_ResolvedJ9Method *owningMethod = (TR_ResolvedJ9Method*)(owningMethodSymbol->getResolvedMethod());586void *entryLocation = owningMethod->varHandleMethodTypeTableEntryAddress(cpIndex);587for (symRef = i.getNext(); symRef; symRef = i.getNext())588if ( owningMethodSymbol->getResolvedMethodIndex() == symRef->getOwningMethodIndex()589&& symRef->getSymbol()->castToStaticSymbol()->getStaticAddress() == entryLocation)590{591return symRef;592}593594TR::StaticSymbol *sym = TR::StaticSymbol::createMethodTypeTableEntry(trHeapMemory(),cpIndex);595sym->setStaticAddress(entryLocation);596bool isUnresolved = owningMethod->isUnresolvedVarHandleMethodTypeTableEntry(cpIndex);597symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1,598isUnresolved ? _numUnresolvedSymbols++ : 0);599if (isUnresolved)600{601// Resolving method type table entries causes java code to run602symRef->setUnresolved();603symRef->setCanGCandReturn();604symRef->setCanGCandExcept();605}606607aliasBuilder.methodTypeTableEntrySymRefs().set(symRef->getReferenceNumber());608return symRef;609}610#endif /* defined(J9VM_OPT_METHOD_HANDLE) */611612613TR::SymbolReference *614J9::SymbolReferenceTable::methodSymRefWithSignature(TR::SymbolReference *originalSymRef, char *effectiveSignature, int32_t effectiveSignatureLength)615{616TR::ResolvedMethodSymbol *originalSymbol = originalSymRef->getSymbol()->castToResolvedMethodSymbol();617TR_ASSERT(originalSymbol, "methodSymRefWithSignature requires a resolved method symref");618TR_ASSERT(!originalSymbol->isVirtual(), "methodSymRefFromName doesn't support virtual methods"); // Until we're able to look up vtable index619int32_t cpIndex = originalSymRef->getCPIndex();620621// Check _methodsBySignature to see if we've already created a symref for this one622//623TR::Method *originalMethod = originalSymbol->getMethod();624625TR::StackMemoryRegion stackMemoryRegion(*trMemory());626627int32_t fullSignatureLength = originalMethod->classNameLength() + 1 + originalMethod->nameLength() + effectiveSignatureLength;628char *fullSignature = (char*)trMemory()->allocateMemory(1 + fullSignatureLength, stackAlloc);629sprintf(fullSignature, "%.*s.%.*s%.*s", originalMethod->classNameLength(), originalMethod->classNameChars(), originalMethod->nameLength(), originalMethod->nameChars(), effectiveSignatureLength, effectiveSignature);630TR_ASSERT(strlen(fullSignature) == fullSignatureLength, "Computed fullSignatureLength must match actual length of fullSignature");631CS2::HashIndex hashIndex = 0;632static char *ignoreMBSCache = feGetEnv("TR_ignoreMBSCache");633OwningMethodAndString key(originalSymRef->getOwningMethodIndex(), fullSignature);634if (_methodsBySignature.Locate(key, hashIndex) && !ignoreMBSCache)635{636TR::SymbolReference *result = _methodsBySignature[hashIndex];637if (comp()->getOption(TR_TraceMethodIndex))638traceMsg(comp(), "-- MBS cache hit (2): M%p\n", result->getSymbol()->getResolvedMethodSymbol()->getResolvedMethod());639return result;640}641else642{643// fullSignature will be kept as a key by _methodsBySignature, so it needs heapAlloc644//645key = OwningMethodAndString(originalSymRef->getOwningMethodIndex(), self()->strdup(fullSignature));646if (comp()->getOption(TR_TraceMethodIndex))647traceMsg(comp(), "-- MBS cache miss (2) owning method #%d, signature %s\n", originalSymRef->getOwningMethodIndex().value(), fullSignature);648}649650//651// No existing symref. Create a new one.652//653654TR_OpaqueMethodBlock *method = originalSymbol->getResolvedMethod()->getPersistentIdentifier();655656TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());657// Note: we use cpIndex=-1 here so we don't end up getting back originalSymRef (which will not have the signature we want)658TR::SymbolReference *result = findOrCreateMethodSymbol(originalSymRef->getOwningMethodIndex(), -1,659fej9->createResolvedMethodWithSignature(comp()->trMemory(), method, NULL, effectiveSignature, effectiveSignatureLength, originalSymbol->getResolvedMethod()->owningMethod()), originalSymbol->getMethodKind());660661result->setCPIndex(cpIndex);662_methodsBySignature.Add(key, result);663TR_ASSERT(_methodsBySignature.Locate(key), "After _methodsBySignature.Add, _methodsBySignature.Locate must be true");664665return result;666}667668669TR::SymbolReference *670J9::SymbolReferenceTable::findOrCreateTypeCheckArrayStoreSymbolRef(TR::ResolvedMethodSymbol *)671{672return findOrCreateRuntimeHelper(TR_typeCheckArrayStore, false, true, true);673}674675676TR::SymbolReference *677J9::SymbolReferenceTable::findOrCreateArrayClassRomPtrSymbolRef()678{679if (!element(arrayClassRomPtrSymbol))680{681TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());682TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);683element(arrayClassRomPtrSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), arrayClassRomPtrSymbol, sym);684element(arrayClassRomPtrSymbol)->setOffset(fej9->getOffsetOfArrayClassRomPtrField());685if (!TR::Compiler->cls.romClassObjectsMayBeCollected())686sym->setNotCollected();687}688return element(arrayClassRomPtrSymbol);689}690691692TR::SymbolReference *693J9::SymbolReferenceTable::findOrCreateJavaLangReferenceReferentShadowSymbol(694TR::ResolvedMethodSymbol * owningMethodSymbol,695bool isResolved,696TR::DataType type,697uint32_t offset, bool isUnresolvedInCP)698{699TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();700701TR::SymbolReference * symRef = NULL;702symRef = findJavaLangReferenceReferentShadowSymbol(owningMethod, TR::Address, offset);703if (!symRef)704{705symRef = createShadowSymbolWithoutCpIndex(owningMethodSymbol, true, TR::Address, offset, false);706}707return symRef;708}709710711// Right now it only works for private fields or fields that are guaranteed to be accessed only from one class712// because searchRecognizedField only does a name comparison, t does not work if the field is accessed from a subclass of the expected one713TR::SymbolReference *714J9::SymbolReferenceTable::findOrFabricateShadowSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, TR::Symbol::RecognizedField recognizedField, TR::DataType type, uint32_t offset, bool isVolatile, bool isPrivate, bool isFinal, char* name)715{716TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();717718//The following code (up to and including the call to initShadowSymbol) has been adapted from719//J9::SymbolReferenceTable::findOrCreateShadowSymbol720TR::SymbolReference * symRef = NULL;721TR::Symbol * sym = NULL;722723if (!comp()->compileRelocatableCode()724#if defined(J9VM_OPT_JITSERVER)725&& !comp()->isOutOfProcessCompilation()726#endif727)728{729symRef = findShadowSymbol(owningMethod, -1, type, &recognizedField);730731if (symRef)732return symRef;733}734sym = createShadowSymbol(735type,736isVolatile,737isPrivate,738isFinal,739name,740recognizedField);741742symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1);743// isResolved = true, isUnresolvedInCP = false744initShadowSymbol(owningMethod, symRef, true, type, offset, false);745return symRef;746}747748TR::SymbolReference *749J9::SymbolReferenceTable::findResolvedFieldShadow(750ResolvedFieldShadowKey key,751bool isVolatile,752bool isPrivate,753bool isFinal)754{755const auto entry = _resolvedFieldShadows.find(key);756if (entry == _resolvedFieldShadows.end())757return NULL;758759TR::SymbolReference *symRef = entry->second;760int32_t refNum = symRef->getReferenceNumber();761TR::Symbol *sym = symRef->getSymbol();762763// The following asserts enforce restrictions on certain symbols properties.764//765// Taking volatility as an example, it is possible to find a symref in _resolvedFieldShadows766// whose symbols is marked isVolatile but that is for a non-volatile field. Consider a scenario767// where, during compilation, an unresolved field reference is encountered. We will create a768// symbol and conservatively mark is volatile. Later, a resolved reference for the same field is769// encountered (note that it need not have the same cpIndex as the first field ref). Being770// resolved, we determine that it is non-volatile. Because a symref for the field771// already exists but has a different resolution state, a new *symref* is created but the found772// *symbol* is reused. Since volatility is a property of the symbol, the new symref will share773// the volatility of the first symref (which was unresolved and must therefore be conservatively774// considered volatile). The new symref is then added to _resolvedFieldShadows. The next time775// the same field reference is encountered, the symref for it is found in _resolvedFieldShadows776// and once again its symbol is marked as volatile despite the field being non-volatile.777//778// The inverse condition, however, is not currently possible (i.e. finding a non-volatile symbol779// for a volatile field). Still, it's possible that could change in the future (for accesses780// with different memory ordering effects). If so, it should be made part of the key, and the781// two symRefs differing only in isVolatile should be considered to possibly alias.782//783// Similar restrictions apply to the isPrivate and isFinal symbol properties, although the truth784// conditions are reversed.785TR_ASSERT_FATAL(sym->isVolatile() || !isVolatile, "expecting volatile symref but found non-volatile symref #%d\n", refNum);786TR_ASSERT_FATAL(!sym->isPrivate() || isPrivate, "expecting non-private symref but found private symref #%d\n", refNum);787TR_ASSERT_FATAL(!sym->isFinal() || isFinal, "expecting non-final symref but found final symref #%d\n", refNum);788789return symRef;790}791792TR::SymbolReference *793J9::SymbolReferenceTable::findOrFabricateShadowSymbol(794TR_OpaqueClassBlock *containingClass,795TR::DataType type,796uint32_t offset,797bool isVolatile,798bool isPrivate,799bool isFinal,800const char *name,801const char *signature)802{803ResolvedFieldShadowKey key(containingClass, offset, type);804TR::SymbolReference *symRef = findResolvedFieldShadow(key, isVolatile, isPrivate, isFinal);805if (symRef != NULL)806return symRef;807808int32_t classNameLen = 0;809const char *className =810TR::Compiler->cls.classNameChars(comp(), containingClass, classNameLen);811812int qualifiedFieldNameSize = classNameLen + 1 + strlen(name) + 1 + strlen(signature) + 1;813char *qualifiedFieldName = (char*)trHeapMemory().allocate(qualifiedFieldNameSize);814TR::snprintfNoTrunc(815qualifiedFieldName,816qualifiedFieldNameSize,817"%.*s.%s %s",818classNameLen,819className,820name,821signature);822823TR::Symbol *sym = createShadowSymbol(824type,825isVolatile,826isPrivate,827isFinal,828qualifiedFieldName,829TR::Symbol::UnknownField);830831mcount_t methodIndex = mcount_t::valueOf(0);832int32_t cpIndex = -1;833symRef = new (trHeapMemory()) TR::SymbolReference(834self(),835sym,836methodIndex,837cpIndex);838839bool isResolved = true;840bool isUnresolvedInCP = false;841initShadowSymbol(NULL, symRef, isResolved, type, offset, isUnresolvedInCP);842843_resolvedFieldShadows.insert(std::make_pair(key, symRef));844return symRef;845}846847TR::SymbolReference *848J9::SymbolReferenceTable::findFlattenedArrayElementFieldShadow(849ResolvedFieldShadowKey key,850bool isPrivate)851{852const auto entry = _flattenedArrayElementFieldShadows.find(key);853if (entry == _flattenedArrayElementFieldShadows.end())854return NULL;855856TR::SymbolReference *symRef = entry->second;857int32_t refNum = symRef->getReferenceNumber();858TR::Symbol *sym = symRef->getSymbol();859860TR_ASSERT_FATAL(sym->isPrivate() == isPrivate, "expecting %s symref but found %s: symref #%d\n",861isPrivate ? "private" : "non-private", sym->isPrivate() ? "private" : "non-private", refNum);862863// When an array element is flattened, a write through this field shadow doesn't represent a write864// to the field. It is a partial write to an array element which is non volatile.865TR_ASSERT_FATAL(sym->isVolatile() == false, "expecting non-volatile symref but found volatile: symref #%d\n", refNum);866// The field is flattened into the array element which is mutable.867TR_ASSERT_FATAL(sym->isFinal() == false, "expecting non-final symref but found final: symref #%d\n", refNum);868869return symRef;870}871872TR::SymbolReference *873J9::SymbolReferenceTable::findOrFabricateFlattenedArrayElementFieldShadowSymbol(874TR_OpaqueClassBlock *arrayComponentClass,875TR::DataType type,876uint32_t fieldOffset,877bool isPrivate,878const char *fieldName,879const char *fieldSignature)880{881int32_t flattenedFieldOffset = (int32_t)fieldOffset - (int32_t)TR::Compiler->om.objectHeaderSizeInBytes();882883TR_ASSERT_FATAL(flattenedFieldOffset >= 0, "flattenedFieldOffset %d is invalid: fieldOffset %u objectHeaderSizeInBytes %" OMR_PRIuPTR " \n", flattenedFieldOffset, fieldOffset, TR::Compiler->om.objectHeaderSizeInBytes());884885ResolvedFieldShadowKey key(arrayComponentClass, flattenedFieldOffset, type);886887TR::SymbolReference *symRef = findFlattenedArrayElementFieldShadow(key, isPrivate);888if (symRef != NULL)889return symRef;890891int32_t classNameLen = 0;892const char *className = TR::Compiler->cls.classNameChars(comp(), arrayComponentClass, classNameLen);893894// "<Q-className-array-shadow>.fieldName fieldSignature"895char qNameMem[128];896TR::StringBuf qNameBuf(trMemory()->currentStackRegion(), qNameMem, sizeof(qNameMem));897qNameBuf.appendf("<Q-%.*s-array-shadow>.%s %s", classNameLen, className, fieldName, fieldSignature);898899size_t qualifiedFieldNameSize = qNameBuf.len() + 1; // +1 for NULL terminator900char *qualifiedFieldName = (char*)trHeapMemory().allocate(qualifiedFieldNameSize);901memcpy(qualifiedFieldName, qNameBuf.text(), qualifiedFieldNameSize);902903// isVolatile is false because when an array element is flattened, a write through904// this field shadow doesn't represent a write to the field. It is a partial write905// to an array element which is non volatile.906// isFinal is false because the field is flattened into the array element which is mutable.907TR::Symbol *sym = createShadowSymbol(908type,909false /*isVolatile*/,910isPrivate,911false /*isFinal*/,912qualifiedFieldName,913TR::Symbol::UnknownField);914915mcount_t methodIndex = mcount_t::valueOf(0);916int32_t cpIndex = -1;917symRef = new (trHeapMemory()) TR::SymbolReference(918self(),919sym,920methodIndex,921cpIndex);922923bool isResolved = true;924bool isUnresolvedInCP = false;925initShadowSymbol(NULL, symRef, isResolved, type, flattenedFieldOffset, isUnresolvedInCP);926927_flattenedArrayElementFieldShadows.insert(std::make_pair(key, symRef));928return symRef;929}930931TR::Symbol *932J9::SymbolReferenceTable::createShadowSymbol(933TR::DataType type,934bool isVolatile,935bool isPrivate,936bool isFinal,937const char *name,938TR::Symbol::RecognizedField recognizedField)939{940TR::Symbol *sym = TR::Symbol::createPossiblyRecognizedShadowWithFlags(941trHeapMemory(), type, isVolatile, isFinal, isPrivate, recognizedField);942943if (name != NULL)944{945sym->setNamedShadowSymbol();946sym->setName(name);947}948949static char *dontAliasShadowsToEarlierGISEnv = feGetEnv("TR_dontAliasShadowsToEarlierGIS");950bool dontAliasShadowsToEarlierGIS = dontAliasShadowsToEarlierGISEnv != NULL;951952if (aliasBuilder.mutableGenericIntShadowHasBeenCreated() && !dontAliasShadowsToEarlierGIS)953{954// Some previously-created GIS might actually refer to this shadow955aliasBuilder.setConservativeGenericIntShadowAliasing(true);956}957958return sym;959}960961TR::SymbolReference *962J9::SymbolReferenceTable::findOrCreateShadowSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, bool isStore)963{964TR_ResolvedJ9Method * owningMethod =965static_cast<TR_ResolvedJ9Method*>(owningMethodSymbol->getResolvedMethod());966967bool isVolatile = true, isFinal = false, isPrivate = false, isUnresolvedInCP;968TR::DataType type = TR::NoType;969uint32_t offset = 0;970bool resolved = owningMethod->fieldAttributes(comp(), cpIndex, &offset, &type, &isVolatile, &isFinal, &isPrivate, isStore, &isUnresolvedInCP, true);971bool sharesSymbol = false;972973TR_OpaqueClassBlock *containingClass = NULL;974TR::Symbol::RecognizedField recognizedField = TR::Symbol::searchRecognizedField(comp(), owningMethod, cpIndex, false);975976if (isStore && isPrivate && !comp()->getOptions()->realTimeGC() &&977owningMethodSymbol->getResolvedMethod()->getRecognizedMethod() == TR::java_lang_ref_SoftReference_get &&978recognizedField == TR::Symbol::Java_lang_ref_SoftReference_age)979{980isVolatile = false;981}982983if (resolved)984{985bool isStatic = false;986TR_OpaqueClassBlock* fromResolvedJ9Method = NULL;987containingClass =988owningMethod->definingClassFromCPFieldRef(comp(), cpIndex, isStatic, &fromResolvedJ9Method);989990// Normally, the expectation is that if a cp field ref is resolved, then the cp ref pointing991// to the containing class must also be resolved. However, in #9416, it was discovered that992// this assumption does not hold in some cases. Under AOT, loading class data from the SCC993// using findSharedData() may fail, which is propagated to the JIT as a NULL containing class.994// In addition, if a class is redefined between the point where a field is looked up and995// where the defining class is looked, the latter may become NULL.996//997// Having a NULL containing class would imply two fields from different classes could have998// the same lookup key, which is a problem. So, until the above issues are resolved, the999// safe thing to do is to abort compilation in these (rare) cases.1000if (containingClass == NULL)1001comp()->failCompilation<TR::CompilationException>(1002"failed to get defining class of resolved field ref cpIndex=%d in owning method J9Method=%p",1003cpIndex,1004owningMethod->getNonPersistentIdentifier());10051006ResolvedFieldShadowKey key(containingClass, offset, type);1007TR::SymbolReference *symRef =1008findResolvedFieldShadow(key, isVolatile, isPrivate, isFinal);10091010if (symRef != NULL)1011return symRef;1012}10131014TR::Symbol * sym = 0;10151016TR::SymbolReference * symRef = findShadowSymbol(owningMethod, cpIndex, type, &recognizedField);1017if (symRef)1018{1019if ((resolved && !symRef->isUnresolved()) ||1020(!resolved && symRef->isUnresolved() && owningMethod == symRef->getOwningMethod(comp())))1021return symRef;1022sym = symRef->getSymbol()->castToShadowSymbol();1023sharesSymbol = true;1024}1025else1026{1027sym = createShadowSymbol(1028type,1029isVolatile,1030isPrivate,1031isFinal,1032NULL,1033recognizedField);1034}10351036int32_t unresolvedIndex = resolved ? 0 : _numUnresolvedSymbols++;10371038if (sharesSymbol)1039symRef->setReallySharesSymbol();10401041symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), cpIndex, unresolvedIndex);1042checkUserField(symRef);10431044if (sharesSymbol)1045symRef->setReallySharesSymbol();10461047initShadowSymbol(owningMethod, symRef, resolved, type, offset, isUnresolvedInCP);10481049if (cpIndex > 0)1050aliasBuilder.cpSymRefs().set(symRef->getReferenceNumber());10511052if (containingClass != NULL)1053{1054ResolvedFieldShadowKey key(containingClass, offset, type);1055_resolvedFieldShadows.insert(std::make_pair(key, symRef));1056}10571058return symRef;1059}10601061TR::SymbolReference *1062J9::SymbolReferenceTable::findOrCreateObjectNewInstanceImplSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol)1063{1064if (!_ObjectNewInstanceImplSymRef)1065{1066TR_J9VMBase *fej9 = (TR_J9VMBase *)fe();1067TR_ResolvedMethod * resolvedMethod = fej9->getObjectNewInstanceImplMethod(trMemory());1068TR::ResolvedMethodSymbol * sym = TR::ResolvedMethodSymbol::create(trHeapMemory(),resolvedMethod,comp());1069sym->setMethodKind(TR::MethodSymbol::Virtual);10701071mcount_t owningMethodIndex = owningMethodSymbol->getResolvedMethodIndex();10721073_ObjectNewInstanceImplSymRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodIndex, -1, 0);1074_ObjectNewInstanceImplSymRef->setCanGCandReturn();1075_ObjectNewInstanceImplSymRef->setCanGCandExcept();1076_ObjectNewInstanceImplSymRef->setOffset(fej9->getNewInstanceImplVirtualCallOffset());10771078aliasBuilder.methodSymRefs().set(_ObjectNewInstanceImplSymRef->getReferenceNumber()); // cmvc defect 19349310791080// This is a dummy resolved method - would never be called. However, we set1081// the count to zero here to make sure that the optimizer does not think that1082// this method is cold and never being called1083//1084resolvedMethod->setInvocationCount(resolvedMethod->getInvocationCount(), 0);1085}1086return _ObjectNewInstanceImplSymRef;1087}108810891090TR::SymbolReference *1091J9::SymbolReferenceTable::findOrCreateDLTBlockSymbolRef()1092{1093if (!element(dltBlockSymbol))1094{1095TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1096TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "DLTBlockMeta");1097sym->setDataType(TR::Address);1098sym->setNotCollected();1099element(dltBlockSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), dltBlockSymbol, sym);1100element(dltBlockSymbol)->setOffset(fej9->thisThreadGetDLTBlockOffset());11011102// We can't let the load/store of the exception symbol swing down1103//1104aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(dltBlockSymbol)); // add the symRef to the statics list to get correct aliasing info1105aliasBuilder.gcSafePointSymRefNumbers().set(getNonhelperIndex(dltBlockSymbol));1106}1107return element(dltBlockSymbol);1108}110911101111TR::SymbolReference *1112J9::SymbolReferenceTable::findDLTBlockSymbolRef()1113{1114return element(dltBlockSymbol);1115}111611171118TR::SymbolReference *1119J9::SymbolReferenceTable::findOrCreateMultiANewArraySymbolRef(TR::ResolvedMethodSymbol *)1120{1121return findOrCreateRuntimeHelper(TR_multiANewArray, true, true, true);1122}112311241125TR::SymbolReference *1126J9::SymbolReferenceTable::findOrCreateInstanceShapeSymbolRef()1127{1128if (!element(instanceShapeSymbol))1129{1130TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1131TR::Symbol * sym;1132if (self()->comp()->target().is64Bit())1133sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);1134else1135sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);1136element(instanceShapeSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), instanceShapeSymbol, sym);1137element(instanceShapeSymbol)->setOffset(fej9->getOffsetOfInstanceShapeFromClassField());1138}1139return element(instanceShapeSymbol);1140}114111421143TR::SymbolReference *1144J9::SymbolReferenceTable::findOrCreateInstanceDescriptionSymbolRef()1145{1146if (!element(instanceDescriptionSymbol))1147{1148TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1149TR::Symbol * sym;1150if (self()->comp()->target().is64Bit())1151sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);1152else1153sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);1154element(instanceDescriptionSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), instanceDescriptionSymbol, sym);1155element(instanceDescriptionSymbol)->setOffset(fej9->getOffsetOfInstanceDescriptionFromClassField());1156}1157return element(instanceDescriptionSymbol);1158}1159116011611162TR::SymbolReference *1163J9::SymbolReferenceTable::findOrCreateDescriptionWordFromPtrSymbolRef()1164{1165if (!element(descriptionWordFromPtrSymbol))1166{1167TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1168TR::Symbol * sym;1169if (self()->comp()->target().is64Bit())1170sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);1171else1172sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);1173element(descriptionWordFromPtrSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), descriptionWordFromPtrSymbol, sym);1174element(descriptionWordFromPtrSymbol)->setOffset(fej9->getOffsetOfDescriptionWordFromPtrField());1175}1176return element(descriptionWordFromPtrSymbol);1177}117811791180TR::SymbolReference *1181J9::SymbolReferenceTable::findOrCreateClassFlagsSymbolRef()1182{1183if (!element(isClassFlagsSymbol))1184{1185TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1186TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);1187element(isClassFlagsSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), isClassFlagsSymbol, sym);1188element(isClassFlagsSymbol)->setOffset(fej9->getOffsetOfClassFlags());1189}1190return element(isClassFlagsSymbol);1191}119211931194TR::SymbolReference *1195J9::SymbolReferenceTable::findOrCreateClassAndDepthFlagsSymbolRef()1196{1197if (!element(isClassAndDepthFlagsSymbol))1198{1199TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1200TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);1201element(isClassAndDepthFlagsSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), isClassAndDepthFlagsSymbol, sym);1202element(isClassAndDepthFlagsSymbol)->setOffset(fej9->getOffsetOfClassAndDepthFlags());1203}1204return element(isClassAndDepthFlagsSymbol);1205}120612071208TR::SymbolReference *1209J9::SymbolReferenceTable::findOrCreateArrayComponentTypeAsPrimitiveSymbolRef()1210{1211if (!element(componentClassAsPrimitiveSymbol))1212{1213TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1214TR::Symbol * sym;1215if (self()->comp()->target().is64Bit())1216sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);1217else1218sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);12191220element(componentClassAsPrimitiveSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), componentClassAsPrimitiveSymbol, sym);1221element(componentClassAsPrimitiveSymbol)->setOffset(fej9->getOffsetOfArrayComponentTypeField());1222if (!TR::Compiler->cls.classObjectsMayBeCollected())1223sym->setNotCollected();1224}1225return element(componentClassAsPrimitiveSymbol);1226}122712281229TR::SymbolReference *1230J9::SymbolReferenceTable::findOrCreateMethodTypeCheckSymbolRef(TR::ResolvedMethodSymbol *)1231{1232return findOrCreateRuntimeHelper(TR_methodTypeCheck, false, true, true);1233}12341235TR::SymbolReference *1236J9::SymbolReferenceTable::findOrCreateIncompatibleReceiverSymbolRef(TR::ResolvedMethodSymbol *)1237{1238return findOrCreateRuntimeHelper(TR_incompatibleReceiver, false, true, true);1239}12401241TR::SymbolReference *1242J9::SymbolReferenceTable::findOrCreateIncompatibleClassChangeErrorSymbolRef(TR::ResolvedMethodSymbol *)1243{1244return findOrCreateRuntimeHelper(TR_IncompatibleClassChangeError, false, true, true);1245}12461247TR::SymbolReference *1248J9::SymbolReferenceTable::findOrCreateReportStaticMethodEnterSymbolRef(TR::ResolvedMethodSymbol *)1249{1250return findOrCreateRuntimeHelper(TR_reportStaticMethodEnter, true, false, true);1251}125212531254TR::SymbolReference *1255J9::SymbolReferenceTable::findOrCreateReportMethodExitSymbolRef(TR::ResolvedMethodSymbol *)1256{1257return findOrCreateRuntimeHelper(TR_reportMethodExit, true, false, true);1258}12591260TR::SymbolReference *1261J9::SymbolReferenceTable::findOrCreateHeaderFlagsSymbolRef()1262{1263if (!element(headerFlagsSymbol))1264{1265TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1266TR::SymbolReference * symRef;1267// object header flags now occupy 4bytes on 64-bit1268symRef = new (trHeapMemory()) TR::SymbolReference(self(), headerFlagsSymbol, TR::Symbol::createShadow(trHeapMemory(),TR::Int32));1269symRef->setOffset(TR::Compiler->om.offsetOfHeaderFlags());1270element(headerFlagsSymbol) = symRef;1271aliasBuilder.intShadowSymRefs().set(symRef->getReferenceNumber());1272}12731274return element(headerFlagsSymbol);1275}127612771278TR::SymbolReference *1279J9::SymbolReferenceTable::findOrCreateDiscontiguousArraySizeSymbolRef()1280{1281if (!element(discontiguousArraySizeSymbol))1282{1283TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1284TR::Symbol * sym;12851286// Size field is 32-bits on ALL header shapes.1287//1288sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);1289element(discontiguousArraySizeSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), discontiguousArraySizeSymbol, sym);1290element(discontiguousArraySizeSymbol)->setOffset(fej9->getOffsetOfDiscontiguousArraySizeField());1291}1292return element(discontiguousArraySizeSymbol);1293}129412951296TR::SymbolReference *1297J9::SymbolReferenceTable::findOrCreateClassLoaderSymbolRef(TR_ResolvedMethod * method)1298{1299ListIterator<TR::SymbolReference> i(&_classLoaderSymbolRefs);1300TR::SymbolReference * symRef;1301for (symRef = i.getFirst(); symRef; symRef = i.getNext())1302if (symRef->getOwningMethod(comp()) == method)1303return symRef;13041305TR::StaticSymbol * sym = TR::StaticSymbol::create(trHeapMemory(),TR::Address);1306TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1307sym->setStaticAddress(fej9->getLocationOfClassLoaderObjectPointer(method->classOfMethod()));1308mcount_t index = comp()->getOwningMethodSymbol(method)->getResolvedMethodIndex();1309symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, index, -1);13101311aliasBuilder.addressStaticSymRefs().set(symRef->getReferenceNumber()); // add the symRef to the statics list to get correct aliasing info13121313_classLoaderSymbolRefs.add(symRef);13141315return symRef;1316}131713181319TR::SymbolReference *1320J9::SymbolReferenceTable::findOrCreateCurrentThreadSymbolRef()1321{1322if (!element(currentThreadSymbol))1323{1324TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1325TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "CurrentThread");1326sym->setDataType(TR::Address);1327sym->setImmutableField();1328element(currentThreadSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), currentThreadSymbol, sym);1329element(currentThreadSymbol)->setOffset(fej9->thisThreadGetCurrentThreadOffset());1330}1331return element(currentThreadSymbol);1332}13331334TR::SymbolReference *1335J9::SymbolReferenceTable::findOrCreateJ9MethodConstantPoolFieldSymbolRef(intptr_t offset)1336{1337if (!element(j9methodConstantPoolSymbol))1338{1339TR::Symbol * sym;1340if (self()->comp()->target().is64Bit())1341sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int64);1342else1343sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int32);13441345element(j9methodConstantPoolSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), j9methodConstantPoolSymbol, sym);1346element(j9methodConstantPoolSymbol)->setOffset(offset);1347}1348TR::SymbolReference *result = element(j9methodConstantPoolSymbol);1349TR_ASSERT(result->getOffset() == offset, "findOrCreateJ9MethodConstantPoolFieldSymbolRef must use the right offset! %d != %d", result->getOffset(), offset);1350return result;1351}13521353TR::SymbolReference *1354J9::SymbolReferenceTable::findOrCreateJ9MethodExtraFieldSymbolRef(intptr_t offset)1355{1356if (!element(j9methodExtraFieldSymbol))1357{1358TR::Symbol * sym;1359if (self()->comp()->target().is64Bit())1360sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int64);1361else1362sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int32);13631364element(j9methodExtraFieldSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), j9methodExtraFieldSymbol, sym);1365element(j9methodExtraFieldSymbol)->setOffset(offset);1366}1367TR::SymbolReference *result = element(j9methodExtraFieldSymbol);1368TR_ASSERT(result->getOffset() == offset, "findOrCreateJ9MethodExtraFieldSymbolRef must use the right offset! %d != %d", result->getOffset(), offset);1369return result;1370}13711372TR::SymbolReference *1373J9::SymbolReferenceTable::findOrCreateJ9JNIMethodIDvTableIndexFieldSymbol(intptr_t offset)1374{1375if (!element(J9JNIMethodIDvTableIndexFieldSymbol))1376{1377TR::Symbol * sym;1378if (self()->comp()->target().is64Bit())1379sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int64);1380else1381sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int32);13821383element(J9JNIMethodIDvTableIndexFieldSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), J9JNIMethodIDvTableIndexFieldSymbol, sym);1384element(J9JNIMethodIDvTableIndexFieldSymbol)->setOffset(offset);1385}1386return element(J9JNIMethodIDvTableIndexFieldSymbol);1387}13881389TR::SymbolReference *1390J9::SymbolReferenceTable::findOrCreateStartPCLinkageInfoSymbolRef(intptr_t offset)1391{1392if (!element(startPCLinkageInfoSymbol))1393{1394TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int32);1395element(startPCLinkageInfoSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), startPCLinkageInfoSymbol, sym);1396element(startPCLinkageInfoSymbol)->setOffset(offset);1397}1398TR::SymbolReference *result = element(startPCLinkageInfoSymbol);1399TR_ASSERT(result->getOffset() == offset, "findOrCreateStartPCLinkageInfoSymbolRef must use the right offset! %d != %d", result->getOffset(), offset);1400return result;1401}140214031404TR::SymbolReference *1405J9::SymbolReferenceTable::findOrCreatePerCodeCacheHelperSymbolRef(TR_CCPreLoadedCode helper, uintptr_t helperAddr)1406{1407CommonNonhelperSymbol index = (CommonNonhelperSymbol)(firstPerCodeCacheHelperSymbol + helper);1408if (!element(index))1409{1410TR::MethodSymbol * methodSymbol = TR::MethodSymbol::create(trHeapMemory(),TR_Private);1411methodSymbol->setHelper();1412// The address of the helper depends on the current codecache, which can change during compilation, so we don't have a single method address1413methodSymbol->setMethodAddress(NULL);1414element(index) = new (trHeapMemory()) TR::SymbolReference(self(), index, methodSymbol);1415}1416return element(index);1417}141814191420TR::SymbolReference *1421J9::SymbolReferenceTable::findOrCreateANewArraySymbolRef(TR::ResolvedMethodSymbol *)1422{1423return findOrCreateRuntimeHelper(TR_aNewArray, true, true, true);1424}142514261427TR::SymbolReference *1428J9::SymbolReferenceTable::findOrCreateStringSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)1429{1430TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();1431void * stringConst = owningMethod->stringConstant(cpIndex);1432TR::SymbolReference * symRef;1433bool isString = true;1434if (owningMethod->isUnresolvedString(cpIndex))1435{1436symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, false, 0);1437symRef->setOffset((uintptr_t)stringConst);1438}1439else1440{1441TR::KnownObjectTable::Index knownObjectIndex = TR::KnownObjectTable::UNKNOWN;1442if (!comp()->compileRelocatableCode())1443{1444TR::KnownObjectTable *knot = comp()->getOrCreateKnownObjectTable();1445if (knot)1446{1447knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)stringConst);1448}1449}1450symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, true, stringConst, knownObjectIndex);1451}14521453TR::StaticSymbol * sym = (TR::StaticSymbol *)symRef->getSymbol();14541455// If the cp entry is patched, it's resolved during the patching1456// Unresolved cp entry will always contain a const string1457if (symRef->isUnresolved())1458{1459sym->setConstString();1460}1461// If symbol is created the first time, check if the const object is String1462else if (!sym->isConstString() &&1463!sym->isNonSpecificConstObject())1464{1465TR::VMAccessCriticalSection constantCriticalSection(comp()->fej9());1466TR_OpaqueClassBlock *clazz = comp()->fej9()->getObjectClassAt((uintptr_t)stringConst);1467if (comp()->fej9()->isString(clazz))1468{1469sym->setConstString();1470}1471else1472{1473if (comp()->compileRelocatableCode())1474comp()->failCompilation<J9::AOTHasPatchedCPConstant>("Patched Constant not supported in AOT.");14751476sym->setNonSpecificConstObject();1477}1478}14791480return symRef;1481}14821483TR::SymbolReference *1484J9::SymbolReferenceTable::findOrCreateConstantDynamicSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, char* symbolTypeSig, int32_t symbolTypeSigLength, bool isCondyPrimitive)1485{1486TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();1487void * dynamicConst = owningMethod->dynamicConstant(cpIndex, NULL);1488TR::SymbolReference * symRef;1489if (owningMethod->isUnresolvedConstantDynamic(cpIndex))1490{1491symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, false, 0);1492symRef->setOffset((uintptr_t)dynamicConst);1493}1494else1495{1496symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, true, dynamicConst);1497}1498TR::StaticSymbol * sym = (TR::StaticSymbol *)symRef->getSymbol();1499sym->setConstantDynamic();1500sym->makeConstantDynamic(symbolTypeSig, symbolTypeSigLength, isCondyPrimitive);1501return symRef;1502}15031504TR::SymbolReference *1505J9::SymbolReferenceTable::findOrCreateMethodMonitorEntrySymbolRef(TR::ResolvedMethodSymbol *)1506{1507return findOrCreateRuntimeHelper(TR_methodMonitorEntry, true, false, true);1508}150915101511TR::SymbolReference *1512J9::SymbolReferenceTable::findOrCreateMethodMonitorExitSymbolRef(TR::ResolvedMethodSymbol *)1513{1514return findOrCreateRuntimeHelper(TR_methodMonitorExit, true /* canGCandReturn */, true /* canGCandExcept */, true /* preservesAllRegisters */);1515}151615171518TR::SymbolReference *1519J9::SymbolReferenceTable::findOrCreateCompiledMethodSymbolRef()1520{1521if (!element(compiledMethodSymbol))1522{1523TR::StaticSymbol * sym = TR::StaticSymbol::create(trHeapMemory(),TR::Address);1524sym->setStaticAddress(comp()->getCurrentMethod()->getPersistentIdentifier());1525sym->setCompiledMethod();1526sym->setNotDataAddress();1527element(compiledMethodSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), compiledMethodSymbol, sym);1528}1529return element(compiledMethodSymbol);1530}153115321533TR::SymbolReference *1534J9::SymbolReferenceTable::findOrCreateMethodTypeSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)1535{1536TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();1537void * methodTypeConst = owningMethod->methodTypeConstant(cpIndex);1538TR::SymbolReference * symRef;1539if (owningMethod->isUnresolvedMethodType(cpIndex))1540{1541symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, false, 0);1542symRef->setOffset((uintptr_t)methodTypeConst);1543}1544else1545{1546symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, true, methodTypeConst);1547}1548TR::StaticSymbol * sym = (TR::StaticSymbol *)symRef->getSymbol();1549sym->setConstMethodType();1550return symRef;1551}15521553TR::SymbolReference *1554J9::SymbolReferenceTable::findOrCreateMethodHandleSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)1555{1556TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();1557void * methodHandleConst = owningMethod->methodHandleConstant(cpIndex);1558TR::SymbolReference * symRef;1559if (owningMethod->isUnresolvedMethodHandle(cpIndex))1560{1561symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, false, 0);1562symRef->setOffset((uintptr_t)methodHandleConst);1563}1564else1565{1566TR::KnownObjectTable::Index knownObjectIndex = TR::KnownObjectTable::UNKNOWN;1567TR::KnownObjectTable *knot = comp()->getOrCreateKnownObjectTable();1568if (knot)1569knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)methodHandleConst);1570symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, true, methodHandleConst, knownObjectIndex);1571}1572TR::StaticSymbol * sym = (TR::StaticSymbol *)symRef->getSymbol();1573sym->setConstMethodHandle();1574return symRef;1575}157615771578TR::SymbolReference *1579J9::SymbolReferenceTable::findOrCreateClassStaticsSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)1580{1581TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();15821583TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1584void * classStatics = fej9->addressOfFirstClassStatic(owningMethod->classOfStatic(cpIndex, true));15851586ListIterator<TR::SymbolReference> i(&_classStaticsSymbolRefs);1587TR::SymbolReference * symRef;1588for (symRef = i.getFirst(); symRef; symRef = i.getNext())1589if (symRef->getSymbol()->getStaticSymbol()->getStaticAddress() == classStatics)1590return symRef;15911592TR::StaticSymbol * sym = TR::StaticSymbol::create(trHeapMemory(),TR::Address);1593sym->setStaticAddress(classStatics);1594if (!TR::Compiler->cls.classObjectsMayBeCollected())1595sym->setNotCollected();1596// cpIndex for resolved Class statics symbol is unused. Furthermore having a cpIndex here might create illusion for cases where we1597// care about cpIndex and also as Two or more (resolved) static field references belonging to same class will1598// share the same information (inlined call site index, cpIndex) , using a cpIndex for these cases will1599// need further changes to prevent any sharing hence it is set to -1 for static resolved fields.1600// For more detailed information take a look at PR#4322 in eclipse-openj9/openj9 repo1601symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1);16021603aliasBuilder.addressStaticSymRefs().set(symRef->getReferenceNumber()); // add the symRef to the statics list to get correct aliasing info16041605_classStaticsSymbolRefs.add(symRef);16061607return symRef;1608}160916101611TR::SymbolReference *1612J9::SymbolReferenceTable::findOrCreateClassFromJavaLangClassAsPrimitiveSymbolRef()1613{1614if (!element(classFromJavaLangClassAsPrimitiveSymbol))1615{1616TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1617TR::Symbol * sym;1618if (self()->comp()->target().is64Bit())1619sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);1620else1621sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);16221623element(classFromJavaLangClassAsPrimitiveSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), classFromJavaLangClassAsPrimitiveSymbol, sym);1624element(classFromJavaLangClassAsPrimitiveSymbol)->setOffset(fej9->getOffsetOfClassFromJavaLangClassField());1625}1626return element(classFromJavaLangClassAsPrimitiveSymbol);1627}162816291630TR::SymbolReference *1631J9::SymbolReferenceTable::findClassFromJavaLangClassAsPrimitiveSymbolRef()1632{1633return element(classFromJavaLangClassAsPrimitiveSymbol);1634}163516361637TR::SymbolReference *1638J9::SymbolReferenceTable::createShadowSymbolWithoutCpIndex(TR::ResolvedMethodSymbol * owningMethodSymbol, bool isResolved,1639TR::DataType type, uint32_t offset, bool isUnresolvedInCP)1640{1641TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();16421643TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(),type);1644TR::SymbolReference * symRef;16451646int32_t unresolvedIndex = isResolved ? 0 : _numUnresolvedSymbols++;1647symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1);1648initShadowSymbol(owningMethod, symRef, isResolved, type, offset, isUnresolvedInCP);1649return symRef;1650}165116521653TR::SymbolReference *1654J9::SymbolReferenceTable::findJavaLangReferenceReferentShadowSymbol(TR_ResolvedMethod * owningMethod, TR::DataType type, uint32_t offset)1655{1656TR::SymbolReference * symRef;1657TR_SymRefIterator i(type == TR::Address ? aliasBuilder.addressShadowSymRefs() :1658(type == TR::Int32 ? aliasBuilder.intShadowSymRefs() : aliasBuilder.nonIntPrimitiveShadowSymRefs()), self());1659while ((symRef = i.getNext()) != NULL)1660if (symRef->getSymbol()->getDataType() == type &&1661symRef->getOffset() == offset &&1662symRef->getOwningMethod(comp()) == owningMethod)1663return symRef;1664return 0;1665}166616671668void1669J9::SymbolReferenceTable::initShadowSymbol(TR_ResolvedMethod * owningMethod, TR::SymbolReference *symRef, bool isResolved,1670TR::DataType type, uint32_t offset, bool isUnresolvedInCP)1671{1672if (isResolved)1673{1674symRef->setOffset(offset);1675}1676else1677{1678symRef->setUnresolved();1679symRef->setCanGCandExcept();1680aliasBuilder.unresolvedShadowSymRefs().set(symRef->getReferenceNumber());1681}16821683symRef->setHasBeenAccessedAtRuntime(isUnresolvedInCP? TR_no : TR_maybe);16841685if (type == TR::Address)1686aliasBuilder.addressShadowSymRefs().set(symRef->getReferenceNumber());1687else if (type == TR::Int32)1688aliasBuilder.intShadowSymRefs().set(symRef->getReferenceNumber());1689else1690aliasBuilder.nonIntPrimitiveShadowSymRefs().set(symRef->getReferenceNumber());16911692if (shouldMarkBlockAsCold(owningMethod, isUnresolvedInCP))1693markBlockAsCold();16941695return;1696}169716981699List<TR::SymbolReference> *1700J9::SymbolReferenceTable::dynamicMethodSymrefsByCallSiteIndex(int32_t index)1701{1702if (!_dynamicMethodSymrefsByCallSiteIndex[index])1703_dynamicMethodSymrefsByCallSiteIndex[index] = new (trHeapMemory()) List<TR::SymbolReference>(comp()->trMemory());1704return _dynamicMethodSymrefsByCallSiteIndex[index];1705}17061707bool1708J9::SymbolReferenceTable::isFieldClassObject(TR::SymbolReference *symRef)1709{1710int32_t len;1711const char *fieldName = symRef->getOwningMethod(comp())->fieldSignatureChars(symRef->getCPIndex(), len);1712dumpOptDetails(comp(), "got fieldsig as %s\n", fieldName);1713return false;1714}17151716static bool isSignatureTypeBool(const char *fieldSignature, int32_t len)1717{1718return len == 1 && fieldSignature[0] == 'Z';1719}17201721static bool isSignatureReturnTypeBool(const char *methodSignature, int32_t len)1722{1723TR_ASSERT(len > 1, "Method signature is unexpectedly short %d", len);1724// Method signature must end with ")Z" to have a boolean result type1725return len > 1 && (')' == methodSignature[len-2]) && ('Z' == methodSignature[len-1]);1726}17271728bool1729J9::SymbolReferenceTable::isFieldTypeBool(TR::SymbolReference *symRef)1730{1731int32_t len;1732const char *fieldSignature = symRef->getOwningMethod(comp())->fieldSignatureChars(symRef->getCPIndex(), len);1733dumpOptDetails(comp(), "got field signature as %s\n", fieldSignature);1734return isSignatureTypeBool(fieldSignature, len);1735}17361737bool1738J9::SymbolReferenceTable::isStaticTypeBool(TR::SymbolReference *symRef)1739{1740int32_t len;1741const char *fieldSignature = symRef->getOwningMethod(comp())->staticSignatureChars(symRef->getCPIndex(), len);1742dumpOptDetails(comp(), "got static signature as %s\n", fieldSignature);1743return isSignatureTypeBool(fieldSignature, len);1744}17451746bool1747J9::SymbolReferenceTable::isReturnTypeBool(TR::SymbolReference *symRef)1748{1749TR::Method *method = symRef->getSymbol()->castToResolvedMethodSymbol()->getMethod();1750char *methodSignature = method->signatureChars();1751const int32_t len = method->signatureLength();1752dumpOptDetails(comp(), "got method signature as %.*s\n", len, methodSignature);1753return isSignatureReturnTypeBool(methodSignature, len);1754}17551756static bool parmSlotCameFromExpandingAnArchetypeArgPlaceholder(int32_t slot, TR::ResolvedMethodSymbol *sym)1757{1758TR_ResolvedJ9Method *meth = (TR_ResolvedJ9Method *) sym->getResolvedMethod();1759if (meth->convertToMethod()->isArchetypeSpecimen())1760return slot >= meth->archetypeArgPlaceholderSlot();1761else1762return false;1763}176417651766void1767J9::SymbolReferenceTable::addParameters(TR::ResolvedMethodSymbol * methodSymbol)1768{1769mcount_t index = methodSymbol->getResolvedMethodIndex();1770methodSymbol->setParameterList();1771ListIterator<TR::ParameterSymbol> parms(&methodSymbol->getParameterList());1772for (TR::ParameterSymbol * p = parms.getFirst(); p; p = parms.getNext())1773{1774TR::KnownObjectTable::Index knownObjectIndex = methodSymbol->getKnownObjectIndexForParm(p->getOrdinal());1775TR::SymbolReference *symRef = NULL;1776if (knownObjectIndex == TR::KnownObjectTable::UNKNOWN)1777symRef = new (trHeapMemory()) TR::SymbolReference(self(), p, index, p->getSlot());1778else1779symRef = createTempSymRefWithKnownObject(p, index, p->getSlot(), knownObjectIndex);1780methodSymbol->setParmSymRef(p->getSlot(), symRef);1781if (!parmSlotCameFromExpandingAnArchetypeArgPlaceholder(p->getSlot(), methodSymbol))1782methodSymbol->getAutoSymRefs(p->getSlot()).add(symRef);1783}1784}178517861787TR::SymbolReference *1788J9::SymbolReferenceTable::findOrCreateStaticSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, bool isStore)1789{1790TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();1791void * dataAddress;1792TR::DataType type = TR::NoType;1793bool isVolatile, isFinal, isPrivate, isUnresolvedInCP;1794bool resolved = owningMethod->staticAttributes(comp(), cpIndex, &dataAddress, &type, &isVolatile, &isFinal, &isPrivate, isStore, &isUnresolvedInCP);17951796bool sharesSymbol = false;17971798TR::StaticSymbol * sym = 0;1799TR::SymbolReference * symRef = findStaticSymbol(owningMethod, cpIndex, type);1800if (symRef)1801{1802if ((resolved && !symRef->isUnresolved()) ||1803(!resolved && symRef->isUnresolved() && owningMethod == symRef->getOwningMethod(comp())))1804{1805symRef->setHasBeenAccessedAtRuntime(isUnresolvedInCP ? TR_no: TR_maybe);1806if (shouldMarkBlockAsCold(owningMethod, isUnresolvedInCP))1807markBlockAsCold();18081809return symRef;1810}18111812sym = symRef->getSymbol()->castToStaticSymbol();1813sharesSymbol = true;1814}1815else1816{1817TR::Symbol::RecognizedField recognizedField = TR::Symbol::searchRecognizedField(comp(), owningMethod, cpIndex, true);1818if (recognizedField != TR::Symbol::UnknownField)1819sym = TR::StaticSymbol::createRecognized(trHeapMemory(), type, recognizedField);1820else1821sym = TR::StaticSymbol::create(trHeapMemory(), type);18221823if (isVolatile)1824sym->setVolatile();1825if (isFinal)1826sym->setFinal();1827if (isPrivate)1828sym->setPrivate();1829}18301831int32_t unresolvedIndex = resolved ? 0 : _numUnresolvedSymbols++;18321833if (sharesSymbol)1834symRef->setReallySharesSymbol();18351836TR::KnownObjectTable::Index knownObjectIndex = TR::KnownObjectTable::UNKNOWN;1837if (resolved && isFinal && type == TR::Address)1838{1839knownObjectIndex = TR::TransformUtil::knownObjectFromFinalStatic(1840comp(), owningMethod, cpIndex, dataAddress);1841}18421843symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), cpIndex, unresolvedIndex, knownObjectIndex);18441845checkUserField(symRef);18461847if (sharesSymbol)1848symRef->setReallySharesSymbol();18491850if (resolved)1851{1852sym->setStaticAddress(dataAddress);1853}1854else1855{1856symRef->setUnresolved();1857symRef->setCanGCandReturn();1858symRef->setCanGCandExcept();1859}18601861symRef->setHasBeenAccessedAtRuntime(isUnresolvedInCP? TR_no : TR_maybe);18621863if (type == TR::Address)1864aliasBuilder.addressStaticSymRefs().set(symRef->getReferenceNumber());1865else if (type == TR::Int32)1866aliasBuilder.intStaticSymRefs().set(symRef->getReferenceNumber());1867else1868aliasBuilder.nonIntPrimitiveStaticSymRefs().set(symRef->getReferenceNumber());18691870if (shouldMarkBlockAsCold(owningMethod, isUnresolvedInCP))1871markBlockAsCold();18721873return symRef;1874}187518761877static struct N { const char * name; } pnames[] =1878{1879"java/",1880"javax/",1881"com/ibm/",1882"com/sun/"1883};188418851886void1887J9::SymbolReferenceTable::checkUserField(TR::SymbolReference *symRef)1888{1889static const char *userField = feGetEnv("TR_UserField");1890if (!userField)1891{1892// In the absence of further analysis, treat everything as user fields1893setHasUserField(true);1894return;1895}18961897if ((!symRef->getSymbol()->isShadow() && (!symRef->getSymbol()->isStatic() || symRef->getSymbol()->isMethod() || symRef->getSymbol()->isConstObjectRef())) || symRef->getCPIndex() <= 0)1898return;18991900int32_t length;1901char * name = symRef->getOwningMethod(comp())->classNameOfFieldOrStatic(symRef->getCPIndex(), length);19021903if (name == NULL || length == 0)1904return;19051906TR_ASSERT(sizeof(pnames)/sizeof(char *) == _numNonUserFieldClasses,"Size of package names array is not correct\n");1907int32_t i;1908bool isNonUserField = false;1909for (i = 0; i < _numNonUserFieldClasses; i++)1910{1911if (!strncmp(pnames[i].name, name, strlen(pnames[i].name)))1912{1913isNonUserField = true;1914//printf ("User field symref %d name=%s length=%d cpindex=%d\n", symRef->getReferenceNumber(), name, length, symRef->getCPIndex());1915break;1916}1917}19181919if (isNonUserField)1920{1921// At the moment this is conservative. i.e. any field in any of the above packages will not be considered1922// a user field in any of the other packages. However it is possible to have fields from one package (or class) that we1923// may want to consider as a user field in another package (class) in which case having the different array elements1924// below would then be the way to acomplish this. The population of the array would need to be more selective.1925//1926}1927else1928{1929setHasUserField(true);1930for (i = 0; i < _numNonUserFieldClasses; i++)1931aliasBuilder.userFieldSymRefNumbers()[i]->set(symRef->getReferenceNumber());1932}1933}193419351936TR::SymbolReference *1937J9::SymbolReferenceTable::findOrCreateThreadLowTenureAddressSymbolRef()1938{1939if (!element(lowTenureAddressSymbol))1940{1941TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1942TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "lowTenureAddress");1943sym->setDataType(TR::Address);1944sym->setNotCollected();1945element(lowTenureAddressSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), lowTenureAddressSymbol, sym);1946element(lowTenureAddressSymbol)->setOffset(fej9->getThreadLowTenureAddressPointerOffset());1947}1948return element(lowTenureAddressSymbol);1949}195019511952TR::SymbolReference *1953J9::SymbolReferenceTable::findOrCreateThreadHighTenureAddressSymbolRef()1954{1955if (!element(highTenureAddressSymbol))1956{1957TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1958TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "highTenureAddress");1959sym->setDataType(TR::Address);1960sym->setNotCollected();1961element(highTenureAddressSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), highTenureAddressSymbol, sym);1962element(highTenureAddressSymbol)->setOffset(fej9->getThreadHighTenureAddressPointerOffset());1963}1964return element(highTenureAddressSymbol);1965}196619671968TR::SymbolReference *1969J9::SymbolReferenceTable::findOrCreateRamStaticsFromClassSymbolRef()1970{1971if (!element(ramStaticsFromClassSymbol))1972{1973TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1974TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);1975element(ramStaticsFromClassSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), ramStaticsFromClassSymbol, sym);1976element(ramStaticsFromClassSymbol)->setOffset(fej9->getOffsetOfRamStaticsFromClassField());1977sym->setNotCollected();1978}1979return element(ramStaticsFromClassSymbol);1980}198119821983TR::SymbolReference *1984J9::SymbolReferenceTable::findOrCreateJavaLangClassFromClassSymbolRef()1985{1986if (!element(javaLangClassFromClassSymbol))1987{1988TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());1989TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);1990element(javaLangClassFromClassSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), javaLangClassFromClassSymbol, sym);1991element(javaLangClassFromClassSymbol)->setOffset(fej9->getOffsetOfJavaLangClassFromClassField());1992}1993return element(javaLangClassFromClassSymbol);1994}199519961997TR::SymbolReference *1998J9::SymbolReferenceTable::findOrCreateClassFromJavaLangClassSymbolRef()1999{2000if (!element(classFromJavaLangClassSymbol))2001{2002TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2003TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);2004element(classFromJavaLangClassSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), classFromJavaLangClassSymbol, sym);2005element(classFromJavaLangClassSymbol)->setOffset(fej9->getOffsetOfClassFromJavaLangClassField());2006sym->setNotCollected();2007}2008return element(classFromJavaLangClassSymbol);2009}20102011TR::SymbolReference *2012J9::SymbolReferenceTable::findInitializeStatusFromClassSymbolRef()2013{2014return element(initializeStatusFromClassSymbol);2015}20162017TR::SymbolReference *2018J9::SymbolReferenceTable::findOrCreateInitializeStatusFromClassSymbolRef()2019{2020if (!element(initializeStatusFromClassSymbol))2021{2022TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2023TR::Symbol * sym = NULL;2024if (self()->comp()->target().is64Bit())2025sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);2026else2027sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);2028element(initializeStatusFromClassSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), initializeStatusFromClassSymbol, sym);2029element(initializeStatusFromClassSymbol)->setOffset(fej9->getOffsetOfInitializeStatusFromClassField());2030}2031return element(initializeStatusFromClassSymbol);2032}20332034TR::SymbolReference *2035J9::SymbolReferenceTable::findOrCreateClassRomPtrSymbolRef()2036{2037if (!element(classRomPtrSymbol))2038{2039TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2040TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);2041element(classRomPtrSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), classRomPtrSymbol, sym);2042element(classRomPtrSymbol)->setOffset(fej9->getOffsetOfClassRomPtrField());2043if (!TR::Compiler->cls.romClassObjectsMayBeCollected())2044sym->setNotCollected();2045}2046return element(classRomPtrSymbol);2047}204820492050TR::SymbolReference *2051J9::SymbolReferenceTable::findOrCreateGlobalFragmentSymbolRef()2052{2053if (!element(globalFragmentSymbol))2054{2055TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2056TR::Symbol * sym;2057if (self()->comp()->target().is64Bit())2058sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int64);2059else2060sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int32);2061sym->setGlobalFragmentShadowSymbol();2062element(globalFragmentSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), globalFragmentSymbol, sym);2063element(globalFragmentSymbol)->setOffset(fej9->getRememberedSetGlobalFragmentOffset());2064}2065return element(globalFragmentSymbol);2066}206720682069TR::SymbolReference *2070J9::SymbolReferenceTable::findOrCreateFragmentParentSymbolRef()2071{2072if (!element(fragmentParentSymbol))2073{2074TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2075TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "FragmentParent");2076sym->setDataType(TR::Address);2077sym->setNotCollected();2078element(fragmentParentSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), fragmentParentSymbol, sym);2079element(fragmentParentSymbol)->setOffset(fej9->thisThreadRememberedSetFragmentOffset() + fej9->getFragmentParentOffset());2080}2081return element(fragmentParentSymbol);2082}208320842085TR::SymbolReference *2086J9::SymbolReferenceTable::findOrCreateThreadDebugEventData(int32_t index)2087{2088TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2089intptr_t offset = fej9->getThreadDebugEventDataOffset(index);2090ListIterator<TR::SymbolReference> li(&_currentThreadDebugEventDataSymbolRefs);2091TR::SymbolReference * symRef;2092for (symRef = li.getFirst(); symRef; symRef = li.getNext())2093if (symRef->getOffset() == offset)2094return symRef;20952096// Not found; create2097if (!_currentThreadDebugEventDataSymbol)2098{2099_currentThreadDebugEventDataSymbol = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "debugEventData");2100_currentThreadDebugEventDataSymbol->setDataType(TR::Address);2101_currentThreadDebugEventDataSymbol->setNotCollected();2102}2103TR::SymbolReference *result = new (trHeapMemory()) TR::SymbolReference(self(), _currentThreadDebugEventDataSymbol, offset);2104_currentThreadDebugEventDataSymbolRefs.add(result);2105return result;2106}21072108TR::SymbolReference *2109J9::SymbolReferenceTable::findUnsafeSymbolRef(TR::DataType type, bool javaObjectReference, bool javaStaticReference, bool isVolatile)2110{2111TR_Array<TR::SymbolReference *> * unsafeSymRefs = NULL;21122113if (isVolatile)2114{2115unsafeSymRefs =2116javaStaticReference ?2117_unsafeJavaStaticVolatileSymRefs :2118_unsafeVolatileSymRefs;2119}2120else2121{2122unsafeSymRefs =2123javaStaticReference ?2124_unsafeJavaStaticSymRefs :2125_unsafeSymRefs;2126}21272128TR::SymbolReference * symRef = NULL;21292130if (unsafeSymRefs != NULL)2131{2132symRef = (*unsafeSymRefs)[type];2133}21342135return symRef;2136}21372138TR::SymbolReference *2139J9::SymbolReferenceTable::findOrCreateUnsafeSymbolRef(TR::DataType type, bool javaObjectReference, bool javaStaticReference, bool isVolatile)2140{2141TR_Array<TR::SymbolReference *> * unsafeSymRefs = NULL;21422143if (isVolatile)2144{2145if (javaStaticReference)2146{2147if (_unsafeJavaStaticVolatileSymRefs == NULL)2148_unsafeJavaStaticVolatileSymRefs = new (trHeapMemory()) TR_Array<TR::SymbolReference *>(comp()->trMemory(), TR::NumTypes);2149unsafeSymRefs = _unsafeJavaStaticVolatileSymRefs;2150}2151else2152{2153if (_unsafeVolatileSymRefs == NULL)2154_unsafeVolatileSymRefs = new (trHeapMemory()) TR_Array<TR::SymbolReference *>(comp()->trMemory(), TR::NumTypes);2155unsafeSymRefs = _unsafeVolatileSymRefs;2156}2157}2158else2159{2160if (javaStaticReference)2161{2162if (_unsafeJavaStaticSymRefs == NULL)2163_unsafeJavaStaticSymRefs = new (trHeapMemory()) TR_Array<TR::SymbolReference *>(comp()->trMemory(), TR::NumTypes);2164unsafeSymRefs = _unsafeJavaStaticSymRefs;2165}2166else2167{2168if (_unsafeSymRefs == NULL)2169_unsafeSymRefs = new (trHeapMemory()) TR_Array<TR::SymbolReference *>(comp()->trMemory(), TR::NumTypes);2170unsafeSymRefs = _unsafeSymRefs;2171}2172}21732174TR::SymbolReference * symRef = (*unsafeSymRefs)[type];21752176if (symRef == NULL)2177{2178TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(),type);2179sym->setUnsafeShadowSymbol();2180sym->setArrayShadowSymbol();2181if (isVolatile)2182sym->setVolatile();2183(*unsafeSymRefs)[type] = symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, comp()->getMethodSymbol()->getResolvedMethodIndex(), -1);2184aliasBuilder.unsafeSymRefNumbers().set(symRef->getReferenceNumber());2185}21862187// For unsafe symbols created by a call that contained an object and an offset we'll alias2188// the symbol against all shadow and statics. If the Unsafe symbol was created using only an2189// address then we won't alias against other Java objects.2190//2191if (javaObjectReference)2192comp()->setHasUnsafeSymbol();2193else2194symRef->setReallySharesSymbol();21952196return symRef;2197}219821992200void2201J9::SymbolReferenceTable::performClassLookahead(TR_PersistentClassInfo *classInfo, TR_ResolvedMethod *method)2202{2203// Do not perform class lookahead when peeking (including recursive class lookahead)2204//2205((TR_J9ByteCodeIlGenerator *)(comp()->getCurrentIlGenerator()))->performClassLookahead(classInfo);2206}220722082209int32_t2210J9::SymbolReferenceTable::userFieldMethodId(TR::MethodSymbol *methodSymbol)2211{2212static const char *userField = feGetEnv("TR_UserField");2213if (userField)2214{2215TR::RecognizedMethod method = methodSymbol->getRecognizedMethod();2216if (method == TR::java_util_HashMap_rehash)2217return J9::nonUser_java_util_HashMap_rehash - 1;2218else if (method == TR::java_util_HashMap_analyzeMap)2219return J9::nonUser_java_util_HashMap_analyzeMap - 1;2220else if (method == TR::java_util_HashMap_calculateCapacity)2221return J9::nonUser_java_util_HashMap_calculateCapacity - 1;2222else if (method == TR::java_util_HashMap_findNullKeyEntry)2223return J9::nonUser_java_util_HashMap_findNullKeyEntry - 1;2224}2225return -1;2226}222722282229int32_t2230J9::SymbolReferenceTable::immutableConstructorId(TR::MethodSymbol *methodSymbol)2231{2232TR::RecognizedMethod method = methodSymbol->getRecognizedMethod();2233switch (method)2234{2235case TR::java_lang_String_init_String:2236case TR::java_lang_String_init_String_char:2237case TR::java_lang_String_init_int_int_char_boolean:2238// All String constructors share the same ID2239method = TR::java_lang_String_init;2240break;2241default:2242break;2243}22442245if (TR::java_lang_Boolean_init <= method && method <= TR::java_lang_String_init)2246return method - TR::java_lang_Boolean_init;2247else2248return -1;2249}225022512252bool2253J9::SymbolReferenceTable::isImmutable(TR::SymbolReference *symRef)2254{2255if (!_hasImmutable)2256return false;22572258int32_t i;2259for (i = 0; i < _numImmutableClasses; i++)2260{2261if (_immutableSymRefNumbers[i]->get(symRef->getReferenceNumber()))2262return true;2263}22642265ListElement<TR_ImmutableInfo> *immutableClassInfoElem = _immutableInfo.getListHead();2266while (immutableClassInfoElem)2267{2268TR_ImmutableInfo *immutableClassInfo = immutableClassInfoElem->getData();2269if (immutableClassInfo->_immutableSymRefNumbers->get(symRef->getReferenceNumber()))2270return true;2271immutableClassInfoElem = immutableClassInfoElem->getNextElement();2272}22732274return false;2275}227622772278TR_ImmutableInfo *2279J9::SymbolReferenceTable::findOrCreateImmutableInfo(TR_OpaqueClassBlock *clazz)2280{2281ListElement<TR_ImmutableInfo> *immutableClassInfoElem = _immutableInfo.getListHead();2282while (immutableClassInfoElem)2283{2284TR_ImmutableInfo *immutableClassInfo = immutableClassInfoElem->getData();2285if (immutableClassInfo->_clazz == clazz)2286return immutableClassInfo;2287immutableClassInfoElem = immutableClassInfoElem->getNextElement();2288}22892290TR_ImmutableInfo *newImmutableInfo = new (trHeapMemory()) TR_ImmutableInfo(clazz,2291new (trHeapMemory()) TR_BitVector(_size_hint, comp()->trMemory(), heapAlloc, growable),2292NULL);2293_immutableInfo.add(newImmutableInfo);2294return newImmutableInfo;2295}229622972298void2299J9::SymbolReferenceTable::checkImmutable(TR::SymbolReference *symRef)2300{2301if (!symRef->getSymbol()->isShadow() || symRef->getCPIndex() < 0)2302return;23032304int32_t length;2305char * name = symRef->getOwningMethod(comp())->classNameOfFieldOrStatic(symRef->getCPIndex(), length);23062307if (name == NULL || length == 0)2308return;23092310static struct N { const char * name; } names[] =2311{2312"java/lang/Boolean",2313"java/lang/Character",2314"java/lang/Byte",2315"java/lang/Short",2316"java/lang/Integer",2317"java/lang/Long",2318"java/lang/Float",2319"java/lang/Double",2320"java/lang/String"2321};23222323if (!comp()->getOption(TR_DisableImmutableFieldAliasing))2324{2325TR_ASSERT(sizeof(names)/sizeof(char *) == _numImmutableClasses,"Size of names array is not correct\n");2326int32_t i;2327for (i = 0; i < _numImmutableClasses; i++)2328{2329if (strcmp(names[i].name, name) == 0)2330{2331_hasImmutable = true;2332_immutableSymRefNumbers[i]->set(symRef->getReferenceNumber());2333break;2334}2335}2336}23372338if (true)2339{2340if (!symRef->getSymbol()->isArrayShadowSymbol())2341{2342TR::Symbol *sym = symRef->getSymbol();2343if (sym->isPrivate() || sym->isFinal())2344{2345int32_t len;2346char *classNameOfFieldOrStatic = symRef->getOwningMethod(comp())->classNameOfFieldOrStatic(symRef->getCPIndex(), len);2347TR_OpaqueClassBlock * classOfStatic = comp()->fe()->getClassFromSignature(classNameOfFieldOrStatic, len, symRef->getOwningMethod(comp()));23482349bool isClassInitialized = false;2350TR_PersistentClassInfo * classInfo =2351comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(classOfStatic, comp());2352if (classInfo && classInfo->isInitialized())2353isClassInitialized = true;23542355if ((classOfStatic != comp()->getSystemClassPointer()) &&2356isClassInitialized && TR::Compiler->cls.isClassFinal(comp(), classOfStatic))2357{2358if (!classInfo->getFieldInfo() &&2359(comp()->getMethodHotness() >= hot))2360{2361performClassLookahead(classInfo, symRef->getOwningMethod(comp()));2362}23632364if (classInfo->getFieldInfo())2365{2366TR_PersistentFieldInfo * fieldInfo = classInfo->getFieldInfo()->find(comp(), sym, symRef);2367if (fieldInfo && fieldInfo->isImmutable())2368{2369setHasImmutable(true);2370TR_ImmutableInfo *clazzImmutableInfo = findOrCreateImmutableInfo(classOfStatic);2371clazzImmutableInfo->_immutableSymRefNumbers->set(symRef->getReferenceNumber());2372}2373}2374}2375}2376}2377}2378}237923802381TR::SymbolReference *2382J9::SymbolReferenceTable::findOrCreateImmutableGenericIntShadowSymbolReference(intptr_t offset)2383{2384static char *disableImmutableIntShadows = feGetEnv("TR_disableImmutableIntShadows");2385if (disableImmutableIntShadows)2386return findOrCreateGenericIntShadowSymbolReference(offset);2387TR::SymbolReference * symRef = new (trHeapMemory()) TR::SymbolReference(self(), findOrCreateGenericIntShadowSymbol(), comp()->getMethodSymbol()->getResolvedMethodIndex(), -1);2388symRef->setOffset(offset);2389return symRef;2390}23912392TR::SymbolReference *2393J9::SymbolReferenceTable::findOrCreateCheckCastForArrayStoreSymbolRef(TR::ResolvedMethodSymbol *)2394{2395return findOrCreateRuntimeHelper(TR_checkCastForArrayStore, false, true, true);2396}2397239823992400TR::SymbolReference *2401J9::SymbolReferenceTable::findOrCreateProfilingBufferCursorSymbolRef()2402{2403if (!element(profilingBufferCursorSymbol))2404{2405TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2406TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "ProfilingBufferCursor");2407sym->setDataType(TR::Address);2408element(profilingBufferCursorSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), profilingBufferCursorSymbol, sym);2409element(profilingBufferCursorSymbol)->setOffset(fej9->thisThreadGetProfilingBufferCursorOffset());24102411// We can't let the load/store of the exception symbol swing down2412aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(profilingBufferCursorSymbol)); // add the symRef to the statics list to get correct aliasing info2413}2414return element(profilingBufferCursorSymbol);2415}241624172418TR::SymbolReference *2419J9::SymbolReferenceTable::findOrCreateProfilingBufferEndSymbolRef()2420{2421if (!element(profilingBufferEndSymbol))2422{2423TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2424TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(),"profilingBufferEnd");2425sym->setDataType(TR::Address);2426element(profilingBufferEndSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), profilingBufferEndSymbol, sym);2427element(profilingBufferEndSymbol)->setOffset(fej9->thisThreadGetProfilingBufferEndOffset());24282429// We can't let the load/store of the exception symbol swing down2430aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(profilingBufferEndSymbol)); // add the symRef to the statics list to get correct aliasing info2431}2432return element(profilingBufferEndSymbol);2433}24342435TR::SymbolReference *2436J9::SymbolReferenceTable::findOrCreateVMThreadTempSlotFieldSymbolRef()2437{2438if (!element(j9VMThreadTempSlotFieldSymbol))2439{2440TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2441TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "j9VMThreadTempSlotField");2442sym->setDataType(TR::Address);2443element(j9VMThreadTempSlotFieldSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), j9VMThreadTempSlotFieldSymbol, sym);2444element(j9VMThreadTempSlotFieldSymbol)->setOffset(fej9->thisThreadGetTempSlotOffset());2445aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(j9VMThreadTempSlotFieldSymbol));2446}2447return element(j9VMThreadTempSlotFieldSymbol);2448}24492450TR::SymbolReference *2451J9::SymbolReferenceTable::findOrCreateProfilingBufferSymbolRef(intptr_t offset)2452{2453if (!element(profilingBufferSymbol))2454{2455TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory());2456sym->setDataType(TR::Int32);2457TR::SymbolReference *symRef = new (trHeapMemory()) TR::SymbolReference(self(), profilingBufferSymbol, sym);2458element(profilingBufferSymbol) = symRef;2459element(profilingBufferSymbol)->setOffset(offset);2460}2461return element(profilingBufferSymbol);2462}246324642465TR::SymbolReference *2466J9::SymbolReferenceTable::findShadowSymbol(TR_ResolvedMethod * owningMethod, int32_t cpIndex, TR::DataType type, TR::Symbol::RecognizedField *recognizedField)2467{2468TR::SymbolReference * symRef;2469TR_SymRefIterator i(type == TR::Address ? aliasBuilder.addressShadowSymRefs() :2470(type == TR::Int32 ? aliasBuilder.intShadowSymRefs() : aliasBuilder.nonIntPrimitiveShadowSymRefs()), self());2471while ((symRef = i.getNext()) != NULL)2472{2473if ((recognizedField &&2474*recognizedField != TR::Symbol::UnknownField &&2475*recognizedField == symRef->getSymbol()->getRecognizedField())||2476(symRef->getSymbol()->getDataType() == type &&2477symRef->getCPIndex() != -1 &&2478cpIndex != -1 &&2479TR::Compiler->cls.jitFieldsAreSame(comp(), owningMethod, cpIndex,2480symRef->getOwningMethod(comp()), symRef->getCPIndex(), symRef->getSymbol()->isStatic())))2481{2482if (cpIndex != -1 && owningMethod->classOfMethod() != symRef->getOwningMethod(comp())->classOfMethod())2483{2484bool isVolatile = true, isFinal = false, isPrivate = false, isUnresolvedInCP ;2485TR::DataType type = TR::DataTypes::NoType;2486uint32_t offset = 0;2487// isStore is a hardcoded false here since we only really want to set hasBeenAccessed correctly2488bool resolved = owningMethod->fieldAttributes(comp(), cpIndex, &offset, &type, &isVolatile, &isFinal, &isPrivate, false, &isUnresolvedInCP, true);2489symRef->setHasBeenAccessedAtRuntime(isUnresolvedInCP ? TR_no : TR_maybe);2490}2491return symRef;2492}2493}2494return 0;2495}249624972498TR::SymbolReference *2499J9::SymbolReferenceTable::findOrCreateClassIsArraySymbolRef()2500{2501if (!element(isArraySymbol))2502{2503TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2504TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);2505element(isArraySymbol) = new (trHeapMemory()) TR::SymbolReference(self(), isArraySymbol, sym);2506element(isArraySymbol)->setOffset(fej9->getOffsetOfIsArrayFieldFromRomClass());2507}2508return element(isArraySymbol);2509}251025112512TR::SymbolReference *2513J9::SymbolReferenceTable::findOrCreateArrayComponentTypeSymbolRef()2514{2515if (!element(componentClassSymbol))2516{2517TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2518TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);2519element(componentClassSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), componentClassSymbol, sym);2520element(componentClassSymbol)->setOffset(fej9->getOffsetOfArrayComponentTypeField());2521if (!TR::Compiler->cls.classObjectsMayBeCollected())2522sym->setNotCollected();2523}2524return element(componentClassSymbol);2525}25262527TR::SymbolReference *2528J9::SymbolReferenceTable::findOrCreateVMThreadFloatTemp1SymbolRef()2529{2530if (!element(j9VMThreadFloatTemp1Symbol))2531{2532TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());2533TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "j9VMThreadFloatTemp1");2534sym->setDataType(TR::Address);2535element(j9VMThreadFloatTemp1Symbol) = new (trHeapMemory()) TR::SymbolReference(self(), j9VMThreadFloatTemp1Symbol, sym);2536element(j9VMThreadFloatTemp1Symbol)->setOffset(fej9->thisThreadGetFloatTemp1Offset());2537aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(j9VMThreadFloatTemp1Symbol));2538}2539return element(j9VMThreadFloatTemp1Symbol);2540}25412542TR::SymbolReference *2543J9::SymbolReferenceTable::findOrCreateObjectInequalityComparisonSymbolRef()2544{2545TR::SymbolReference *symRef = element(objectInequalityComparisonSymbol);2546if (symRef != NULL)2547return symRef;25482549symRef = self()->findOrCreateCodeGenInlinedHelper(objectInequalityComparisonSymbol);2550symRef->setCanGCandReturn();2551symRef->setCanGCandExcept();2552return symRef;2553}25542555TR::SymbolReference *2556J9::SymbolReferenceTable::findOrCreateObjectEqualityComparisonSymbolRef()2557{2558TR::SymbolReference *symRef = element(objectEqualityComparisonSymbol);2559if (symRef != NULL)2560return symRef;25612562symRef = self()->findOrCreateCodeGenInlinedHelper(objectEqualityComparisonSymbol);2563symRef->setCanGCandReturn();2564symRef->setCanGCandExcept();2565return symRef;2566}25672568TR::SymbolReference *2569J9::SymbolReferenceTable::findOrCreateEncodeASCIISymbolRef()2570{2571TR::SymbolReference *symRef = element(encodeASCIISymbol);2572if (symRef != NULL)2573return symRef;25742575symRef = self()->findOrCreateCodeGenInlinedHelper(encodeASCIISymbol);2576return symRef;2577}25782579TR::SymbolReference *2580J9::SymbolReferenceTable::findOrCreateNonNullableArrayNullStoreCheckSymbolRef()2581{2582TR::SymbolReference *symRef = element(nonNullableArrayNullStoreCheckSymbol);2583if (symRef != NULL)2584return symRef;25852586symRef = self()->findOrCreateCodeGenInlinedHelper(nonNullableArrayNullStoreCheckSymbol);2587symRef->setCanGCandExcept();2588return symRef;2589}25902591TR::ParameterSymbol *2592J9::SymbolReferenceTable::createParameterSymbol(2593TR::ResolvedMethodSymbol *owningMethodSymbol,2594int32_t slot,2595TR::DataType type,2596TR::KnownObjectTable::Index knownObjectIndex)2597{2598TR::ParameterSymbol * sym = TR::ParameterSymbol::create(trHeapMemory(),type,slot);25992600if (comp()->getOption(TR_MimicInterpreterFrameShape))2601{2602int32_t parameterSlots = owningMethodSymbol->getNumParameterSlots();2603sym->setGCMapIndex(-slot + parameterSlots - sym->getNumberOfSlots());2604}26052606TR::SymbolReference *symRef = NULL;2607if (knownObjectIndex == TR::KnownObjectTable::UNKNOWN)2608symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), slot);2609else2610symRef = createTempSymRefWithKnownObject(sym, owningMethodSymbol->getResolvedMethodIndex(), slot, knownObjectIndex);26112612owningMethodSymbol->setParmSymRef(slot, symRef);2613if (!parmSlotCameFromExpandingAnArchetypeArgPlaceholder(slot, owningMethodSymbol))2614owningMethodSymbol->getAutoSymRefs(slot).add(symRef);26152616return sym;2617}26182619TR::SymbolReference *2620J9::SymbolReferenceTable::findArrayClassRomPtrSymbolRef()2621{2622return element(arrayClassRomPtrSymbol);2623}26242625TR::SymbolReference *2626J9::SymbolReferenceTable::findClassRomPtrSymbolRef()2627{2628return element(classRomPtrSymbol);2629}26302631const char *J9::SymbolReferenceTable::_commonNonHelperSymbolNames[] =2632{2633"<classRomPtr>",2634"<ramStaticsFromClass>",2635"<componentClassAsPrimitive>",2636"<initializeStatusFromClass>",2637"<threadPrivateFlags>",2638"<arrayletSpineFirstElement>",2639"<dltBlock>",2640"<classFromJavaLangClassAsPrimitive>",2641"<javaVM>",2642"<j9methodExtraField>",2643"<j9methodConstantPoolField>",2644"<startPCLinkageInfo>",2645"<instanceShapeFromROMClass>",2646"<j9VMThreadTempSlotField>"2647};264826492650const char *2651J9::SymbolReferenceTable::getNonHelperSymbolName(CommonNonhelperSymbol nonHelper)2652{2653#ifdef OMR_ENABLE_NONHELPER_EXTENSIBLE_ENUM2654TR_ASSERT_FATAL(nonHelper <= J9lastNonhelperSymbol, "unknown nonhelper %" OMR_PRId32, static_cast<int32_t>(nonHelper));26552656static_assert(sizeof(_commonNonHelperSymbolNames)/sizeof(_commonNonHelperSymbolNames[0]) ==2657static_cast<int32_t>(J9lastNonhelperSymbol - J9firstNonhelperSymbol + 1),2658"_commonNonHelperSymbolNames array must match CommonNonHelperSymbol enumeration");26592660if (nonHelper >= J9firstNonhelperSymbol)2661{2662return _commonNonHelperSymbolNames[static_cast<int32_t>(nonHelper - J9firstNonhelperSymbol)];2663}2664else2665{2666return OMR::SymbolReferenceTableConnector::getNonHelperSymbolName(nonHelper);2667}2668#else2669return NULL;2670#endif2671}267226732674