Path: blob/master/runtime/compiler/p/codegen/J9AheadOfTimeCompile.cpp
6004 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 "codegen/AheadOfTimeCompile.hpp"23#include "codegen/CodeGenerator.hpp"24#include "env/FrontEnd.hpp"25#include "codegen/Instruction.hpp"26#include "compile/AOTClassInfo.hpp"27#include "compile/Compilation.hpp"28#include "compile/ResolvedMethod.hpp"29#include "compile/VirtualGuard.hpp"30#include "env/CHTable.hpp"31#include "env/ClassLoaderTable.hpp"32#include "env/CompilerEnv.hpp"33#include "env/SharedCache.hpp"34#include "env/jittypes.h"35#include "env/VMJ9.h"36#include "il/LabelSymbol.hpp"37#include "il/Node.hpp"38#include "il/Node_inlines.hpp"39#include "il/SymbolReference.hpp"40#include "ras/DebugCounter.hpp"41#include "runtime/RelocationRuntime.hpp"42#include "runtime/RelocationRecord.hpp"43#include "runtime/SymbolValidationManager.hpp"4445J9::Power::AheadOfTimeCompile::AheadOfTimeCompile(TR::CodeGenerator *cg) :46J9::AheadOfTimeCompile(NULL, cg->comp()),47_cg(cg)48{49}5051void J9::Power::AheadOfTimeCompile::processRelocations()52{53TR::Compilation *comp = _cg->comp();54TR_J9VMBase *fej9 = (TR_J9VMBase *)(_cg->fe());55TR::IteratedExternalRelocation *r;5657for (auto iterator = getRelocationList().begin(); iterator != getRelocationList().end(); ++iterator)58(*iterator)->mapRelocation(_cg);5960auto aotIterator = _cg->getExternalRelocationList().begin();61while (aotIterator != _cg->getExternalRelocationList().end())62{63(*aotIterator)->addExternalRelocation(_cg);64++aotIterator;65}6667for (r = getAOTRelocationTargets().getFirst(); r != NULL; r = r->getNext())68{69addToSizeOfAOTRelocations(r->getSizeOfRelocationData());70}7172// now allocate the memory size of all iterated relocations + the header (total length field)7374// Note that when using the SymbolValidationManager, the well-known classes75// must be checked even if no explicit records were generated, since they76// might be responsible for the lack of records.77bool useSVM = comp->getOption(TR_UseSymbolValidationManager);78if (self()->getSizeOfAOTRelocations() != 0 || useSVM)79{80// It would be more straightforward to put the well-known classes offset81// in the AOT method header, but that would use space for AOT bodies that82// don't use the SVM. TODO: Move it once SVM takes over?83int wellKnownClassesOffsetSize = useSVM ? SIZEPOINTER : 0;84uintptr_t reloBufferSize =85self()->getSizeOfAOTRelocations() + SIZEPOINTER + wellKnownClassesOffsetSize;86uint8_t *relocationDataCursor = self()->setRelocationData(87fej9->allocateRelocationData(comp, reloBufferSize));88// set up the size for the region89*(uintptr_t*)relocationDataCursor = reloBufferSize;90relocationDataCursor += SIZEPOINTER;9192if (useSVM)93{94TR::SymbolValidationManager *svm = comp->getSymbolValidationManager();95void *offsets = const_cast<void *>(svm->wellKnownClassChainOffsets());96uintptr_t *wkcOffsetAddr = (uintptr_t *)relocationDataCursor;97*wkcOffsetAddr = self()->offsetInSharedCacheFromPointer(fej9->sharedCache(), offsets);98#if defined(J9VM_OPT_JITSERVER)99self()->addWellKnownClassesSerializationRecord(svm->aotCacheWellKnownClassesRecord(), wkcOffsetAddr);100#endif /* defined(J9VM_OPT_JITSERVER) */101relocationDataCursor += SIZEPOINTER;102}103104// set up pointers for each iterated relocation and initialize header105TR::IteratedExternalRelocation *s;106for (s = getAOTRelocationTargets().getFirst(); s != NULL; s = s->getNext())107{108s->setRelocationData(relocationDataCursor);109s->initializeRelocation(_cg);110relocationDataCursor += s->getSizeOfRelocationData();111}112}113}114115bool116J9::Power::AheadOfTimeCompile::initializePlatformSpecificAOTRelocationHeader(TR::IteratedExternalRelocation *relocation,117TR_RelocationTarget *reloTarget,118TR_RelocationRecord *reloRecord,119uint8_t targetKind)120{121bool platformSpecificReloInitialized = true;122TR::Compilation *comp = self()->comp();123TR_J9VMBase *fej9 = comp->fej9();124TR_SharedCache *sharedCache = fej9->sharedCache();125uint8_t * aotMethodCodeStart = (uint8_t *) comp->getRelocatableMethodCodeStart();126127switch (targetKind)128{129case TR_ClassAddress:130{131TR_RelocationRecordClassAddress *caRecord = reinterpret_cast<TR_RelocationRecordClassAddress *>(reloRecord);132TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation*) relocation->getTargetAddress();133134TR::SymbolReference *symRef = reinterpret_cast<TR::SymbolReference *>(recordInfo->data1);135uintptr_t inlinedSiteIndex = reinterpret_cast<uintptr_t>(recordInfo->data2);136uint8_t flags = static_cast<uint8_t>(recordInfo->data3);137138void *constantPool = symRef->getOwningMethod(comp)->constantPool();139inlinedSiteIndex = self()->findCorrectInlinedSiteIndex(constantPool, inlinedSiteIndex);140141TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");142caRecord->setReloFlags(reloTarget, flags);143caRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex);144caRecord->setConstantPool(reloTarget, reinterpret_cast<uintptr_t>(constantPool));145caRecord->setCpIndex(reloTarget, symRef->getCPIndex());146}147break;148149case TR_DataAddress:150{151TR_RelocationRecordDataAddress *daRecord = reinterpret_cast<TR_RelocationRecordDataAddress *>(reloRecord);152TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation*) relocation->getTargetAddress();153154TR::SymbolReference *symRef = reinterpret_cast<TR::SymbolReference *>(recordInfo->data1);155uintptr_t inlinedSiteIndex = reinterpret_cast<uintptr_t>(recordInfo->data2);156uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(recordInfo->data3));157158void *constantPool = symRef->getOwningMethod(comp)->constantPool();159inlinedSiteIndex = self()->findCorrectInlinedSiteIndex(constantPool, inlinedSiteIndex);160161TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");162daRecord->setReloFlags(reloTarget, flags);163daRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex);164daRecord->setConstantPool(reloTarget, reinterpret_cast<uintptr_t>(constantPool));165daRecord->setCpIndex(reloTarget, symRef->getCPIndex());166daRecord->setOffset(reloTarget, symRef->getOffset());167}168break;169170case TR_AbsoluteHelperAddress:171{172TR_RelocationRecordAbsoluteHelperAddress *ahaRecord = reinterpret_cast<TR_RelocationRecordAbsoluteHelperAddress *>(reloRecord);173TR::SymbolReference *symRef = reinterpret_cast<TR::SymbolReference *>(relocation->getTargetAddress());174uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));175176ahaRecord->setHelperID(reloTarget, static_cast<uint32_t>(symRef->getReferenceNumber()));177ahaRecord->setReloFlags(reloTarget, flags);178}179break;180181case TR_AbsoluteMethodAddressOrderedPair:182{183TR_RelocationRecordMethodAddress *maRecord = reinterpret_cast<TR_RelocationRecordMethodAddress *>(reloRecord);184185TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation *) relocation->getTargetAddress();186uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(recordInfo->data3));187188TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");189maRecord->setReloFlags(reloTarget, flags);190}191break;192193case TR_FixedSequenceAddress:194{195TR_RelocationRecordWithOffset *rwoRecord = reinterpret_cast<TR_RelocationRecordWithOffset *>(reloRecord);196197TR::LabelSymbol *table = reinterpret_cast<TR::LabelSymbol *>(relocation->getTargetAddress());198uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));199uint8_t *codeLocation = table->getCodeLocation();200201TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");202rwoRecord->setReloFlags(reloTarget, flags);203if (comp->target().is64Bit())204{205rwoRecord->setOffset(reloTarget, static_cast<uintptr_t>(codeLocation - aotMethodCodeStart));206}207else208{209TR_ASSERT_FATAL(false, "Creating TR_FixedSeqAddress/TR_FixedSeq2Address relo for 32-bit target");210}211}212break;213214case TR_FixedSequenceAddress2:215{216TR_RelocationRecordWithOffset *rwoRecord = reinterpret_cast<TR_RelocationRecordWithOffset *>(reloRecord);217uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));218219TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");220rwoRecord->setReloFlags(reloTarget, flags);221if (comp->target().is64Bit())222{223TR_ASSERT_FATAL(relocation->getTargetAddress(), "target address is NULL");224225uintptr_t offset = relocation->getTargetAddress()226? static_cast<uintptr_t>(relocation->getTargetAddress() - aotMethodCodeStart)227: 0x0;228229rwoRecord->setOffset(reloTarget, offset);230}231else232{233TR_ASSERT_FATAL(0, "Creating TR_LoadAddress/TR_LoadAddressTempReg relo for 32-bit target");234}235}236break;237238case TR_ArrayCopyHelper:239case TR_ArrayCopyToc:240case TR_BodyInfoAddressLoad:241case TR_RecompQueuedFlag:242{243TR_RelocationRecord *rRecord = reinterpret_cast<TR_RelocationRecord *>(reloRecord);244uint8_t flags;245246if (comp->target().is64Bit())247{248flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));249}250else251{252TR_RelocationRecordInformation *recordInfo = reinterpret_cast<TR_RelocationRecordInformation *>(relocation->getTargetAddress());253flags = static_cast<uint8_t>(recordInfo->data3);254}255256TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");257rRecord->setReloFlags(reloTarget, flags);258}259break;260261case TR_RamMethodSequence:262{263TR_RelocationRecordRamSequence *rsRecord = reinterpret_cast<TR_RelocationRecordRamSequence *>(reloRecord);264uint8_t flags;265266if (comp->target().is64Bit())267{268flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));269270TR_ASSERT_FATAL(relocation->getTargetAddress(), "target address is NULL");271272uintptr_t offset = relocation->getTargetAddress()273? static_cast<uintptr_t>(relocation->getTargetAddress() - aotMethodCodeStart)274: 0x0;275276rsRecord->setOffset(reloTarget, offset);277}278else279{280TR_RelocationRecordInformation *recordInfo = reinterpret_cast<TR_RelocationRecordInformation *>(relocation->getTargetAddress());281flags = static_cast<uint8_t>(recordInfo->data3);282283// Skip Offset284}285286TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");287rsRecord->setReloFlags(reloTarget, flags);288}289break;290291case TR_ArbitraryClassAddress:292{293TR_RelocationRecordArbitraryClassAddress *acaRecord = reinterpret_cast<TR_RelocationRecordArbitraryClassAddress *>(reloRecord);294295// ExternalRelocation data is as expected for TR_ClassAddress296TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation *)relocation->getTargetAddress();297298auto symRef = (TR::SymbolReference *)recordInfo->data1;299auto sym = symRef->getSymbol()->castToStaticSymbol();300auto j9class = (TR_OpaqueClassBlock *)sym->getStaticAddress();301uint8_t flags = (uint8_t)recordInfo->data3;302uintptr_t inlinedSiteIndex = self()->findCorrectInlinedSiteIndex(symRef->getOwningMethod(comp)->constantPool(), recordInfo->data2);303304uintptr_t classChainIdentifyingLoaderOffsetInSharedCache = sharedCache->getClassChainOffsetIdentifyingLoader(j9class);305const AOTCacheClassChainRecord *classChainRecord = NULL;306uintptr_t classChainOffsetInSharedCache = self()->getClassChainOffset(j9class, classChainRecord);307308TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits");309acaRecord->setReloFlags(reloTarget, flags);310acaRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex);311acaRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainIdentifyingLoaderOffsetInSharedCache,312self(), classChainRecord);313acaRecord->setClassChainForInlinedMethod(reloTarget, classChainOffsetInSharedCache, self(), classChainRecord);314}315break;316317case TR_GlobalValue:318{319TR_RelocationRecordGlobalValue *gvRecord = reinterpret_cast<TR_RelocationRecordGlobalValue *>(reloRecord);320321uintptr_t gv;322uint8_t flags;323324if (comp->target().is64Bit())325{326gv = reinterpret_cast<uintptr_t>(relocation->getTargetAddress());327flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));328}329else330{331TR_RelocationRecordInformation *recordInfo = reinterpret_cast<TR_RelocationRecordInformation*>(relocation->getTargetAddress());332gv = recordInfo->data1;333flags = static_cast<uint8_t>(recordInfo->data3);334}335336TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");337gvRecord->setReloFlags(reloTarget, flags);338gvRecord->setOffset(reloTarget, gv);339}340break;341342case TR_DiscontiguousSymbolFromManager:343{344TR_RelocationRecordDiscontiguousSymbolFromManager *dsfmRecord = reinterpret_cast<TR_RelocationRecordDiscontiguousSymbolFromManager *>(reloRecord);345346TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation*) relocation->getTargetAddress();347348uint8_t *symbol = (uint8_t *)recordInfo->data1;349uint16_t symbolID = comp->getSymbolValidationManager()->getSymbolIDFromValue(static_cast<void *>(symbol));350351uint16_t symbolType = (uint16_t)recordInfo->data2;352353uint8_t flags = (uint8_t) recordInfo->data3;354TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");355356dsfmRecord->setSymbolID(reloTarget, symbolID);357dsfmRecord->setSymbolType(reloTarget, static_cast<TR::SymbolType>(symbolType));358dsfmRecord->setReloFlags(reloTarget, flags);359}360break;361362case TR_HCR:363{364TR_RelocationRecordHCR *hcrRecord = reinterpret_cast<TR_RelocationRecordHCR *>(reloRecord);365366uintptr_t gv = reinterpret_cast<uintptr_t>(relocation->getTargetAddress());367uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));368369TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");370hcrRecord->setReloFlags(reloTarget, flags);371hcrRecord->setOffset(reloTarget, gv);372}373break;374375default:376platformSpecificReloInitialized = false;377}378379return platformSpecificReloInitialized;380}381382383384