Path: blob/master/runtime/compiler/aarch64/codegen/J9UnresolvedDataSnippet.cpp
6004 views
/*******************************************************************************1* Copyright (c) 2019, 2020 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/ARM64Instruction.hpp"23#include "codegen/CodeGenerator.hpp"24#include "codegen/MemoryReference.hpp"25#include "codegen/Relocation.hpp"26#include "codegen/UnresolvedDataSnippet.hpp"27#include "compile/Compilation.hpp"28#include "il/StaticSymbol.hpp"29#include "il/Symbol.hpp"3031J9::ARM64::UnresolvedDataSnippet::UnresolvedDataSnippet(TR::CodeGenerator *cg, TR::Node *node, TR::SymbolReference *symRef, bool isStore, bool isGCSafePoint)32: J9::UnresolvedDataSnippet(cg, node, symRef, isStore, isGCSafePoint),33_memoryReference(NULL)34{35cg->machine()->setLinkRegisterKilled(true);36}3738TR_RuntimeHelper39J9::ARM64::UnresolvedDataSnippet::getHelper()40{41if (getDataSymbol()->getShadowSymbol() != NULL) // instance data42{43if (isUnresolvedStore())44return TR_ARM64interpreterUnresolvedInstanceDataStoreGlue;45else46return TR_ARM64interpreterUnresolvedInstanceDataGlue;47}48else if (getDataSymbol()->isClassObject()) // class object49{50if (getDataSymbol()->addressIsCPIndexOfStatic())51return TR_ARM64interpreterUnresolvedClassGlue2;52else53return TR_ARM64interpreterUnresolvedClassGlue;54}55else if (getDataSymbol()->isConstString()) // const string56{57return TR_ARM64interpreterUnresolvedStringGlue;58}59else if (getDataSymbol()->isConstMethodType())60{61return TR_interpreterUnresolvedMethodTypeGlue;62}63else if (getDataSymbol()->isConstMethodHandle())64{65return TR_interpreterUnresolvedMethodHandleGlue;66}67else if (getDataSymbol()->isCallSiteTableEntry())68{69return TR_interpreterUnresolvedCallSiteTableEntryGlue;70}71else if (getDataSymbol()->isMethodTypeTableEntry())72{73return TR_interpreterUnresolvedMethodTypeTableEntryGlue;74}75else if (getDataSymbol()->isConstantDynamic())76{77return TR_ARM64interpreterUnresolvedConstantDynamicGlue;78}79else // must be static data80{81if (isUnresolvedStore())82return TR_ARM64interpreterUnresolvedStaticDataStoreGlue;83else84return TR_ARM64interpreterUnresolvedStaticDataGlue;85}86}8788uint8_t *89J9::ARM64::UnresolvedDataSnippet::emitSnippetBody()90{91uint8_t *cursor = cg()->getBinaryBufferCursor();92TR_RuntimeHelper helper = getHelper();93TR::SymbolReference *glueRef = cg()->symRefTab()->findOrCreateRuntimeHelper(helper);9495getSnippetLabel()->setCodeLocation(cursor);9697*(int32_t *)cursor = cg()->encodeHelperBranchAndLink(glueRef, cursor, getNode()); // BL resolve98cursor += 4;99100*(intptr_t *)cursor = (intptr_t)getAddressOfDataReference(); // Code Cache RA101cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(102cursor,103NULL,104TR_AbsoluteMethodAddress, cg()), __FILE__, __LINE__, getNode());105cursor += 8;106107if (getDataSymbol()->isCallSiteTableEntry())108{109*(intptr_t *)cursor = getDataSymbol()->castToCallSiteTableEntrySymbol()->getCallSiteIndex();110}111else if (getDataSymbol()->isMethodTypeTableEntry())112{113*(intptr_t *)cursor = getDataSymbol()->castToMethodTypeTableEntrySymbol()->getMethodTypeIndex();114}115else116{117*(intptr_t *)cursor = getDataSymbolReference()->getCPIndex(); // CP index118}119cursor += 8;120121*(intptr_t *)cursor = (intptr_t)getDataSymbolReference()->getOwningMethod(cg()->comp())->constantPool(); // CP122cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(123cursor,124*(uint8_t **)cursor,125getNode() ? (uint8_t *)getNode()->getInlinedSiteIndex() : (uint8_t *)-1,126TR_ConstantPool, cg()), __FILE__, __LINE__, getNode());127cursor += 8;128129*(int32_t *)cursor = getMemoryReference()->getOffset(); // offset130if (getDataSymbol()->isConstObjectRef())131{132// reset the offset to zero133// the resolve + picbuilder will fully provide the addr to use134*(int32_t *)cursor = 0;135}136cursor += 4;137138*(int32_t *)cursor = TR::InstOpCode::getOpCodeBinaryEncoding(TR::InstOpCode::movzx); // instruction template -- "movz extraReg, #0"139TR_ASSERT(getMemoryReference()->getExtraRegister(), "_extraReg must have been allocated");140toRealRegister(getMemoryReference()->getExtraRegister())->setRegisterFieldRD((uint32_t *)cursor);141142return cursor+4;143}144145void146TR_Debug::print(TR::FILE *pOutFile, TR::UnresolvedDataSnippet * snippet)147{148uint8_t *cursor = snippet->getSnippetLabel()->getCodeLocation();149TR_RuntimeHelper helper = snippet->getHelper();150TR::SymbolReference *glueRef = _cg->getSymRef(helper);151152printSnippetLabel(pOutFile, snippet->getSnippetLabel(), cursor, "Unresolved Data Snippet");153154char *info = "";155int32_t distance;156if (isBranchToTrampoline(glueRef, cursor, distance))157{158info = " Through Trampoline";159}160161printPrefix(pOutFile, NULL, cursor, 4);162distance = *((int32_t *) cursor) & 0x03ffffff; // imm26163distance = (distance << 6) >> 4; // sign extend and add two 0 bits164trfprintf(pOutFile, "bl \t" POINTER_PRINTF_FORMAT "\t\t;%s%s",165(intptr_t)cursor + distance, getRuntimeHelperName(helper), info);166cursor += 4;167168printPrefix(pOutFile, NULL, cursor, sizeof(intptr_t));169trfprintf(pOutFile, ".dword \t" POINTER_PRINTF_FORMAT "\t\t; Code cache return address", *(intptr_t *)cursor);170cursor += sizeof(intptr_t);171172printPrefix(pOutFile, NULL, cursor, sizeof(intptr_t));173trfprintf(pOutFile, ".dword \t0x%08x\t\t; cpIndex of the data reference", *(intptr_t *)cursor);174cursor += sizeof(intptr_t);175176printPrefix(pOutFile, NULL, cursor, sizeof(intptr_t));177trfprintf(pOutFile, ".dword \t" POINTER_PRINTF_FORMAT "\t\t; Constant pool address", *(intptr_t *)cursor);178cursor += sizeof(intptr_t);179180printPrefix(pOutFile, NULL, cursor, 4);181trfprintf(pOutFile, ".word \t0x%08x\t\t; Offset to be merged", *(int32_t *)cursor);182cursor += 4;183184printPrefix(pOutFile, NULL, cursor, 4);185int32_t instr = *(int32_t *)cursor;186trfprintf(pOutFile, ".word \t0x%08x\t\t; Instruction template (extraReg=x%d)", instr, (instr & 0x1F));187}188189uint32_t190J9::ARM64::UnresolvedDataSnippet::getLength(int32_t estimatedSnippetStart)191{192return 9 * 4;193}194195196