Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/aarch64/codegen/StackCheckFailureSnippet.cpp
6004 views
1
/*******************************************************************************
2
* Copyright (c) 2019, 2020 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 "codegen/StackCheckFailureSnippet.hpp"
24
25
#include "codegen/ARM64Instruction.hpp"
26
#include "codegen/CodeGenerator.hpp"
27
#include "codegen/GCStackAtlas.hpp"
28
#include "codegen/Linkage.hpp"
29
#include "codegen/Machine.hpp"
30
#include "il/ParameterSymbol.hpp"
31
#include "il/ResolvedMethodSymbol.hpp"
32
33
uint8_t *
34
TR::ARM64StackCheckFailureSnippet::emitSnippetBody()
35
{
36
TR::ResolvedMethodSymbol *bodySymbol = cg()->comp()->getJittedMethodSymbol();
37
TR::Machine *machine = cg()->machine();
38
TR::SymbolReference *sofRef = cg()->comp()->getSymRefTab()->findOrCreateStackOverflowSymbolRef(bodySymbol);
39
ListIterator<TR::ParameterSymbol> paramIterator(&(bodySymbol->getParameterList()));
40
TR::ParameterSymbol *paramCursor = paramIterator.getFirst();
41
42
uint8_t *cursor = cg()->getBinaryBufferCursor();
43
uint8_t *returnLocation;
44
45
getSnippetLabel()->setCodeLocation(cursor);
46
47
// Pass cg()->getFrameSizeInBytes() to jitStackOverflow in register x9.
48
//
49
const TR::ARM64LinkageProperties &linkage = cg()->getLinkage()->getProperties();
50
uint32_t frameSize = cg()->getFrameSizeInBytes();
51
52
if (frameSize <= 0xffff)
53
{
54
// mov x9, #frameSize
55
*(int32_t *)cursor = 0xd2800009 | (frameSize << 5);
56
cursor += ARM64_INSTRUCTION_LENGTH;
57
}
58
else
59
{
60
TR_ASSERT(false, "Frame size too big. Not supported yet");
61
}
62
63
// add J9SP, J9SP, x9
64
*(int32_t *)cursor = 0x8b090294;
65
cursor += ARM64_INSTRUCTION_LENGTH;
66
67
// str LR, [J9SP]
68
// ToDo: Skip saving/restoring LR when not required
69
*(int32_t *)cursor = 0xf900029e;
70
cursor += ARM64_INSTRUCTION_LENGTH;
71
72
// bl helper
73
*(int32_t *)cursor = cg()->encodeHelperBranchAndLink(sofRef, cursor, getNode());
74
cursor += ARM64_INSTRUCTION_LENGTH;
75
returnLocation = cursor;
76
77
// ldr LR, [J9SP]
78
*(int32_t *)cursor = 0xf940029e;
79
cursor += ARM64_INSTRUCTION_LENGTH;
80
81
// sub J9SP, J9SP, x9 ; assume that jitStackOverflow does not clobber x9
82
*(int32_t *)cursor = 0xcb090294;
83
cursor += ARM64_INSTRUCTION_LENGTH;
84
85
// b restartLabel
86
intptr_t destination = (intptr_t)getReStartLabel()->getCodeLocation();
87
if (!cg()->directCallRequiresTrampoline(destination, (intptr_t)cursor))
88
{
89
intptr_t distance = destination - (intptr_t)cursor;
90
*(int32_t *)cursor = TR::InstOpCode::getOpCodeBinaryEncoding(TR::InstOpCode::b) | ((distance >> 2) & 0x3ffffff); // imm26
91
}
92
else
93
{
94
TR_ASSERT(false, "Target too far away. Not supported yet");
95
}
96
97
TR::GCStackAtlas *atlas = cg()->getStackAtlas();
98
if (atlas)
99
{
100
// only the arg references are live at this point
101
uint32_t numberOfParmSlots = atlas->getNumberOfParmSlotsMapped();
102
TR_GCStackMap *map = new (cg()->trHeapMemory(), numberOfParmSlots) TR_GCStackMap(numberOfParmSlots);
103
104
map->copy(atlas->getParameterMap());
105
while (paramCursor != NULL)
106
{
107
int32_t intRegArgIndex = paramCursor->getLinkageRegisterIndex();
108
if (intRegArgIndex >= 0 &&
109
paramCursor->isReferencedParameter() &&
110
paramCursor->isCollectedReference())
111
{
112
// In full speed debug all the parameters are passed in the stack for this case
113
// but will also reside in the registers
114
if (!cg()->comp()->getOption(TR_FullSpeedDebug))
115
{
116
map->resetBit(paramCursor->getGCMapIndex());
117
}
118
map->setRegisterBits(1 << (linkage.getIntegerArgumentRegister(intRegArgIndex) - 1));
119
}
120
paramCursor = paramIterator.getNext();
121
}
122
123
// set the GC map
124
gcMap().setStackMap(map);
125
atlas->setParameterMap(map);
126
}
127
gcMap().registerStackMap(returnLocation, cg());
128
129
return cursor+ARM64_INSTRUCTION_LENGTH;
130
}
131
132
void
133
TR_Debug::print(TR::FILE *pOutFile, TR::ARM64StackCheckFailureSnippet * snippet)
134
{
135
TR::ResolvedMethodSymbol *bodySymbol = _comp->getJittedMethodSymbol();
136
TR::SymbolReference *sofRef = _comp->getSymRefTab()->findOrCreateStackOverflowSymbolRef(bodySymbol);
137
uint8_t *bufferPos = snippet->getSnippetLabel()->getCodeLocation();
138
139
printSnippetLabel(pOutFile, snippet->getSnippetLabel(), bufferPos, getName(snippet));
140
141
TR::Machine *machine = _cg->machine();
142
TR::RealRegister *x9 = machine->getRealRegister(TR::RealRegister::x9);
143
TR::RealRegister *stackPtr = _cg->getStackPointerRegister();
144
TR::RealRegister *lr = machine->getRealRegister(TR::RealRegister::x30);
145
uint32_t frameSize = _cg->getFrameSizeInBytes();
146
147
if (frameSize <= 0xffff)
148
{
149
// mov x9, #frameSize
150
printPrefix(pOutFile, NULL, bufferPos, 4);
151
trfprintf(pOutFile, "movzx \t");
152
print(pOutFile, x9, TR_WordReg);
153
trfprintf(pOutFile, ", 0x%04x", frameSize);
154
bufferPos += ARM64_INSTRUCTION_LENGTH;
155
}
156
else
157
{
158
TR_ASSERT(false, "Frame size too big. Not supported yet");
159
}
160
161
printPrefix(pOutFile, NULL, bufferPos, 4);
162
trfprintf(pOutFile, "addx \t");
163
print(pOutFile, stackPtr, TR_WordReg); trfprintf(pOutFile, ", ");
164
print(pOutFile, stackPtr, TR_WordReg); trfprintf(pOutFile, ", ");
165
print(pOutFile, x9, TR_WordReg);
166
bufferPos += ARM64_INSTRUCTION_LENGTH;
167
168
printPrefix(pOutFile, NULL, bufferPos, 4);
169
trfprintf(pOutFile, "strimmx \t");
170
print(pOutFile, lr, TR_WordReg);
171
trfprintf(pOutFile, ", [");
172
print(pOutFile, stackPtr, TR_WordReg);
173
trfprintf(pOutFile, "]");
174
bufferPos += ARM64_INSTRUCTION_LENGTH;
175
176
char *info = "";
177
intptr_t target = (intptr_t)(sofRef->getMethodAddress());
178
int32_t distance;
179
if (isBranchToTrampoline(sofRef, bufferPos, distance))
180
{
181
target = (intptr_t)distance + (intptr_t)bufferPos;
182
info = " Through trampoline";
183
}
184
printPrefix(pOutFile, NULL, bufferPos, 4);
185
trfprintf(pOutFile, "bl \t" POINTER_PRINTF_FORMAT "\t\t;%s", target, info);
186
bufferPos += ARM64_INSTRUCTION_LENGTH;
187
188
printPrefix(pOutFile, NULL, bufferPos, 4);
189
trfprintf(pOutFile, "ldrimmx \t");
190
print(pOutFile, lr, TR_WordReg);
191
trfprintf(pOutFile, ", [");
192
print(pOutFile, stackPtr, TR_WordReg);
193
trfprintf(pOutFile, "]");
194
bufferPos += ARM64_INSTRUCTION_LENGTH;
195
196
printPrefix(pOutFile, NULL, bufferPos, 4);
197
trfprintf(pOutFile, "subx \t");
198
print(pOutFile, stackPtr, TR_WordReg); trfprintf(pOutFile, ", ");
199
print(pOutFile, stackPtr, TR_WordReg); trfprintf(pOutFile, ", ");
200
print(pOutFile, x9, TR_WordReg);
201
bufferPos += ARM64_INSTRUCTION_LENGTH;
202
203
intptr_t destination = (intptr_t)snippet->getReStartLabel()->getCodeLocation();
204
// assuming that the distance to the destination is in the range +/- 128MB
205
printPrefix(pOutFile, NULL, bufferPos, 4);
206
trfprintf(pOutFile, "b \t" POINTER_PRINTF_FORMAT "\t\t; Back to ", destination);
207
print(pOutFile, snippet->getReStartLabel());
208
}
209
210
uint32_t
211
TR::ARM64StackCheckFailureSnippet::getLength(int32_t estimatedSnippetStart)
212
{
213
uint32_t frameSize = cg()->getFrameSizeInBytes();
214
215
if (frameSize <= 0xffff)
216
{
217
return 7*ARM64_INSTRUCTION_LENGTH;
218
}
219
else
220
{
221
TR_ASSERT(false, "Frame size too big. Not supported yet");
222
return 0;
223
}
224
}
225
226