Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/p/codegen/StackCheckFailureSnippet.cpp
6004 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 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 "p/codegen/StackCheckFailureSnippet.hpp"
24
25
#include "codegen/CodeGenerator.hpp"
26
#include "codegen/GCStackAtlas.hpp"
27
#include "codegen/Instruction.hpp"
28
#include "codegen/Linkage.hpp"
29
#include "codegen/Linkage_inlines.hpp"
30
#include "codegen/Machine.hpp"
31
#include "codegen/RealRegister.hpp"
32
#include "codegen/Relocation.hpp"
33
#include "codegen/SnippetGCMap.hpp"
34
#include "env/CompilerEnv.hpp"
35
#include "env/IO.hpp"
36
#include "env/jittypes.h"
37
#include "env/VMJ9.h"
38
#include "il/LabelSymbol.hpp"
39
#include "il/MethodSymbol.hpp"
40
#include "il/Node.hpp"
41
#include "il/Node_inlines.hpp"
42
#include "il/ParameterSymbol.hpp"
43
#include "il/RegisterMappedSymbol.hpp"
44
#include "il/ResolvedMethodSymbol.hpp"
45
#include "il/StaticSymbol.hpp"
46
#include "il/Symbol.hpp"
47
#include "runtime/CodeCacheManager.hpp"
48
49
uint8_t *storeArgumentItem(TR::InstOpCode::Mnemonic op, uint8_t *buffer, TR::RealRegister *reg, int32_t offset, TR::CodeGenerator *cg)
50
{
51
TR::RealRegister *stackPtr = cg->getLinkage()->cg()->getStackPointerRegister();
52
TR::InstOpCode opCode(op);
53
opCode.copyBinaryToBuffer(buffer);
54
reg->setRegisterFieldRS(toPPCCursor(buffer));
55
stackPtr->setRegisterFieldRA(toPPCCursor(buffer));
56
*toPPCCursor(buffer) |= offset & 0x0000ffff;
57
return(buffer+4);
58
}
59
60
uint8_t *loadArgumentItem(TR::InstOpCode::Mnemonic op, uint8_t *buffer, TR::RealRegister *reg, int32_t offset, TR::CodeGenerator *cg)
61
{
62
TR::RealRegister *stackPtr = cg->getLinkage()->cg()->getStackPointerRegister();
63
TR::InstOpCode opCode(op);
64
opCode.copyBinaryToBuffer(buffer);
65
reg->setRegisterFieldRT(toPPCCursor(buffer));
66
stackPtr->setRegisterFieldRA(toPPCCursor(buffer));
67
*toPPCCursor(buffer) |= offset & 0x0000ffff;
68
return(buffer+4);
69
}
70
71
uint8_t *TR::PPCStackCheckFailureSnippet::emitSnippetBody()
72
{
73
TR::Compilation * comp = cg()->comp();
74
TR::ResolvedMethodSymbol *bodySymbol=comp->getJittedMethodSymbol();
75
TR::Machine *machine = cg()->machine();
76
TR::SymbolReference *sofRef = comp->getSymRefTab()->findOrCreateStackOverflowSymbolRef(comp->getJittedMethodSymbol());
77
TR::MethodSymbol *sof = sofRef->getSymbol()->castToMethodSymbol();
78
79
int32_t offsetAdjust=cg()->getFrameSizeInBytes();
80
ListIterator<TR::ParameterSymbol> paramIterator(&(bodySymbol->getParameterList()));
81
TR::ParameterSymbol *paramCursor = paramIterator.getFirst();
82
const TR::PPCLinkageProperties &linkage = cg()->getLinkage()->getProperties();
83
84
uint8_t *buffer = cg()->getBinaryBufferCursor();
85
uint8_t *bufferStart = buffer;
86
uint8_t *returnLocation;
87
bool saveLR = (cg()->getSnippetList().size()<=1 &&
88
!bodySymbol->isEHAware() &&
89
!cg()->canExceptByTrap() &&
90
!machine->getLinkRegisterKilled());
91
TR::InstOpCode add_opCode(TR::InstOpCode::add);
92
TR::InstOpCode addi_opCode(TR::InstOpCode::addi);
93
TR::InstOpCode subf_opCode(TR::InstOpCode::subf);
94
TR::RealRegister *stackPtr = cg()->getLinkage()->cg()->getStackPointerRegister();
95
TR::RealRegister *gr12 = machine->getRealRegister(TR::RealRegister::gr12);
96
97
getSnippetLabel()->setCodeLocation(buffer);
98
99
if (offsetAdjust)
100
{
101
if (offsetAdjust > UPPER_IMMED) // addi is not applicable
102
{
103
// prologue arranged for gr12 to contain offsetAdjust
104
// add sp, sp, gr12
105
add_opCode.copyBinaryToBuffer(buffer);
106
stackPtr->setRegisterFieldRT(toPPCCursor(buffer));
107
stackPtr->setRegisterFieldRA(toPPCCursor(buffer));
108
gr12->setRegisterFieldRB(toPPCCursor(buffer));
109
buffer += 4;
110
}
111
else
112
{
113
// addi sp, sp, framesize
114
addi_opCode.copyBinaryToBuffer(buffer);
115
stackPtr->setRegisterFieldRT(toPPCCursor(buffer));
116
stackPtr->setRegisterFieldRA(toPPCCursor(buffer));
117
*toPPCCursor(buffer) |= offsetAdjust & 0x0000ffff;
118
buffer += 4;
119
// pass framesize to jitStackOverflow in gr12
120
// addi gr12, gr0, framesize (ie li gr12, framesize)
121
addi_opCode.copyBinaryToBuffer(buffer);
122
gr12->setRegisterFieldRT(toPPCCursor(buffer));
123
*toPPCCursor(buffer) |= offsetAdjust & 0x0000ffff;
124
buffer += 4;
125
}
126
}
127
else
128
{
129
if (saveLR)
130
{
131
// addi sp, sp, -sizeOfJavaPointer
132
addi_opCode.copyBinaryToBuffer(buffer);
133
stackPtr->setRegisterFieldRT(toPPCCursor(buffer));
134
stackPtr->setRegisterFieldRA(toPPCCursor(buffer));
135
*toPPCCursor(buffer) |= (-TR::Compiler->om.sizeofReferenceAddress()) & 0x0000ffff;
136
buffer += 4;
137
}
138
// pass framesize to jitStackOverflow in gr12
139
// addi gr12, gr0, framesize (ie li gr12, framesize)
140
addi_opCode.copyBinaryToBuffer(buffer);
141
gr12->setRegisterFieldRT(toPPCCursor(buffer));
142
*toPPCCursor(buffer) |= offsetAdjust & 0x0000ffff;
143
buffer += 4;
144
}
145
146
if (saveLR)
147
{
148
// mflr gr0
149
*(int32_t *)buffer = 0x7c0802a6;
150
buffer += 4;
151
}
152
153
if (saveLR)
154
{
155
if (comp->target().is64Bit())
156
// std [gr14, 0], gr0
157
*(int32_t *)buffer = 0xf80e0000;
158
else
159
// stw [gr14, 0], gr0
160
*(int32_t *)buffer = 0x900e0000;
161
buffer += 4;
162
}
163
164
intptr_t helperAddress = (intptr_t)sof->getMethodAddress();
165
if (cg()->directCallRequiresTrampoline(helperAddress, (intptr_t)buffer))
166
{
167
helperAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(sofRef->getReferenceNumber(), (void *)buffer);
168
TR_ASSERT_FATAL(comp->target().cpu.isTargetWithinIFormBranchRange(helperAddress, (intptr_t)buffer), "Helper address is out of range");
169
}
170
171
// bl distance
172
*(int32_t *)buffer = 0x48000001 | ((helperAddress - (intptr_t)buffer) & 0x03ffffff);
173
cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(buffer,
174
(uint8_t *)sofRef,
175
TR_HelperAddress, cg()),
176
__FILE__, __LINE__, getNode());
177
buffer += 4;
178
returnLocation = buffer;
179
180
if (saveLR)
181
{
182
// For FSD, we have to reload the return address
183
if (comp->getOption(TR_FullSpeedDebug))
184
{
185
if (comp->target().is64Bit())
186
// ld gr0, [gr14, 0]
187
*(int32_t *)buffer = 0xe80e0000;
188
else
189
// lwz gr0, [gr14, 0]
190
*(int32_t *)buffer = 0x800e0000;
191
buffer += 4;
192
}
193
194
// mtlr gr0
195
*(int32_t *)buffer = 0x7c0803a6;
196
buffer += 4;
197
}
198
199
if (offsetAdjust)
200
{
201
if (offsetAdjust > (-LOWER_IMMED)) // addi is not applicable
202
{
203
// prologue arranged for gr12 to contain offsetAdjust
204
// and gr12 is preserved across the call to jitStackOverflow
205
// subf sp, gr12, sp
206
subf_opCode.copyBinaryToBuffer(buffer);
207
stackPtr->setRegisterFieldRT(toPPCCursor(buffer));
208
gr12->setRegisterFieldRA(toPPCCursor(buffer));
209
stackPtr->setRegisterFieldRB(toPPCCursor(buffer));
210
}
211
else
212
{
213
// addi sp, sp, -framesize
214
addi_opCode.copyBinaryToBuffer(buffer);
215
stackPtr->setRegisterFieldRT(toPPCCursor(buffer));
216
stackPtr->setRegisterFieldRA(toPPCCursor(buffer));
217
*toPPCCursor(buffer) |= -offsetAdjust & 0x0000ffff;
218
}
219
buffer += 4;
220
}
221
else if (saveLR)
222
{
223
// addi sp, sp, sizeOfJavaPointer
224
addi_opCode.copyBinaryToBuffer(buffer);
225
stackPtr->setRegisterFieldRT(toPPCCursor(buffer));
226
stackPtr->setRegisterFieldRA(toPPCCursor(buffer));
227
*toPPCCursor(buffer) |= TR::Compiler->om.sizeofReferenceAddress() & 0x0000ffff;
228
buffer += 4;
229
}
230
231
// b restartLabel -- assuming it is less than 64MB away.
232
*(int32_t *)buffer = 0x48000000 | (((intptr_t)getReStartLabel()->getCodeLocation() - (intptr_t)buffer) & 0x03fffffc);
233
234
TR::GCStackAtlas *atlas = cg()->getStackAtlas();
235
if (atlas)
236
{
237
// only the arg references are live at this point
238
uint32_t numberOfParmSlots = atlas->getNumberOfParmSlotsMapped();
239
TR_GCStackMap *map = new (cg()->trHeapMemory(), numberOfParmSlots) TR_GCStackMap(numberOfParmSlots);
240
241
map->copy(atlas->getParameterMap());
242
while (paramCursor != NULL)
243
{
244
int32_t intRegArgIndex = paramCursor->getLinkageRegisterIndex();
245
if (intRegArgIndex >= 0 &&
246
paramCursor->isReferencedParameter() &&
247
paramCursor->isCollectedReference())
248
{
249
// In full speed debug all the parameters are passed in the stack for this case
250
// but will also reside in the registers
251
if (!comp->getOption(TR_FullSpeedDebug))
252
{
253
map->resetBit(paramCursor->getGCMapIndex());
254
}
255
map->setRegisterBits(cg()->registerBitMask(linkage.getIntegerArgumentRegister(intRegArgIndex)));
256
}
257
paramCursor = paramIterator.getNext();
258
}
259
260
// set the GC map
261
gcMap().setStackMap(map);
262
atlas->setParameterMap(map);
263
}
264
gcMap().registerStackMap(returnLocation, cg());
265
return buffer + 4;
266
}
267
268
269
void
270
TR_Debug::print(TR::FILE *pOutFile, TR::PPCStackCheckFailureSnippet * snippet)
271
{
272
uint8_t *cursor = snippet->getSnippetLabel()->getCodeLocation();
273
274
printSnippetLabel(pOutFile, snippet->getSnippetLabel(), cursor, "Stack Check Failure Snippet");
275
276
TR::ResolvedMethodSymbol *bodySymbol=_comp->getJittedMethodSymbol();
277
const TR::PPCLinkageProperties &linkage = _cg->getLinkage()->getProperties();
278
TR::Machine *machine = _cg->machine();
279
TR::RealRegister *stackPtr = _cg->getStackPointerRegister();
280
281
bool saveLR = (_cg->getSnippetList().size() <= 1 &&
282
!bodySymbol->isEHAware() &&
283
!_cg->canExceptByTrap() &&
284
!machine->getLinkRegisterKilled());
285
286
int32_t offsetAdjust = _cg->getFrameSizeInBytes();
287
288
if (offsetAdjust)
289
{
290
if (offsetAdjust > UPPER_IMMED) // addi is not applicable
291
{
292
// prologue arranged for gr12 to contain offsetAdjust
293
printPrefix(pOutFile, NULL, cursor, 4);
294
trfprintf(pOutFile, "add \t");
295
print(pOutFile, stackPtr, TR_WordReg);
296
trfprintf(pOutFile, ", ");
297
print(pOutFile, stackPtr, TR_WordReg);
298
trfprintf(pOutFile, ", gr12");
299
cursor += 4;
300
}
301
else
302
{
303
printPrefix(pOutFile, NULL, cursor, 4);
304
trfprintf(pOutFile, "addi2 \t");
305
print(pOutFile, stackPtr, TR_WordReg);
306
trfprintf(pOutFile, ", ");
307
print(pOutFile, stackPtr, TR_WordReg);
308
trfprintf(pOutFile, ", 0x%x", offsetAdjust);
309
cursor += 4;
310
printPrefix(pOutFile, NULL, cursor, 4);
311
trfprintf(pOutFile, "li \tgr12");
312
trfprintf(pOutFile, ", 0x%x", offsetAdjust);
313
cursor += 4;
314
}
315
}
316
else
317
{
318
if (saveLR)
319
{
320
printPrefix(pOutFile, NULL, cursor, 4);
321
trfprintf(pOutFile, "addi2 \t");
322
print(pOutFile, stackPtr, TR_WordReg);
323
trfprintf(pOutFile, ", ");
324
print(pOutFile, stackPtr, TR_WordReg);
325
trfprintf(pOutFile, ", 0x%x", -TR::Compiler->om.sizeofReferenceAddress());
326
cursor += 4;
327
}
328
printPrefix(pOutFile, NULL, cursor, 4);
329
trfprintf(pOutFile, "li \tgr12");
330
trfprintf(pOutFile, ", 0x%x", offsetAdjust);
331
cursor += 4;
332
}
333
334
if (saveLR)
335
{
336
printPrefix(pOutFile, NULL, cursor, 4);
337
trfprintf(pOutFile, "mflr \tgr0");
338
cursor += 4;
339
}
340
341
if (saveLR)
342
{
343
printPrefix(pOutFile, NULL, cursor, 4);
344
if (_comp->target().is64Bit())
345
trfprintf(pOutFile, "std \t[gr14, 0], gr0");
346
else
347
trfprintf(pOutFile, "stw \t[gr14, 0], gr0");
348
cursor += 4;
349
}
350
351
char *info = "";
352
int32_t distance;
353
if (isBranchToTrampoline(_comp->getSymRefTab()->element(TR_stackOverflow), cursor, distance))
354
info = " Through trampoline";
355
356
printPrefix(pOutFile, NULL, cursor, 4);
357
distance = *((int32_t *) cursor) & 0x03fffffc;
358
distance = (distance << 6) >> 6; // sign extend
359
trfprintf(pOutFile, "bl \t" POINTER_PRINTF_FORMAT "\t\t;%s", (intptr_t)cursor + distance, info);
360
cursor += 4;
361
362
if (saveLR)
363
{
364
printPrefix(pOutFile, NULL, cursor, 4);
365
trfprintf(pOutFile, "mtlr \tgr0");
366
cursor += 4;
367
}
368
369
if (offsetAdjust)
370
{
371
if (offsetAdjust > (-LOWER_IMMED)) // addi is not applicable
372
{
373
// prologue arranged for gr12 to contain offsetAdjust
374
printPrefix(pOutFile, NULL, cursor, 4);
375
trfprintf(pOutFile, "subf \t");
376
print(pOutFile, stackPtr, TR_WordReg);
377
trfprintf(pOutFile, ", gr12, ");
378
print(pOutFile, stackPtr, TR_WordReg);
379
}
380
else
381
{
382
printPrefix(pOutFile, NULL, cursor, 4);
383
trfprintf(pOutFile, "addi2 \t");
384
print(pOutFile, stackPtr, TR_WordReg);
385
trfprintf(pOutFile, ", ");
386
print(pOutFile, stackPtr, TR_WordReg);
387
trfprintf(pOutFile, ", 0x%x", -offsetAdjust);
388
}
389
cursor += 4;
390
}
391
else if (saveLR)
392
{
393
printPrefix(pOutFile, NULL, cursor, 4);
394
trfprintf(pOutFile, "addi2 \t");
395
print(pOutFile, stackPtr, TR_WordReg);
396
trfprintf(pOutFile, ", ");
397
print(pOutFile, stackPtr, TR_WordReg);
398
trfprintf(pOutFile, ", 0x%x", TR::Compiler->om.sizeofReferenceAddress());
399
cursor += 4;
400
}
401
402
// b restartLabel -- assuming it is less than 64MB away.
403
printPrefix(pOutFile, NULL, cursor, 4);
404
distance = *((int32_t *) cursor) & 0x03fffffc;
405
distance = (distance << 6) >> 6; // sign extend
406
trfprintf(pOutFile, "b \t" POINTER_PRINTF_FORMAT "\t\t; Back to ", (intptr_t)cursor + distance);
407
print(pOutFile, snippet->getReStartLabel());
408
}
409
410
uint32_t TR::PPCStackCheckFailureSnippet::getLength(int32_t estimatedSnippetStart)
411
{
412
int32_t length = 0;
413
TR::ResolvedMethodSymbol *bodySymbol=cg()->comp()->getJittedMethodSymbol();
414
415
if (cg()->getSnippetList().size()<=1 &&
416
!bodySymbol->isEHAware() &&
417
!cg()->canExceptByTrap() &&
418
!cg()->machine()->getLinkRegisterKilled())
419
{
420
length += 12;
421
if (cg()->getFrameSizeInBytes() == 0)
422
length += 8;
423
if (cg()->comp()->getOption(TR_FullSpeedDebug))
424
length += 4;
425
}
426
427
if (cg()->getFrameSizeInBytes())
428
length += 8;
429
if (cg()->getFrameSizeInBytes() <= UPPER_IMMED)
430
length += 4; // to load r12 with framesize
431
432
return(length+8);
433
}
434
435