Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/p/codegen/J9AheadOfTimeCompile.cpp
6004 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2022 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/AheadOfTimeCompile.hpp"
24
#include "codegen/CodeGenerator.hpp"
25
#include "env/FrontEnd.hpp"
26
#include "codegen/Instruction.hpp"
27
#include "compile/AOTClassInfo.hpp"
28
#include "compile/Compilation.hpp"
29
#include "compile/ResolvedMethod.hpp"
30
#include "compile/VirtualGuard.hpp"
31
#include "env/CHTable.hpp"
32
#include "env/ClassLoaderTable.hpp"
33
#include "env/CompilerEnv.hpp"
34
#include "env/SharedCache.hpp"
35
#include "env/jittypes.h"
36
#include "env/VMJ9.h"
37
#include "il/LabelSymbol.hpp"
38
#include "il/Node.hpp"
39
#include "il/Node_inlines.hpp"
40
#include "il/SymbolReference.hpp"
41
#include "ras/DebugCounter.hpp"
42
#include "runtime/RelocationRuntime.hpp"
43
#include "runtime/RelocationRecord.hpp"
44
#include "runtime/SymbolValidationManager.hpp"
45
46
J9::Power::AheadOfTimeCompile::AheadOfTimeCompile(TR::CodeGenerator *cg) :
47
J9::AheadOfTimeCompile(NULL, cg->comp()),
48
_cg(cg)
49
{
50
}
51
52
void J9::Power::AheadOfTimeCompile::processRelocations()
53
{
54
TR::Compilation *comp = _cg->comp();
55
TR_J9VMBase *fej9 = (TR_J9VMBase *)(_cg->fe());
56
TR::IteratedExternalRelocation *r;
57
58
for (auto iterator = getRelocationList().begin(); iterator != getRelocationList().end(); ++iterator)
59
(*iterator)->mapRelocation(_cg);
60
61
auto aotIterator = _cg->getExternalRelocationList().begin();
62
while (aotIterator != _cg->getExternalRelocationList().end())
63
{
64
(*aotIterator)->addExternalRelocation(_cg);
65
++aotIterator;
66
}
67
68
for (r = getAOTRelocationTargets().getFirst(); r != NULL; r = r->getNext())
69
{
70
addToSizeOfAOTRelocations(r->getSizeOfRelocationData());
71
}
72
73
// now allocate the memory size of all iterated relocations + the header (total length field)
74
75
// Note that when using the SymbolValidationManager, the well-known classes
76
// must be checked even if no explicit records were generated, since they
77
// might be responsible for the lack of records.
78
bool useSVM = comp->getOption(TR_UseSymbolValidationManager);
79
if (self()->getSizeOfAOTRelocations() != 0 || useSVM)
80
{
81
// It would be more straightforward to put the well-known classes offset
82
// in the AOT method header, but that would use space for AOT bodies that
83
// don't use the SVM. TODO: Move it once SVM takes over?
84
int wellKnownClassesOffsetSize = useSVM ? SIZEPOINTER : 0;
85
uintptr_t reloBufferSize =
86
self()->getSizeOfAOTRelocations() + SIZEPOINTER + wellKnownClassesOffsetSize;
87
uint8_t *relocationDataCursor = self()->setRelocationData(
88
fej9->allocateRelocationData(comp, reloBufferSize));
89
// set up the size for the region
90
*(uintptr_t*)relocationDataCursor = reloBufferSize;
91
relocationDataCursor += SIZEPOINTER;
92
93
if (useSVM)
94
{
95
TR::SymbolValidationManager *svm = comp->getSymbolValidationManager();
96
void *offsets = const_cast<void *>(svm->wellKnownClassChainOffsets());
97
uintptr_t *wkcOffsetAddr = (uintptr_t *)relocationDataCursor;
98
*wkcOffsetAddr = self()->offsetInSharedCacheFromPointer(fej9->sharedCache(), offsets);
99
#if defined(J9VM_OPT_JITSERVER)
100
self()->addWellKnownClassesSerializationRecord(svm->aotCacheWellKnownClassesRecord(), wkcOffsetAddr);
101
#endif /* defined(J9VM_OPT_JITSERVER) */
102
relocationDataCursor += SIZEPOINTER;
103
}
104
105
// set up pointers for each iterated relocation and initialize header
106
TR::IteratedExternalRelocation *s;
107
for (s = getAOTRelocationTargets().getFirst(); s != NULL; s = s->getNext())
108
{
109
s->setRelocationData(relocationDataCursor);
110
s->initializeRelocation(_cg);
111
relocationDataCursor += s->getSizeOfRelocationData();
112
}
113
}
114
}
115
116
bool
117
J9::Power::AheadOfTimeCompile::initializePlatformSpecificAOTRelocationHeader(TR::IteratedExternalRelocation *relocation,
118
TR_RelocationTarget *reloTarget,
119
TR_RelocationRecord *reloRecord,
120
uint8_t targetKind)
121
{
122
bool platformSpecificReloInitialized = true;
123
TR::Compilation *comp = self()->comp();
124
TR_J9VMBase *fej9 = comp->fej9();
125
TR_SharedCache *sharedCache = fej9->sharedCache();
126
uint8_t * aotMethodCodeStart = (uint8_t *) comp->getRelocatableMethodCodeStart();
127
128
switch (targetKind)
129
{
130
case TR_ClassAddress:
131
{
132
TR_RelocationRecordClassAddress *caRecord = reinterpret_cast<TR_RelocationRecordClassAddress *>(reloRecord);
133
TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation*) relocation->getTargetAddress();
134
135
TR::SymbolReference *symRef = reinterpret_cast<TR::SymbolReference *>(recordInfo->data1);
136
uintptr_t inlinedSiteIndex = reinterpret_cast<uintptr_t>(recordInfo->data2);
137
uint8_t flags = static_cast<uint8_t>(recordInfo->data3);
138
139
void *constantPool = symRef->getOwningMethod(comp)->constantPool();
140
inlinedSiteIndex = self()->findCorrectInlinedSiteIndex(constantPool, inlinedSiteIndex);
141
142
TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");
143
caRecord->setReloFlags(reloTarget, flags);
144
caRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex);
145
caRecord->setConstantPool(reloTarget, reinterpret_cast<uintptr_t>(constantPool));
146
caRecord->setCpIndex(reloTarget, symRef->getCPIndex());
147
}
148
break;
149
150
case TR_DataAddress:
151
{
152
TR_RelocationRecordDataAddress *daRecord = reinterpret_cast<TR_RelocationRecordDataAddress *>(reloRecord);
153
TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation*) relocation->getTargetAddress();
154
155
TR::SymbolReference *symRef = reinterpret_cast<TR::SymbolReference *>(recordInfo->data1);
156
uintptr_t inlinedSiteIndex = reinterpret_cast<uintptr_t>(recordInfo->data2);
157
uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(recordInfo->data3));
158
159
void *constantPool = symRef->getOwningMethod(comp)->constantPool();
160
inlinedSiteIndex = self()->findCorrectInlinedSiteIndex(constantPool, inlinedSiteIndex);
161
162
TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");
163
daRecord->setReloFlags(reloTarget, flags);
164
daRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex);
165
daRecord->setConstantPool(reloTarget, reinterpret_cast<uintptr_t>(constantPool));
166
daRecord->setCpIndex(reloTarget, symRef->getCPIndex());
167
daRecord->setOffset(reloTarget, symRef->getOffset());
168
}
169
break;
170
171
case TR_AbsoluteHelperAddress:
172
{
173
TR_RelocationRecordAbsoluteHelperAddress *ahaRecord = reinterpret_cast<TR_RelocationRecordAbsoluteHelperAddress *>(reloRecord);
174
TR::SymbolReference *symRef = reinterpret_cast<TR::SymbolReference *>(relocation->getTargetAddress());
175
uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));
176
177
ahaRecord->setHelperID(reloTarget, static_cast<uint32_t>(symRef->getReferenceNumber()));
178
ahaRecord->setReloFlags(reloTarget, flags);
179
}
180
break;
181
182
case TR_AbsoluteMethodAddressOrderedPair:
183
{
184
TR_RelocationRecordMethodAddress *maRecord = reinterpret_cast<TR_RelocationRecordMethodAddress *>(reloRecord);
185
186
TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation *) relocation->getTargetAddress();
187
uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(recordInfo->data3));
188
189
TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");
190
maRecord->setReloFlags(reloTarget, flags);
191
}
192
break;
193
194
case TR_FixedSequenceAddress:
195
{
196
TR_RelocationRecordWithOffset *rwoRecord = reinterpret_cast<TR_RelocationRecordWithOffset *>(reloRecord);
197
198
TR::LabelSymbol *table = reinterpret_cast<TR::LabelSymbol *>(relocation->getTargetAddress());
199
uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));
200
uint8_t *codeLocation = table->getCodeLocation();
201
202
TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");
203
rwoRecord->setReloFlags(reloTarget, flags);
204
if (comp->target().is64Bit())
205
{
206
rwoRecord->setOffset(reloTarget, static_cast<uintptr_t>(codeLocation - aotMethodCodeStart));
207
}
208
else
209
{
210
TR_ASSERT_FATAL(false, "Creating TR_FixedSeqAddress/TR_FixedSeq2Address relo for 32-bit target");
211
}
212
}
213
break;
214
215
case TR_FixedSequenceAddress2:
216
{
217
TR_RelocationRecordWithOffset *rwoRecord = reinterpret_cast<TR_RelocationRecordWithOffset *>(reloRecord);
218
uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));
219
220
TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");
221
rwoRecord->setReloFlags(reloTarget, flags);
222
if (comp->target().is64Bit())
223
{
224
TR_ASSERT_FATAL(relocation->getTargetAddress(), "target address is NULL");
225
226
uintptr_t offset = relocation->getTargetAddress()
227
? static_cast<uintptr_t>(relocation->getTargetAddress() - aotMethodCodeStart)
228
: 0x0;
229
230
rwoRecord->setOffset(reloTarget, offset);
231
}
232
else
233
{
234
TR_ASSERT_FATAL(0, "Creating TR_LoadAddress/TR_LoadAddressTempReg relo for 32-bit target");
235
}
236
}
237
break;
238
239
case TR_ArrayCopyHelper:
240
case TR_ArrayCopyToc:
241
case TR_BodyInfoAddressLoad:
242
case TR_RecompQueuedFlag:
243
{
244
TR_RelocationRecord *rRecord = reinterpret_cast<TR_RelocationRecord *>(reloRecord);
245
uint8_t flags;
246
247
if (comp->target().is64Bit())
248
{
249
flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));
250
}
251
else
252
{
253
TR_RelocationRecordInformation *recordInfo = reinterpret_cast<TR_RelocationRecordInformation *>(relocation->getTargetAddress());
254
flags = static_cast<uint8_t>(recordInfo->data3);
255
}
256
257
TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");
258
rRecord->setReloFlags(reloTarget, flags);
259
}
260
break;
261
262
case TR_RamMethodSequence:
263
{
264
TR_RelocationRecordRamSequence *rsRecord = reinterpret_cast<TR_RelocationRecordRamSequence *>(reloRecord);
265
uint8_t flags;
266
267
if (comp->target().is64Bit())
268
{
269
flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));
270
271
TR_ASSERT_FATAL(relocation->getTargetAddress(), "target address is NULL");
272
273
uintptr_t offset = relocation->getTargetAddress()
274
? static_cast<uintptr_t>(relocation->getTargetAddress() - aotMethodCodeStart)
275
: 0x0;
276
277
rsRecord->setOffset(reloTarget, offset);
278
}
279
else
280
{
281
TR_RelocationRecordInformation *recordInfo = reinterpret_cast<TR_RelocationRecordInformation *>(relocation->getTargetAddress());
282
flags = static_cast<uint8_t>(recordInfo->data3);
283
284
// Skip Offset
285
}
286
287
TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");
288
rsRecord->setReloFlags(reloTarget, flags);
289
}
290
break;
291
292
case TR_ArbitraryClassAddress:
293
{
294
TR_RelocationRecordArbitraryClassAddress *acaRecord = reinterpret_cast<TR_RelocationRecordArbitraryClassAddress *>(reloRecord);
295
296
// ExternalRelocation data is as expected for TR_ClassAddress
297
TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation *)relocation->getTargetAddress();
298
299
auto symRef = (TR::SymbolReference *)recordInfo->data1;
300
auto sym = symRef->getSymbol()->castToStaticSymbol();
301
auto j9class = (TR_OpaqueClassBlock *)sym->getStaticAddress();
302
uint8_t flags = (uint8_t)recordInfo->data3;
303
uintptr_t inlinedSiteIndex = self()->findCorrectInlinedSiteIndex(symRef->getOwningMethod(comp)->constantPool(), recordInfo->data2);
304
305
uintptr_t classChainIdentifyingLoaderOffsetInSharedCache = sharedCache->getClassChainOffsetIdentifyingLoader(j9class);
306
const AOTCacheClassChainRecord *classChainRecord = NULL;
307
uintptr_t classChainOffsetInSharedCache = self()->getClassChainOffset(j9class, classChainRecord);
308
309
TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits");
310
acaRecord->setReloFlags(reloTarget, flags);
311
acaRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex);
312
acaRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainIdentifyingLoaderOffsetInSharedCache,
313
self(), classChainRecord);
314
acaRecord->setClassChainForInlinedMethod(reloTarget, classChainOffsetInSharedCache, self(), classChainRecord);
315
}
316
break;
317
318
case TR_GlobalValue:
319
{
320
TR_RelocationRecordGlobalValue *gvRecord = reinterpret_cast<TR_RelocationRecordGlobalValue *>(reloRecord);
321
322
uintptr_t gv;
323
uint8_t flags;
324
325
if (comp->target().is64Bit())
326
{
327
gv = reinterpret_cast<uintptr_t>(relocation->getTargetAddress());
328
flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));
329
}
330
else
331
{
332
TR_RelocationRecordInformation *recordInfo = reinterpret_cast<TR_RelocationRecordInformation*>(relocation->getTargetAddress());
333
gv = recordInfo->data1;
334
flags = static_cast<uint8_t>(recordInfo->data3);
335
}
336
337
TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");
338
gvRecord->setReloFlags(reloTarget, flags);
339
gvRecord->setOffset(reloTarget, gv);
340
}
341
break;
342
343
case TR_DiscontiguousSymbolFromManager:
344
{
345
TR_RelocationRecordDiscontiguousSymbolFromManager *dsfmRecord = reinterpret_cast<TR_RelocationRecordDiscontiguousSymbolFromManager *>(reloRecord);
346
347
TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation*) relocation->getTargetAddress();
348
349
uint8_t *symbol = (uint8_t *)recordInfo->data1;
350
uint16_t symbolID = comp->getSymbolValidationManager()->getSymbolIDFromValue(static_cast<void *>(symbol));
351
352
uint16_t symbolType = (uint16_t)recordInfo->data2;
353
354
uint8_t flags = (uint8_t) recordInfo->data3;
355
TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");
356
357
dsfmRecord->setSymbolID(reloTarget, symbolID);
358
dsfmRecord->setSymbolType(reloTarget, static_cast<TR::SymbolType>(symbolType));
359
dsfmRecord->setReloFlags(reloTarget, flags);
360
}
361
break;
362
363
case TR_HCR:
364
{
365
TR_RelocationRecordHCR *hcrRecord = reinterpret_cast<TR_RelocationRecordHCR *>(reloRecord);
366
367
uintptr_t gv = reinterpret_cast<uintptr_t>(relocation->getTargetAddress());
368
uint8_t flags = static_cast<uint8_t>(reinterpret_cast<uintptr_t>(relocation->getTargetAddress2()));
369
370
TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n");
371
hcrRecord->setReloFlags(reloTarget, flags);
372
hcrRecord->setOffset(reloTarget, gv);
373
}
374
break;
375
376
default:
377
platformSpecificReloInitialized = false;
378
}
379
380
return platformSpecificReloInitialized;
381
}
382
383
384