Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/z/codegen/J9SystemLinkageLinux.cpp
6004 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* 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-exception
21
*******************************************************************************/
22
23
#include "z/codegen/J9SystemLinkageLinux.hpp"
24
25
#include "codegen/BackingStore.hpp"
26
#include "codegen/CodeGenerator.hpp"
27
#include "codegen/GCStackAtlas.hpp"
28
#include "codegen/GCStackMap.hpp"
29
#include "codegen/Linkage.hpp"
30
#include "codegen/Linkage_inlines.hpp"
31
#include "codegen/S390PrivateLinkage.hpp"
32
#include "compile/Compilation.hpp"
33
#include "env/CHTable.hpp"
34
#include "env/CompilerEnv.hpp"
35
#include "env/VMJ9.h"
36
#include "env/jittypes.h"
37
#include "il/LabelSymbol.hpp"
38
#include "il/MethodSymbol.hpp"
39
#include "il/Node.hpp"
40
#include "il/Node_inlines.hpp"
41
#include "il/RegisterMappedSymbol.hpp"
42
#include "il/ResolvedMethodSymbol.hpp"
43
#include "il/StaticSymbol.hpp"
44
#include "il/Symbol.hpp"
45
#include "runtime/Runtime.hpp"
46
#include "runtime/RuntimeAssumptions.hpp"
47
#include "z/codegen/CallSnippet.hpp"
48
#include "z/codegen/OpMemToMem.hpp"
49
#include "z/codegen/S390Evaluator.hpp"
50
#include "z/codegen/S390GenerateInstructions.hpp"
51
#include "z/codegen/S390HelperCallSnippet.hpp"
52
#include "z/codegen/S390J9CallSnippet.hpp"
53
#include "z/codegen/S390StackCheckFailureSnippet.hpp"
54
55
////////////////////////////////////////////////////////////////////////////////
56
// J9::Z::zLinuxSystemLinkage Implementations
57
////////////////////////////////////////////////////////////////////////////////
58
J9::Z::zLinuxSystemLinkage::zLinuxSystemLinkage(TR::CodeGenerator * codeGen)
59
: TR::S390zLinuxSystemLinkage(codeGen)
60
{
61
}
62
63
/////////////////////////////////////////////////////////////////////////////////
64
// J9::Z::zLinuxSystemLinkage::generateInstructionsForCall - Front-end
65
// customization of callNativeFunction
66
////////////////////////////////////////////////////////////////////////////////
67
void
68
J9::Z::zLinuxSystemLinkage::generateInstructionsForCall(TR::Node * callNode,
69
TR::RegisterDependencyConditions * deps, intptr_t targetAddress,
70
TR::Register * methodAddressReg, TR::Register * javaLitOffsetReg,
71
TR::LabelSymbol * returnFromJNICallLabel,
72
TR::Snippet * callDataSnippet, bool isJNIGCPoint)
73
{
74
TR::S390JNICallDataSnippet * jniCallDataSnippet = static_cast<TR::S390JNICallDataSnippet *>(callDataSnippet);
75
TR::CodeGenerator * codeGen = cg();
76
TR_J9VMBase *fej9 = (TR_J9VMBase *)(codeGen->fe());
77
J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));
78
TR::Register * javaLitPoolRegister = privateLinkage->getLitPoolRealRegister();
79
TR::Register * javaStackRegister = privateLinkage->getStackPointerRealRegister();
80
TR::Register * parm3 = deps->searchPreConditionRegister(getIntegerArgumentRegister(2));
81
TR::Register * parm4 = deps->searchPreConditionRegister(getIntegerArgumentRegister(3));
82
TR::Register * parm5 = deps->searchPreConditionRegister(getIntegerArgumentRegister(4));
83
84
TR::RegisterDependencyConditions * postDeps =
85
new (trHeapMemory()) TR::RegisterDependencyConditions(NULL,
86
deps->getPostConditions(), 0, deps->getAddCursorForPost(), cg());
87
88
TR::Register * systemReturnAddressRegister =
89
deps->searchPostConditionRegister(getReturnAddressRegister());
90
91
bool passLitPoolReg = false;
92
if (codeGen->isLiteralPoolOnDemandOn())
93
{
94
passLitPoolReg = true;
95
}
96
97
if (((TR::RealRegister *) javaLitPoolRegister)->getState() != TR::RealRegister::Locked)
98
{
99
javaLitPoolRegister = deps->searchPostConditionRegister(privateLinkage->getLitPoolRegister());
100
}
101
102
// get the address of the function descriptor
103
/*
104
* for AOT we create a relocation where uint8_t *_targetAddress is set to callNode->getSymbolReference(),
105
* _targetAddress is used in different relocation types, where sometimes it's an actual address and sometimes (eg. TR_HelperAddress) it's a symref
106
* for cases when _targetAddress is actually a symref we cast it back to symref in TR::AheadOfTimeCompile::initializeAOTRelocationHeader
107
*
108
* In this case
109
* generateRegLitRefInstruction creates a ConstantDataSnippet with reloType: TR_HelperAddress, which creates a 32Bit/64Bit ExternalRelocation
110
* of type TR_AbsoluteHelperAddress with _targetAddress set to TR::SymbolReference from the call
111
*
112
*/
113
if (fej9->needRelocationsForHelpers()
114
&& !(callNode->getSymbol()->isResolvedMethod()
115
|| jniCallDataSnippet))
116
{
117
generateRegLitRefInstruction(cg(), TR::InstOpCode::getLoadOpCode(), callNode, systemReturnAddressRegister,
118
(uintptr_t) callNode->getSymbolReference(), TR_HelperAddress, NULL, NULL, NULL);
119
}
120
// get the address of the function descriptor
121
else if (callNode->getSymbol()->isResolvedMethod() && jniCallDataSnippet) // unresolved means a helper being called using system linkage
122
{
123
generateRXInstruction(codeGen, TR::InstOpCode::getLoadOpCode(), callNode,
124
systemReturnAddressRegister, generateS390MemoryReference(jniCallDataSnippet->getBaseRegister(),
125
jniCallDataSnippet->getTargetAddressOffset(), codeGen));
126
}
127
else if (codeGen->needClassAndMethodPointerRelocations()
128
&& callNode->isPreparedForDirectJNI())
129
{
130
TR_ExternalRelocationTargetKind reloType;
131
if (callNode->getSymbol()->castToResolvedMethodSymbol()->isSpecial())
132
reloType = TR_JNISpecialTargetAddress;
133
else if (callNode->getSymbol()->castToResolvedMethodSymbol()->isStatic())
134
reloType = TR_JNIStaticTargetAddress;
135
else if (callNode->getSymbol()->castToResolvedMethodSymbol()->isVirtual())
136
reloType = TR_JNIVirtualTargetAddress;
137
else
138
{
139
reloType = TR_NoRelocation;
140
TR_ASSERT(0,"JNI relocation not supported.");
141
}
142
generateRegLitRefInstruction(cg(), TR::InstOpCode::getLoadOpCode(), callNode,
143
systemReturnAddressRegister, (uintptr_t) targetAddress,
144
reloType, NULL, NULL, NULL);
145
}
146
else
147
{
148
genLoadAddressConstant(codeGen, callNode, targetAddress,
149
systemReturnAddressRegister, NULL, NULL, javaLitPoolRegister);
150
}
151
152
//param 3, 4 and 5 are currently in gpr8, gpr9 and gpr10, move them in correct regs( gpr4, gpr5 and gpr6 )
153
if (parm3)
154
{
155
TR::Register * gpr4Reg = deps->searchPostConditionRegister(TR::RealRegister::GPR4);
156
generateRRInstruction(codeGen, TR::InstOpCode::getLoadRegOpCode(), callNode, gpr4Reg, parm3);
157
}
158
if (parm4)
159
{
160
generateRRInstruction(codeGen, TR::InstOpCode::getLoadRegOpCode(), callNode, javaStackRegister, parm4);
161
}
162
if (parm5)
163
{
164
//save litpool reg GPR6
165
generateRRInstruction(codeGen, TR::InstOpCode::getLoadRegOpCode(), callNode,
166
javaLitOffsetReg, javaLitPoolRegister);
167
generateRRInstruction(codeGen, TR::InstOpCode::getLoadRegOpCode(), callNode,
168
javaLitPoolRegister, parm5);
169
}
170
// call the JNI function
171
TR::Instruction * gcPoint = generateRRInstruction(codeGen, TR::InstOpCode::BASR,
172
callNode, systemReturnAddressRegister,
173
systemReturnAddressRegister, deps);
174
175
if (isJNIGCPoint)
176
{
177
gcPoint->setNeedsGCMap(0x00000000);
178
}
179
generateS390LabelInstruction(codeGen, TR::InstOpCode::label, callNode, returnFromJNICallLabel);
180
181
if (parm5)
182
{
183
//restore litpool reg GPR6
184
generateRRInstruction(codeGen, TR::InstOpCode::getLoadRegOpCode(), callNode,
185
javaLitPoolRegister, javaLitOffsetReg);
186
}
187
188
}
189
190
void
191
J9::Z::zLinuxSystemLinkage::setupRegisterDepForLinkage(TR::Node * callNode, TR_DispatchType dispatchType,
192
TR::RegisterDependencyConditions * &deps, int64_t & killMask, TR::SystemLinkage * systemLinkage,
193
TR::Node * &GlobalRegDeps, bool &hasGlRegDeps, TR::Register ** methodAddressReg, TR::Register * &javaLitOffsetReg)
194
{
195
// call j9 private linkage specialization
196
J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));
197
privateLinkage->setupRegisterDepForLinkage(callNode, dispatchType, deps, killMask, systemLinkage, GlobalRegDeps, hasGlRegDeps, methodAddressReg, javaLitOffsetReg);
198
}
199
200
void
201
J9::Z::zLinuxSystemLinkage::setupBuildArgForLinkage(TR::Node * callNode, TR_DispatchType dispatchType, TR::RegisterDependencyConditions * deps, bool isFastJNI,
202
bool isPassReceiver, int64_t & killMask, TR::Node * GlobalRegDeps, bool hasGlRegDeps, TR::SystemLinkage * systemLinkage)
203
{
204
J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));
205
privateLinkage->setupBuildArgForLinkage(callNode, dispatchType, deps, isFastJNI, isPassReceiver, killMask, GlobalRegDeps, hasGlRegDeps, systemLinkage);
206
}
207
208
void
209
J9::Z::zLinuxSystemLinkage::performCallNativeFunctionForLinkage(TR::Node * callNode, TR_DispatchType dispatchType, TR::Register * &javaReturnRegister, TR::SystemLinkage * systemLinkage,
210
TR::RegisterDependencyConditions * &deps, TR::Register * javaLitOffsetReg, TR::Register * methodAddressReg, bool isJNIGCPoint)
211
{
212
// call base class implementation first
213
OMR::Z::Linkage::performCallNativeFunctionForLinkage(callNode, dispatchType, javaReturnRegister, systemLinkage, deps, javaLitOffsetReg, methodAddressReg, isJNIGCPoint);
214
215
// get javaStack Real Register
216
TR::CodeGenerator * codeGen = cg();
217
TR_J9VMBase *fej9 = (TR_J9VMBase *)(codeGen->fe());
218
J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));
219
TR::RealRegister * javaStackPointerRealRegister = privateLinkage->getStackPointerRealRegister();
220
221
// get methodMetaDataVirtualRegister
222
TR::Register * methodMetaDataVirtualRegister = privateLinkage->getMethodMetaDataRealRegister();
223
224
// restore java stack pointer
225
generateRXInstruction(codeGen, TR::InstOpCode::getLoadOpCode(), callNode, javaStackPointerRealRegister,
226
new (trHeapMemory()) TR::MemoryReference(methodMetaDataVirtualRegister, (int32_t)fej9->thisThreadGetJavaSPOffset(), codeGen));
227
}
228
229
void
230
J9::Z::zLinuxSystemLinkage::doNotKillSpecialRegsForBuildArgs (TR::Linkage *linkage, bool isFastJNI, int64_t &killMask)
231
{
232
J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));
233
privateLinkage->doNotKillSpecialRegsForBuildArgs(linkage, isFastJNI, killMask);
234
}
235
236
void
237
J9::Z::zLinuxSystemLinkage::addSpecialRegDepsForBuildArgs(TR::Node * callNode, TR::RegisterDependencyConditions * dependencies, int32_t& from, int32_t step)
238
{
239
J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));
240
privateLinkage->addSpecialRegDepsForBuildArgs(callNode, dependencies, from, step);
241
}
242
243
int64_t
244
J9::Z::zLinuxSystemLinkage::addFECustomizedReturnRegDependency(int64_t killMask, TR::Linkage* linkage, TR::DataType resType, TR::RegisterDependencyConditions * dependencies)
245
{
246
J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));
247
killMask = privateLinkage->addFECustomizedReturnRegDependency(killMask, linkage, resType, dependencies);
248
return killMask;
249
}
250
251
int32_t
252
J9::Z::zLinuxSystemLinkage::storeExtraEnvRegForBuildArgs(TR::Node * callNode, TR::Linkage* linkage, TR::RegisterDependencyConditions * dependencies,
253
bool isFastJNI, int32_t stackOffset, int8_t gprSize, uint32_t &numIntegerArgs)
254
{
255
J9::Z::PrivateLinkage * privateLinkage = static_cast<J9::Z::PrivateLinkage *>(cg()->getLinkage(TR_Private));
256
stackOffset = privateLinkage->storeExtraEnvRegForBuildArgs(callNode, linkage, dependencies, isFastJNI, stackOffset, gprSize, numIntegerArgs);
257
return stackOffset;
258
}
259
260