Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/p/codegen/J9UnresolvedDataSnippet.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 "codegen/UnresolvedDataSnippet.hpp"
24
#include "codegen/UnresolvedDataSnippet_inlines.hpp"
25
26
#include <stddef.h>
27
#include <stdint.h>
28
#include "codegen/CodeGenerator.hpp"
29
#include "env/FrontEnd.hpp"
30
#include "codegen/Instruction.hpp"
31
#include "codegen/Machine.hpp"
32
#include "codegen/MemoryReference.hpp"
33
#include "codegen/RealRegister.hpp"
34
#include "codegen/Relocation.hpp"
35
#include "compile/Compilation.hpp"
36
#include "compile/ResolvedMethod.hpp"
37
#include "compile/SymbolReferenceTable.hpp"
38
#include "control/Options.hpp"
39
#include "control/Options_inlines.hpp"
40
#include "env/IO.hpp"
41
#include "env/ObjectModel.hpp"
42
#include "env/TRMemory.hpp"
43
#include "env/jittypes.h"
44
#include "env/VMJ9.h"
45
#include "il/DataTypes.hpp"
46
#include "il/LabelSymbol.hpp"
47
#include "il/Node.hpp"
48
#include "il/StaticSymbol.hpp"
49
#include "il/StaticSymbol_inlines.hpp"
50
#include "il/Symbol.hpp"
51
#include "il/SymbolReference.hpp"
52
#include "infra/Assert.hpp"
53
#include "p/codegen/PPCTableOfConstants.hpp"
54
#include "ras/Debug.hpp"
55
#include "runtime/CodeCacheManager.hpp"
56
#include "runtime/J9Runtime.hpp"
57
#include "env/CompilerEnv.hpp"
58
59
J9::Power::UnresolvedDataSnippet::UnresolvedDataSnippet(
60
TR::CodeGenerator *cg,
61
TR::Node *node,
62
TR::SymbolReference *symRef,
63
bool isStore,
64
bool canCauseGC) :
65
J9::UnresolvedDataSnippet(cg, node, symRef, isStore, canCauseGC),
66
_memoryReference(NULL), _dataRegister(NULL)
67
{
68
}
69
70
uint8_t *J9::Power::UnresolvedDataSnippet::getAddressOfDataReference()
71
{
72
if (self()->getDataReferenceInstruction())
73
return self()->getDataReferenceInstruction()->getBinaryEncoding();
74
else
75
return self()->OMR::UnresolvedDataSnippet::getAddressOfDataReference();
76
}
77
78
uint8_t *J9::Power::UnresolvedDataSnippet::emitSnippetBody()
79
{
80
uint8_t *cursor = cg()->getBinaryBufferCursor();
81
TR::Compilation *comp = cg()->comp();
82
TR_J9VMBase *fej9 = (TR_J9VMBase *)(comp->fe());
83
TR::SymbolReference *glueRef;
84
TR_RuntimeHelper refNum;
85
86
if (getDataSymbol()->getShadowSymbol() != NULL) // instance data
87
{
88
if (isUnresolvedStore())
89
refNum = TR_PPCinterpreterUnresolvedInstanceDataStoreGlue;
90
else
91
refNum = TR_PPCinterpreterUnresolvedInstanceDataGlue;
92
}
93
else if (getDataSymbol()->isClassObject())
94
{
95
if (getDataSymbol()->addressIsCPIndexOfStatic())
96
refNum = TR_PPCinterpreterUnresolvedClassGlue2;
97
else
98
refNum = TR_PPCinterpreterUnresolvedClassGlue;
99
}
100
else if (getDataSymbol()->isConstString())
101
{
102
refNum = TR_PPCinterpreterUnresolvedStringGlue;
103
}
104
else if (getDataSymbol()->isConstMethodType())
105
{
106
refNum = TR_interpreterUnresolvedMethodTypeGlue;
107
}
108
else if (getDataSymbol()->isConstMethodHandle())
109
{
110
refNum = TR_interpreterUnresolvedMethodHandleGlue;
111
}
112
else if (getDataSymbol()->isCallSiteTableEntry())
113
{
114
refNum = TR_interpreterUnresolvedCallSiteTableEntryGlue;
115
}
116
else if (getDataSymbol()->isMethodTypeTableEntry())
117
{
118
refNum = TR_interpreterUnresolvedMethodTypeTableEntryGlue;
119
}
120
else if (getDataSymbol()->isConstantDynamic())
121
{
122
refNum = TR_PPCinterpreterUnresolvedConstantDynamicGlue;
123
}
124
else // must be static data
125
{
126
if (isUnresolvedStore())
127
refNum = TR_PPCinterpreterUnresolvedStaticDataStoreGlue;
128
else
129
refNum = TR_PPCinterpreterUnresolvedStaticDataGlue;
130
}
131
132
glueRef = cg()->symRefTab()->findOrCreateRuntimeHelper(refNum);
133
getSnippetLabel()->setCodeLocation(cursor);
134
135
intptr_t helperAddress = (intptr_t)glueRef->getMethodAddress();
136
if (cg()->directCallRequiresTrampoline(helperAddress, (intptr_t)cursor))
137
{
138
helperAddress = TR::CodeCacheManager::instance()->findHelperTrampoline(glueRef->getReferenceNumber(), (void *)cursor);
139
TR_ASSERT_FATAL(comp->target().cpu.isTargetWithinIFormBranchRange(helperAddress, (intptr_t)cursor), "Helper address is out of range");
140
}
141
142
// bl distance
143
*(int32_t *)cursor = 0x48000001 | ((helperAddress - (intptr_t)cursor) & 0x03fffffc);
144
cg()->addProjectSpecializedRelocation(cursor,(uint8_t *)glueRef, NULL, TR_HelperAddress,
145
__FILE__,
146
__LINE__,
147
getNode());
148
if (getDataSymbol()->isClassObject() && cg()->wantToPatchClassPointer(NULL, getAddressOfDataReference()))
149
{
150
uintptr_t dis = cursor - getAddressOfDataReference();
151
cg()->jitAddUnresolvedAddressMaterializationToPatchOnClassRedefinition((void *) getAddressOfDataReference());
152
}
153
cursor += 4;
154
155
*(intptr_t *)cursor = (intptr_t)getAddressOfDataReference(); // Code Cache RA
156
cg()->addProjectSpecializedRelocation(cursor, NULL, NULL, TR_AbsoluteMethodAddress,
157
__FILE__, __LINE__, getNode());
158
cursor += TR::Compiler->om.sizeofReferenceAddress();
159
160
if (getDataSymbolReference()->getSymbol()->isCallSiteTableEntry())
161
{
162
*(int32_t *)cursor = getDataSymbolReference()->getSymbol()->castToCallSiteTableEntrySymbol()->getCallSiteIndex();
163
}
164
else if (getDataSymbol()->isMethodTypeTableEntry())
165
{
166
*(int32_t *)cursor = getDataSymbolReference()->getSymbol()->castToMethodTypeTableEntrySymbol()->getMethodTypeIndex();
167
}
168
else // constant pool index
169
{
170
*(int32_t *)cursor = getDataSymbolReference()->getCPIndex();
171
}
172
173
if (getMemoryReference()->isTOCAccess())
174
*(int32_t *)cursor |= 1<<31; // Set Pseudo TOC bit
175
if (isSpecialDouble())
176
*(int32_t *)cursor |= 1<<30; // Set Special Double bit
177
if (inSyncSequence())
178
*(int32_t *)cursor |= 1<<29; // Set Sync Pattern bit
179
if (getMemoryReference()->useIndexedForm())
180
*(int32_t *)cursor |= 1<<28; // Set the index bit
181
if (is32BitLong())
182
*(int32_t *)cursor |= 1<<27; // Set the double word load/store bit
183
cursor += 4;
184
185
*(intptr_t *)cursor = (intptr_t)getDataSymbolReference()->getOwningMethod(comp)->constantPool();
186
cg()->addExternalRelocation(new (cg()->trHeapMemory()) TR::ExternalRelocation(cursor,*(uint8_t **)cursor,
187
getNode() ? (uint8_t *)getNode()->getInlinedSiteIndex() : (uint8_t *)-1,
188
TR_ConstantPool,
189
cg()),
190
__FILE__,
191
__LINE__,
192
getNode());
193
cursor += TR::Compiler->om.sizeofReferenceAddress();
194
195
if (getMemoryReference()->isTOCAccess())
196
{
197
*(int32_t *)cursor = getMemoryReference()->getTOCOffset();
198
}
199
else
200
{
201
*(int32_t *)cursor = getMemoryReference()->getOffset(*(comp)); // offset
202
if (getDataSymbol()->isConstObjectRef() || getDataSymbol()->isConstantDynamic())
203
{
204
cg()->addProjectSpecializedRelocation(cursor, *(uint8_t **)(cursor-4),
205
getNode() ? (uint8_t *)getNode()->getInlinedSiteIndex() : (uint8_t *)-1, TR_ConstantPool,
206
__FILE__,
207
__LINE__,
208
getNode());
209
}
210
}
211
cursor += 4;
212
213
if (getMemoryReference()->isTOCAccess())
214
{
215
if (getMemoryReference()->getTOCOffset() != PTOC_FULL_INDEX)
216
{
217
if (getMemoryReference()->getTOCOffset()<LOWER_IMMED ||
218
getMemoryReference()->getTOCOffset()>UPPER_IMMED)
219
{
220
*(int32_t *)cursor = 0x3c000000;
221
toRealRegister(getMemoryReference()->getModBase())->setRegisterFieldRT((uint32_t *)cursor);
222
}
223
else
224
{
225
*(int32_t *)cursor = comp->target().is64Bit()?0xe8000000:0x80000000;
226
getDataRegister()->setRegisterFieldRT((uint32_t *)cursor);
227
}
228
cg()->getTOCBaseRegister()->setRegisterFieldRA((uint32_t *)cursor);
229
}
230
else
231
{
232
*(int32_t *)cursor = 0x3c000000;
233
getDataRegister()->setRegisterFieldRT((uint32_t *)cursor);
234
}
235
}
236
else
237
{
238
*(int32_t *)cursor = 0x3c000000; // Template
239
toRealRegister(getMemoryReference()->getModBase())->setRegisterFieldRT((uint32_t *)cursor);
240
if (getMemoryReference()->getBaseRegister() == NULL)
241
{
242
cg()->machine()->getRealRegister(TR::RealRegister::gr0)->setRegisterFieldRA((uint32_t *)cursor);
243
}
244
else
245
{
246
toRealRegister(getMemoryReference()->getBaseRegister())->setRegisterFieldRA((uint32_t *)cursor);
247
}
248
}
249
cursor += 4;
250
251
*(int32_t *)cursor = 0; // Lock word
252
253
// CLInit case
254
cursor += 4;
255
*(int32_t *)cursor = 0xdeadbeef; // Patched with lis via runtime code
256
cursor += 4;
257
intptr_t targetAddress = (intptr_t)getAddressOfDataReference()+4;
258
TR_ASSERT_FATAL(comp->target().cpu.isTargetWithinIFormBranchRange(targetAddress, (intptr_t)cursor),
259
"Return address is out of range");
260
*(int32_t *)cursor = 0x48000000 | ((targetAddress - (intptr_t)cursor) & 0x03fffffc);
261
262
return cursor+4;
263
}
264
265
266
void
267
TR_Debug::print(TR::FILE *pOutFile, TR::UnresolvedDataSnippet * snippet)
268
{
269
uint8_t *cursor = snippet->getSnippetLabel()->getCodeLocation();
270
271
printSnippetLabel(pOutFile, snippet->getSnippetLabel(), cursor, "Unresolved Data Snippet");
272
273
TR::SymbolReference *glueRef;
274
275
if (snippet->getDataSymbol()->getShadowSymbol() != NULL) // instance data
276
{
277
if (snippet->isUnresolvedStore())
278
glueRef = _cg->getSymRef(TR_PPCinterpreterUnresolvedInstanceDataStoreGlue);
279
else
280
glueRef = _cg->getSymRef(TR_PPCinterpreterUnresolvedInstanceDataGlue);
281
}
282
else if (snippet->getDataSymbol()->isClassObject())
283
{
284
if (snippet->getDataSymbol()->addressIsCPIndexOfStatic())
285
glueRef = _cg->getSymRef(TR_PPCinterpreterUnresolvedClassGlue2);
286
else
287
glueRef = _cg->getSymRef(TR_PPCinterpreterUnresolvedClassGlue);
288
}
289
else if (snippet->getDataSymbol()->isConstString())
290
{
291
glueRef = _cg->getSymRef(TR_PPCinterpreterUnresolvedStringGlue);
292
}
293
else if (snippet->getDataSymbol()->isConstMethodType())
294
{
295
glueRef = _cg->getSymRef(TR_interpreterUnresolvedMethodTypeGlue);
296
}
297
else if (snippet->getDataSymbol()->isConstMethodHandle())
298
{
299
glueRef = _cg->getSymRef(TR_interpreterUnresolvedMethodHandleGlue);
300
}
301
else if (snippet->getDataSymbol()->isCallSiteTableEntry())
302
{
303
glueRef = _cg->getSymRef(TR_interpreterUnresolvedCallSiteTableEntryGlue);
304
}
305
else if (snippet->getDataSymbol()->isMethodTypeTableEntry())
306
{
307
glueRef = _cg->getSymRef(TR_interpreterUnresolvedMethodTypeTableEntryGlue);
308
}
309
else if (snippet->getDataSymbol()->isConstantDynamic())
310
{
311
glueRef = _cg->getSymRef(TR_PPCinterpreterUnresolvedConstantDynamicGlue);
312
}
313
else // must be static data
314
{
315
if (snippet->isUnresolvedStore())
316
glueRef = _cg->getSymRef(TR_PPCinterpreterUnresolvedStaticDataStoreGlue);
317
else
318
glueRef = _cg->getSymRef(TR_PPCinterpreterUnresolvedStaticDataGlue);
319
}
320
321
char *info = "";
322
int32_t distance;
323
if (isBranchToTrampoline(glueRef, cursor, distance))
324
info = " Through Trampoline";
325
326
printPrefix(pOutFile, NULL, cursor, 4);
327
distance = *((int32_t *) cursor) & 0x03fffffc;
328
distance = (distance << 6) >> 6; // sign extend
329
trfprintf(pOutFile, "bl \t" POINTER_PRINTF_FORMAT "\t\t;%s", (intptr_t)cursor + distance, info);
330
cursor += 4;
331
332
printPrefix(pOutFile, NULL, cursor, sizeof(intptr_t));
333
trfprintf(pOutFile, ".long \t" POINTER_PRINTF_FORMAT "\t\t; Code cache return address", *(intptr_t *)cursor);
334
cursor += sizeof(intptr_t);
335
336
printPrefix(pOutFile, NULL, cursor, 4);
337
trfprintf(pOutFile, ".long \t0x%08x\t\t; pTOC|VD|SY|IX|cpIndex of the data reference", *(int32_t *)cursor);
338
cursor += 4;
339
340
printPrefix(pOutFile, NULL, cursor, sizeof(intptr_t));
341
trfprintf(pOutFile, ".long \t" POINTER_PRINTF_FORMAT "\t\t; Constant pool address", *(intptr_t *)cursor);
342
cursor += sizeof(intptr_t);
343
344
printPrefix(pOutFile, NULL, cursor, 4);
345
trfprintf(pOutFile, ".long \t0x%08x\t\t; Offset to be merged", *(int32_t *)cursor);
346
cursor += 4;
347
348
printPrefix(pOutFile, NULL, cursor, 4);
349
trfprintf(pOutFile, ".long \t0x%08x\t\t; Instruction template", *(int32_t *)cursor);
350
cursor += 4;
351
352
printPrefix(pOutFile, NULL, cursor, 4);
353
trfprintf(pOutFile, ".long \t0x%08x\t\t; Lock word initialized to 0", *(int32_t *)cursor);
354
cursor += 4;
355
356
printPrefix(pOutFile, NULL, cursor, 4);
357
trfprintf(pOutFile, ".long \t0x%08x\t\t; <clinit> case - 1st instruction (0xdeadbeef)", *(int32_t *)cursor);
358
cursor += 4;
359
360
printPrefix(pOutFile, NULL, cursor, 4);
361
distance = *((int32_t *) cursor) & 0x03fffffc;
362
distance = (distance << 6) >> 6; // sign extend
363
trfprintf(pOutFile, "b \t" POINTER_PRINTF_FORMAT "\t\t; <clinit> case - Branch back to main line code", (intptr_t)cursor + distance);
364
}
365
366
uint32_t J9::Power::UnresolvedDataSnippet::getLength(int32_t estimatedSnippetStart)
367
{
368
return 28+2*TR::Compiler->om.sizeofReferenceAddress();
369
}
370
371