Path: blob/master/runtime/compiler/z/codegen/J9SystemLinkageLinux.cpp
6004 views
/*******************************************************************************1* Copyright (c) 2000, 2021 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 "z/codegen/J9SystemLinkageLinux.hpp"2324#include "codegen/BackingStore.hpp"25#include "codegen/CodeGenerator.hpp"26#include "codegen/GCStackAtlas.hpp"27#include "codegen/GCStackMap.hpp"28#include "codegen/Linkage.hpp"29#include "codegen/Linkage_inlines.hpp"30#include "codegen/S390PrivateLinkage.hpp"31#include "compile/Compilation.hpp"32#include "env/CHTable.hpp"33#include "env/CompilerEnv.hpp"34#include "env/VMJ9.h"35#include "env/jittypes.h"36#include "il/LabelSymbol.hpp"37#include "il/MethodSymbol.hpp"38#include "il/Node.hpp"39#include "il/Node_inlines.hpp"40#include "il/RegisterMappedSymbol.hpp"41#include "il/ResolvedMethodSymbol.hpp"42#include "il/StaticSymbol.hpp"43#include "il/Symbol.hpp"44#include "runtime/Runtime.hpp"45#include "runtime/RuntimeAssumptions.hpp"46#include "z/codegen/CallSnippet.hpp"47#include "z/codegen/OpMemToMem.hpp"48#include "z/codegen/S390Evaluator.hpp"49#include "z/codegen/S390GenerateInstructions.hpp"50#include "z/codegen/S390HelperCallSnippet.hpp"51#include "z/codegen/S390J9CallSnippet.hpp"52#include "z/codegen/S390StackCheckFailureSnippet.hpp"5354////////////////////////////////////////////////////////////////////////////////55// J9::Z::zLinuxSystemLinkage Implementations56////////////////////////////////////////////////////////////////////////////////57J9::Z::zLinuxSystemLinkage::zLinuxSystemLinkage(TR::CodeGenerator * codeGen)58: TR::S390zLinuxSystemLinkage(codeGen)59{60}6162/////////////////////////////////////////////////////////////////////////////////63// J9::Z::zLinuxSystemLinkage::generateInstructionsForCall - Front-end64// customization of callNativeFunction65////////////////////////////////////////////////////////////////////////////////66void67J9::Z::zLinuxSystemLinkage::generateInstructionsForCall(TR::Node * callNode,68TR::RegisterDependencyConditions * deps, intptr_t targetAddress,69TR::Register * methodAddressReg, TR::Register * javaLitOffsetReg,70TR::LabelSymbol * returnFromJNICallLabel,71TR::Snippet * callDataSnippet, bool isJNIGCPoint)72{73TR::S390JNICallDataSnippet * jniCallDataSnippet = static_cast<TR::S390JNICallDataSnippet *>(callDataSnippet);74TR::CodeGenerator * codeGen = cg();75TR_J9VMBase *fej9 = (TR_J9VMBase *)(codeGen->fe());76J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));77TR::Register * javaLitPoolRegister = privateLinkage->getLitPoolRealRegister();78TR::Register * javaStackRegister = privateLinkage->getStackPointerRealRegister();79TR::Register * parm3 = deps->searchPreConditionRegister(getIntegerArgumentRegister(2));80TR::Register * parm4 = deps->searchPreConditionRegister(getIntegerArgumentRegister(3));81TR::Register * parm5 = deps->searchPreConditionRegister(getIntegerArgumentRegister(4));8283TR::RegisterDependencyConditions * postDeps =84new (trHeapMemory()) TR::RegisterDependencyConditions(NULL,85deps->getPostConditions(), 0, deps->getAddCursorForPost(), cg());8687TR::Register * systemReturnAddressRegister =88deps->searchPostConditionRegister(getReturnAddressRegister());8990bool passLitPoolReg = false;91if (codeGen->isLiteralPoolOnDemandOn())92{93passLitPoolReg = true;94}9596if (((TR::RealRegister *) javaLitPoolRegister)->getState() != TR::RealRegister::Locked)97{98javaLitPoolRegister = deps->searchPostConditionRegister(privateLinkage->getLitPoolRegister());99}100101// get the address of the function descriptor102/*103* for AOT we create a relocation where uint8_t *_targetAddress is set to callNode->getSymbolReference(),104* _targetAddress is used in different relocation types, where sometimes it's an actual address and sometimes (eg. TR_HelperAddress) it's a symref105* for cases when _targetAddress is actually a symref we cast it back to symref in TR::AheadOfTimeCompile::initializeAOTRelocationHeader106*107* In this case108* generateRegLitRefInstruction creates a ConstantDataSnippet with reloType: TR_HelperAddress, which creates a 32Bit/64Bit ExternalRelocation109* of type TR_AbsoluteHelperAddress with _targetAddress set to TR::SymbolReference from the call110*111*/112if (fej9->needRelocationsForHelpers()113&& !(callNode->getSymbol()->isResolvedMethod()114|| jniCallDataSnippet))115{116generateRegLitRefInstruction(cg(), TR::InstOpCode::getLoadOpCode(), callNode, systemReturnAddressRegister,117(uintptr_t) callNode->getSymbolReference(), TR_HelperAddress, NULL, NULL, NULL);118}119// get the address of the function descriptor120else if (callNode->getSymbol()->isResolvedMethod() && jniCallDataSnippet) // unresolved means a helper being called using system linkage121{122generateRXInstruction(codeGen, TR::InstOpCode::getLoadOpCode(), callNode,123systemReturnAddressRegister, generateS390MemoryReference(jniCallDataSnippet->getBaseRegister(),124jniCallDataSnippet->getTargetAddressOffset(), codeGen));125}126else if (codeGen->needClassAndMethodPointerRelocations()127&& callNode->isPreparedForDirectJNI())128{129TR_ExternalRelocationTargetKind reloType;130if (callNode->getSymbol()->castToResolvedMethodSymbol()->isSpecial())131reloType = TR_JNISpecialTargetAddress;132else if (callNode->getSymbol()->castToResolvedMethodSymbol()->isStatic())133reloType = TR_JNIStaticTargetAddress;134else if (callNode->getSymbol()->castToResolvedMethodSymbol()->isVirtual())135reloType = TR_JNIVirtualTargetAddress;136else137{138reloType = TR_NoRelocation;139TR_ASSERT(0,"JNI relocation not supported.");140}141generateRegLitRefInstruction(cg(), TR::InstOpCode::getLoadOpCode(), callNode,142systemReturnAddressRegister, (uintptr_t) targetAddress,143reloType, NULL, NULL, NULL);144}145else146{147genLoadAddressConstant(codeGen, callNode, targetAddress,148systemReturnAddressRegister, NULL, NULL, javaLitPoolRegister);149}150151//param 3, 4 and 5 are currently in gpr8, gpr9 and gpr10, move them in correct regs( gpr4, gpr5 and gpr6 )152if (parm3)153{154TR::Register * gpr4Reg = deps->searchPostConditionRegister(TR::RealRegister::GPR4);155generateRRInstruction(codeGen, TR::InstOpCode::getLoadRegOpCode(), callNode, gpr4Reg, parm3);156}157if (parm4)158{159generateRRInstruction(codeGen, TR::InstOpCode::getLoadRegOpCode(), callNode, javaStackRegister, parm4);160}161if (parm5)162{163//save litpool reg GPR6164generateRRInstruction(codeGen, TR::InstOpCode::getLoadRegOpCode(), callNode,165javaLitOffsetReg, javaLitPoolRegister);166generateRRInstruction(codeGen, TR::InstOpCode::getLoadRegOpCode(), callNode,167javaLitPoolRegister, parm5);168}169// call the JNI function170TR::Instruction * gcPoint = generateRRInstruction(codeGen, TR::InstOpCode::BASR,171callNode, systemReturnAddressRegister,172systemReturnAddressRegister, deps);173174if (isJNIGCPoint)175{176gcPoint->setNeedsGCMap(0x00000000);177}178generateS390LabelInstruction(codeGen, TR::InstOpCode::label, callNode, returnFromJNICallLabel);179180if (parm5)181{182//restore litpool reg GPR6183generateRRInstruction(codeGen, TR::InstOpCode::getLoadRegOpCode(), callNode,184javaLitPoolRegister, javaLitOffsetReg);185}186187}188189void190J9::Z::zLinuxSystemLinkage::setupRegisterDepForLinkage(TR::Node * callNode, TR_DispatchType dispatchType,191TR::RegisterDependencyConditions * &deps, int64_t & killMask, TR::SystemLinkage * systemLinkage,192TR::Node * &GlobalRegDeps, bool &hasGlRegDeps, TR::Register ** methodAddressReg, TR::Register * &javaLitOffsetReg)193{194// call j9 private linkage specialization195J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));196privateLinkage->setupRegisterDepForLinkage(callNode, dispatchType, deps, killMask, systemLinkage, GlobalRegDeps, hasGlRegDeps, methodAddressReg, javaLitOffsetReg);197}198199void200J9::Z::zLinuxSystemLinkage::setupBuildArgForLinkage(TR::Node * callNode, TR_DispatchType dispatchType, TR::RegisterDependencyConditions * deps, bool isFastJNI,201bool isPassReceiver, int64_t & killMask, TR::Node * GlobalRegDeps, bool hasGlRegDeps, TR::SystemLinkage * systemLinkage)202{203J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));204privateLinkage->setupBuildArgForLinkage(callNode, dispatchType, deps, isFastJNI, isPassReceiver, killMask, GlobalRegDeps, hasGlRegDeps, systemLinkage);205}206207void208J9::Z::zLinuxSystemLinkage::performCallNativeFunctionForLinkage(TR::Node * callNode, TR_DispatchType dispatchType, TR::Register * &javaReturnRegister, TR::SystemLinkage * systemLinkage,209TR::RegisterDependencyConditions * &deps, TR::Register * javaLitOffsetReg, TR::Register * methodAddressReg, bool isJNIGCPoint)210{211// call base class implementation first212OMR::Z::Linkage::performCallNativeFunctionForLinkage(callNode, dispatchType, javaReturnRegister, systemLinkage, deps, javaLitOffsetReg, methodAddressReg, isJNIGCPoint);213214// get javaStack Real Register215TR::CodeGenerator * codeGen = cg();216TR_J9VMBase *fej9 = (TR_J9VMBase *)(codeGen->fe());217J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));218TR::RealRegister * javaStackPointerRealRegister = privateLinkage->getStackPointerRealRegister();219220// get methodMetaDataVirtualRegister221TR::Register * methodMetaDataVirtualRegister = privateLinkage->getMethodMetaDataRealRegister();222223// restore java stack pointer224generateRXInstruction(codeGen, TR::InstOpCode::getLoadOpCode(), callNode, javaStackPointerRealRegister,225new (trHeapMemory()) TR::MemoryReference(methodMetaDataVirtualRegister, (int32_t)fej9->thisThreadGetJavaSPOffset(), codeGen));226}227228void229J9::Z::zLinuxSystemLinkage::doNotKillSpecialRegsForBuildArgs (TR::Linkage *linkage, bool isFastJNI, int64_t &killMask)230{231J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));232privateLinkage->doNotKillSpecialRegsForBuildArgs(linkage, isFastJNI, killMask);233}234235void236J9::Z::zLinuxSystemLinkage::addSpecialRegDepsForBuildArgs(TR::Node * callNode, TR::RegisterDependencyConditions * dependencies, int32_t& from, int32_t step)237{238J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));239privateLinkage->addSpecialRegDepsForBuildArgs(callNode, dependencies, from, step);240}241242int64_t243J9::Z::zLinuxSystemLinkage::addFECustomizedReturnRegDependency(int64_t killMask, TR::Linkage* linkage, TR::DataType resType, TR::RegisterDependencyConditions * dependencies)244{245J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));246killMask = privateLinkage->addFECustomizedReturnRegDependency(killMask, linkage, resType, dependencies);247return killMask;248}249250int32_t251J9::Z::zLinuxSystemLinkage::storeExtraEnvRegForBuildArgs(TR::Node * callNode, TR::Linkage* linkage, TR::RegisterDependencyConditions * dependencies,252bool isFastJNI, int32_t stackOffset, int8_t gprSize, uint32_t &numIntegerArgs)253{254J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));255stackOffset = privateLinkage->storeExtraEnvRegForBuildArgs(callNode, linkage, dependencies, isFastJNI, stackOffset, gprSize, numIntegerArgs);256return stackOffset;257}258259260