Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/compile/J9SymbolReferenceTable.cpp
6000 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 "omrformatconsts.h"
24
#include "codegen/CodeGenerator.hpp"
25
#include "env/KnownObjectTable.hpp"
26
#include "compile/AliasBuilder.hpp"
27
#include "compile/Compilation.hpp"
28
#include "compile/Method.hpp"
29
#include "compile/ResolvedMethod.hpp"
30
#include "compile/SymbolReferenceTable.hpp"
31
#include "cs2/hashtab.h"
32
#include "env/CHTable.hpp"
33
#include "env/CompilerEnv.hpp"
34
#include "env/PersistentInfo.hpp"
35
#include "env/StackMemoryRegion.hpp"
36
#include "env/TRMemory.hpp"
37
#include "env/VMAccessCriticalSection.hpp"
38
#include "env/VMJ9.h"
39
#include "env/j9method.h"
40
#include "env/jittypes.h"
41
#include "il/StaticSymbol.hpp"
42
#include "il/StaticSymbol_inlines.hpp"
43
#include "il/ParameterSymbol.hpp"
44
#include "il/RegisterMappedSymbol.hpp"
45
#include "il/ResolvedMethodSymbol.hpp"
46
#include "il/SymbolReference.hpp"
47
#include "ilgen/IlGen.hpp"
48
#include "ilgen/J9ByteCodeIlGenerator.hpp"
49
#include "infra/Assert.hpp"
50
#include "infra/BitVector.hpp"
51
#include "infra/List.hpp"
52
#include "infra/String.hpp"
53
#include "runtime/RuntimeAssumptions.hpp"
54
#include "env/PersistentCHTable.hpp"
55
#include "optimizer/TransformUtil.hpp"
56
#if defined(J9VM_OPT_JITSERVER)
57
#include "env/j9methodServer.hpp"
58
#endif /* defined(J9VM_OPT_JITSERVER) */
59
60
namespace J9
61
{
62
enum NonUserMethod
63
{
64
unknownNonUserMethod,
65
nonUser_java_util_HashMap_rehash,
66
nonUser_java_util_HashMap_analyzeMap,
67
nonUser_java_util_HashMap_calculateCapacity,
68
nonUser_java_util_HashMap_findNullKeyEntry,
69
70
numNonUserMethods
71
};
72
}
73
74
75
J9::SymbolReferenceTable::SymbolReferenceTable(size_t sizeHint, TR::Compilation *c) :
76
OMR::SymbolReferenceTableConnector(sizeHint, c),
77
_immutableInfo(c->trMemory()),
78
_immutableSymRefNumbers(c->trMemory(), _numImmutableClasses),
79
_dynamicMethodSymrefsByCallSiteIndex(c->trMemory()),
80
_unsafeJavaStaticSymRefs(NULL),
81
_unsafeJavaStaticVolatileSymRefs(NULL),
82
_currentThreadDebugEventDataSymbol(0),
83
_currentThreadDebugEventDataSymbolRefs(c->trMemory()),
84
_constantPoolAddressSymbolRefs(c->trMemory()),
85
_resolvedFieldShadows(
86
std::less<ResolvedFieldShadowKey>(),
87
getTypedAllocator<ResolvedFieldShadowsEntry>(c->allocator())),
88
_flattenedArrayElementFieldShadows(
89
std::less<ResolvedFieldShadowKey>(),
90
getTypedAllocator<FlattenedArrayElementFieldShadowsEntry>(c->allocator()))
91
{
92
for (uint32_t i = 0; i < _numImmutableClasses; i++)
93
_immutableSymRefNumbers[i] = new (trHeapMemory()) TR_BitVector(sizeHint, c->trMemory(), heapAlloc, growable);
94
}
95
96
97
TR::SymbolReference *
98
J9::SymbolReferenceTable::findOrCreateCountForRecompileSymbolRef()
99
{
100
if (!element(countForRecompileSymbol))
101
{
102
TR::StaticSymbol * sym = TR::StaticSymbol::create(trHeapMemory(),TR::Int32);
103
TR::PersistentInfo *pinfo = comp()->getPersistentInfo();
104
sym->setStaticAddress(&(pinfo->_countForRecompile));
105
sym->setCountForRecompile();
106
sym->setNotDataAddress();
107
element(countForRecompileSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), countForRecompileSymbol, sym);
108
}
109
return element(countForRecompileSymbol);
110
}
111
112
113
TR::SymbolReference *
114
J9::SymbolReferenceTable::findOrCreateOSRBufferSymbolRef()
115
{
116
if (!element(osrBufferSymbol))
117
{
118
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
119
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "OSRBuffer");
120
sym->setDataType(TR::Address);
121
sym->setNotCollected();
122
element(osrBufferSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), osrBufferSymbol, sym);
123
element(osrBufferSymbol)->setOffset(fej9->thisThreadGetOSRBufferOffset());
124
125
// We can't let the load/store of the exception symbol swing down
126
aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(osrBufferSymbol)); // add the symRef to the statics list to get correct aliasing info
127
}
128
return element(osrBufferSymbol);
129
}
130
131
132
TR::SymbolReference *
133
J9::SymbolReferenceTable::findOrCreateOSRScratchBufferSymbolRef()
134
{
135
if (!element(osrScratchBufferSymbol))
136
{
137
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
138
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "OSRScratchBuffer");
139
sym->setDataType(TR::Address);
140
sym->setNotCollected();
141
element(osrScratchBufferSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), osrScratchBufferSymbol, sym);
142
element(osrScratchBufferSymbol)->setOffset(fej9->thisThreadGetOSRScratchBufferOffset());
143
144
// We can't let the load/store of the exception symbol swing down
145
aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(osrScratchBufferSymbol)); // add the symRef to the statics list to get correct aliasing info
146
}
147
return element(osrScratchBufferSymbol);
148
}
149
150
151
TR::SymbolReference *
152
J9::SymbolReferenceTable::findOrCreateOSRFrameIndexSymbolRef()
153
{
154
if (!element(osrFrameIndexSymbol))
155
{
156
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
157
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "osrFrameIndex");
158
sym->setDataType(TR::Int32);
159
element(osrFrameIndexSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), osrFrameIndexSymbol, sym);
160
element(osrFrameIndexSymbol)->setOffset(fej9->thisThreadGetOSRFrameIndexOffset());
161
162
// We can't let the load/store of the exception symbol swing down
163
//SD: do we need this?
164
aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(osrFrameIndexSymbol)); // add the symRef to the statics list to get correct aliasing info
165
}
166
return element(osrFrameIndexSymbol);
167
}
168
169
170
TR::SymbolReference *
171
J9::SymbolReferenceTable::findOrCreateAcquireVMAccessSymbolRef(TR::ResolvedMethodSymbol *)
172
{
173
return findOrCreateRuntimeHelper(TR_acquireVMAccess, true, false, true);
174
}
175
176
177
TR::SymbolReference *
178
J9::SymbolReferenceTable::findOrCreateThrowCurrentExceptionSymbolRef(TR::ResolvedMethodSymbol *)
179
{
180
return findOrCreateRuntimeHelper(TR_throwCurrentException, true, false, true);
181
}
182
183
TR::SymbolReference *
184
J9::SymbolReferenceTable::findOrCreateThrowUnreportedExceptionSymbolRef(TR::ResolvedMethodSymbol *)
185
{
186
return findOrCreateRuntimeHelper(TR_throwUnreportedException, true /* canGCandReturn */, false /* canGCandExcept */, true /* preservesAllRegisters */);
187
}
188
189
TR::SymbolReference *
190
J9::SymbolReferenceTable::findOrCreateReleaseVMAccessSymbolRef(TR::ResolvedMethodSymbol *)
191
{
192
return findOrCreateRuntimeHelper(TR_releaseVMAccess, true, false, true);
193
}
194
195
196
TR::SymbolReference *
197
J9::SymbolReferenceTable::findOrCreateStackOverflowSymbolRef(TR::ResolvedMethodSymbol *)
198
{
199
return findOrCreateRuntimeHelper(TR_stackOverflow, true, true, true);
200
}
201
202
203
TR::SymbolReference *
204
J9::SymbolReferenceTable::findOrCreateWriteBarrierStoreSymbolRef(TR::ResolvedMethodSymbol *)
205
{
206
return findOrCreateRuntimeHelper(TR_writeBarrierStore, false, false, true);
207
}
208
209
210
TR::SymbolReference *
211
J9::SymbolReferenceTable::findOrCreateWriteBarrierStoreGenerationalSymbolRef(TR::ResolvedMethodSymbol *)
212
{
213
return findOrCreateRuntimeHelper(TR_writeBarrierStoreGenerational, false, false, true);
214
}
215
216
217
TR::SymbolReference *
218
J9::SymbolReferenceTable::findOrCreateWriteBarrierStoreGenerationalAndConcurrentMarkSymbolRef(TR::ResolvedMethodSymbol *)
219
{
220
return findOrCreateRuntimeHelper(TR_writeBarrierStoreGenerationalAndConcurrentMark, false, false, true);
221
}
222
223
224
TR::SymbolReference *
225
J9::SymbolReferenceTable::findOrCreateWriteBarrierStoreRealTimeGCSymbolRef(TR::ResolvedMethodSymbol *)
226
{
227
return findOrCreateRuntimeHelper(TR_writeBarrierStoreRealTimeGC, true, true, true);
228
}
229
230
231
TR::SymbolReference *
232
J9::SymbolReferenceTable::findOrCreateWriteBarrierClassStoreRealTimeGCSymbolRef(TR::ResolvedMethodSymbol *)
233
{
234
return findOrCreateRuntimeHelper(TR_writeBarrierClassStoreRealTimeGC, true, true, true);
235
}
236
237
238
TR::SymbolReference *
239
J9::SymbolReferenceTable::findOrCreateWriteBarrierBatchStoreSymbolRef(TR::ResolvedMethodSymbol *)
240
{
241
return findOrCreateRuntimeHelper(TR_writeBarrierBatchStore, false, false, true);
242
}
243
244
245
TR::SymbolReference *
246
J9::SymbolReferenceTable::findOrCreateAcmpeqHelperSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)
247
{
248
return findOrCreateRuntimeHelper(TR_acmpeqHelper, true, false, true);
249
}
250
251
252
TR::SymbolReference *
253
J9::SymbolReferenceTable::findOrCreateAcmpneHelperSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)
254
{
255
return findOrCreateRuntimeHelper(TR_acmpneHelper, true, false, true);
256
}
257
258
259
TR::SymbolReference *
260
J9::SymbolReferenceTable::findOrCreateGetFlattenableFieldSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)
261
{
262
return findOrCreateRuntimeHelper(TR_getFlattenableField, true, true, true);
263
}
264
265
266
TR::SymbolReference *
267
J9::SymbolReferenceTable::findOrCreateWithFlattenableFieldSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)
268
{
269
return findOrCreateRuntimeHelper(TR_withFlattenableField, true, true, true);
270
}
271
272
273
TR::SymbolReference *
274
J9::SymbolReferenceTable::findOrCreatePutFlattenableFieldSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)
275
{
276
return findOrCreateRuntimeHelper(TR_putFlattenableField, true, true, true);
277
}
278
279
280
TR::SymbolReference *
281
J9::SymbolReferenceTable::findOrCreateGetFlattenableStaticFieldSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)
282
{
283
return findOrCreateRuntimeHelper(TR_getFlattenableStaticField, true, true, true);
284
}
285
286
287
TR::SymbolReference *
288
J9::SymbolReferenceTable::findOrCreatePutFlattenableStaticFieldSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)
289
{
290
return findOrCreateRuntimeHelper(TR_putFlattenableStaticField, true, true, true);
291
}
292
293
294
TR::SymbolReference *
295
J9::SymbolReferenceTable::findOrCreateLoadFlattenableArrayElementSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)
296
{
297
return findOrCreateRuntimeHelper(TR_ldFlattenableArrayElement, true, true, true);
298
}
299
300
301
TR::SymbolReference *
302
J9::SymbolReferenceTable::findOrCreateStoreFlattenableArrayElementSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)
303
{
304
return findOrCreateRuntimeHelper(TR_strFlattenableArrayElement, true, true, true);
305
}
306
307
308
TR::SymbolReference *
309
J9::SymbolReferenceTable::findOrCreateLookupDynamicInterfaceMethodSymbolRef()
310
{
311
return findOrCreateRuntimeHelper(TR_jitLookupDynamicInterfaceMethod, false, false, true);
312
}
313
314
315
TR::SymbolReference *
316
J9::SymbolReferenceTable::findOrCreateLookupDynamicPublicInterfaceMethodSymbolRef()
317
{
318
return findOrCreateRuntimeHelper(TR_jitLookupDynamicPublicInterfaceMethod, false, true, true);
319
}
320
321
322
TR::SymbolReference *
323
J9::SymbolReferenceTable::findOrCreateFloatSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
324
{
325
void * dataAddress = owningMethodSymbol->getResolvedMethod()->floatConstant(cpIndex);
326
TR::SymbolReference * symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Float, true, dataAddress);
327
symRef->getSymbol()->setConst();
328
return symRef;
329
}
330
331
332
TR::SymbolReference *
333
J9::SymbolReferenceTable::findOrCreateDoubleSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
334
{
335
void * dataAddress = owningMethodSymbol->getResolvedMethod()->doubleConstant(cpIndex, trMemory());
336
TR::SymbolReference * symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Double, true, dataAddress);
337
symRef->getSymbol()->setConst();
338
return symRef;
339
}
340
341
342
TR::SymbolReference *
343
J9::SymbolReferenceTable::createSystemRuntimeHelper(
344
TR_RuntimeHelper index,
345
bool canGCandReturn,
346
bool canGCandExcept,
347
bool preservesAllRegisters)
348
{
349
TR::SymbolReference * symRef = createRuntimeHelper(index,false,false,false);
350
if (symRef)
351
{
352
symRef->getSymbol()->castToMethodSymbol()->setSystemLinkageDispatch();
353
symRef->getSymbol()->castToMethodSymbol()->setLinkage(TR_System);
354
}
355
return symRef;
356
}
357
358
TR::SymbolReference *
359
J9::SymbolReferenceTable::findOrCreateConstantPoolAddressSymbolRef(TR::ResolvedMethodSymbol * owningMethodSymbol)
360
{
361
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
362
void *cpAddress = owningMethodSymbol->getResolvedMethod()->constantPool();
363
ListIterator<TR::SymbolReference> i(&_constantPoolAddressSymbolRefs);
364
TR::SymbolReference * symRef;
365
for (symRef = i.getFirst(); symRef; symRef = i.getNext())
366
if (symRef->getSymbol()->getStaticSymbol()->getStaticAddress() == cpAddress)
367
return symRef;
368
369
TR::StaticSymbol * sym = TR::StaticSymbol::create(trHeapMemory(),TR::Address);
370
sym->setStaticAddress(cpAddress);
371
sym->setConstantPoolAddress();
372
sym->setNotCollected();
373
sym->setNotDataAddress();
374
375
symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1);
376
_constantPoolAddressSymbolRefs.add(symRef);
377
return symRef;
378
}
379
380
TR::SymbolReference *
381
J9::SymbolReferenceTable::findOrCreateStaticMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
382
{
383
bool isUnresolvedInCP;
384
TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedStaticMethod(comp(), cpIndex, &isUnresolvedInCP);
385
if (method)
386
owningMethodSymbol->setMayHaveInlineableCall(true);
387
388
return findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::Static, isUnresolvedInCP);
389
}
390
391
392
TR::SymbolReference *
393
J9::SymbolReferenceTable::findOrCreateSpecialMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
394
{
395
bool isUnresolvedInCP;
396
TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedSpecialMethod(comp(), cpIndex, &isUnresolvedInCP);
397
if (method)
398
owningMethodSymbol->setMayHaveInlineableCall(true);
399
400
return findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::Special, isUnresolvedInCP);
401
}
402
403
404
TR::SymbolReference *
405
J9::SymbolReferenceTable::findOrCreateVirtualMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
406
{
407
bool isUnresolvedInCP;
408
TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedVirtualMethod(comp(), cpIndex, false, &isUnresolvedInCP);
409
if (method)
410
owningMethodSymbol->setMayHaveInlineableCall(true);
411
412
return findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::Virtual, false); //isUnresolvedInCP);
413
}
414
415
416
TR::SymbolReference *
417
J9::SymbolReferenceTable::findOrCreateInterfaceMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
418
{
419
owningMethodSymbol->setMayHaveInlineableCall(true);
420
421
TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, 0, TR::MethodSymbol::Interface);
422
423
// javasoft.sqe.tests.vm.instr.invokeinterface.invokeinterface019.invokeinterface01910m1.invokeinterface01910m1
424
// has an invoke interface on a final method in object.
425
//
426
if (symRef->getSymbol()->castToMethodSymbol()->getMethod()->isFinalInObject())
427
{
428
comp()->failCompilation<TR::CompilationException>("Method symbol reference is final in object");
429
}
430
431
return symRef;
432
}
433
434
435
TR::SymbolReference *
436
J9::SymbolReferenceTable::findOrCreateDynamicMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t callSiteIndex, bool * unresolvedInCP)
437
{
438
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
439
TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedDynamicMethod(comp(), callSiteIndex, unresolvedInCP);
440
if (method)
441
owningMethodSymbol->setMayHaveInlineableCall(true);
442
443
TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), -1, method, TR::MethodSymbol::Static);
444
#else
445
List<TR::SymbolReference> *methods = dynamicMethodSymrefsByCallSiteIndex(callSiteIndex);
446
ListIterator<TR::SymbolReference> li(methods);
447
for (TR::SymbolReference *symRef = li.getFirst(); symRef; symRef = li.getNext())
448
{
449
if (symRef->getOwningMethodIndex() == owningMethodSymbol->getResolvedMethodIndex())
450
return symRef;
451
}
452
TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedDynamicMethod(comp(), callSiteIndex, unresolvedInCP);
453
TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), -1, method, TR::MethodSymbol::ComputedVirtual);
454
methods->add(symRef);
455
#endif /* J9VM_OPT_OPENJDK_METHODHANDLE */
456
return symRef;
457
}
458
459
460
TR::SymbolReference *
461
J9::SymbolReferenceTable::findOrCreateHandleMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, char *signature)
462
{
463
TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedHandleMethodWithSignature(comp(), cpIndex, signature);
464
if (method)
465
owningMethodSymbol->setMayHaveInlineableCall(true);
466
467
TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::ComputedVirtual);
468
return symRef;
469
}
470
471
472
TR::SymbolReference *
473
J9::SymbolReferenceTable::findOrCreateHandleMethodSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, bool * unresolvedInCP)
474
{
475
TR_ResolvedMethod * method = owningMethodSymbol->getResolvedMethod()->getResolvedHandleMethod(comp(), cpIndex, unresolvedInCP);
476
if (method)
477
owningMethodSymbol->setMayHaveInlineableCall(true);
478
479
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
480
TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::Static);
481
#else
482
TR::SymbolReference * symRef = findOrCreateMethodSymbol(owningMethodSymbol->getResolvedMethodIndex(), cpIndex, method, TR::MethodSymbol::ComputedVirtual);
483
#endif /* J9VM_OPT_OPENJDK_METHODHANDLE */
484
return symRef;
485
}
486
487
488
TR::SymbolReference *
489
J9::SymbolReferenceTable::findOrCreateCallSiteTableEntrySymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t callSiteIndex)
490
{
491
TR::SymbolReference *symRef;
492
TR_SymRefIterator i(aliasBuilder.callSiteTableEntrySymRefs(), self());
493
TR_ResolvedMethod *owningMethod = owningMethodSymbol->getResolvedMethod();
494
void *entryLocation = owningMethod->callSiteTableEntryAddress(callSiteIndex);
495
for (symRef = i.getNext(); symRef; symRef = i.getNext())
496
if ( owningMethodSymbol->getResolvedMethodIndex() == symRef->getOwningMethodIndex()
497
&& symRef->getSymbol()->castToStaticSymbol()->getStaticAddress() == entryLocation)
498
{
499
return symRef;
500
}
501
502
TR::StaticSymbol *sym = TR::StaticSymbol::create(trHeapMemory(),TR::Address);
503
sym->makeCallSiteTableEntry(callSiteIndex);
504
sym->setStaticAddress(entryLocation);
505
bool isUnresolved = owningMethod->isUnresolvedCallSiteTableEntry(callSiteIndex);
506
507
TR::KnownObjectTable::Index knownObjectIndex = TR::KnownObjectTable::UNKNOWN;
508
if (!isUnresolved)
509
{
510
TR::KnownObjectTable *knot = comp()->getOrCreateKnownObjectTable();
511
if (knot)
512
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
513
knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)entryLocation, true);
514
#else
515
knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)entryLocation);
516
#endif
517
}
518
519
symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1,
520
(isUnresolved ? _numUnresolvedSymbols++ : 0), knownObjectIndex);
521
522
if (isUnresolved)
523
{
524
// Resolving call site table entries causes java code to run
525
symRef->setUnresolved();
526
symRef->setCanGCandReturn();
527
symRef->setCanGCandExcept();
528
}
529
530
aliasBuilder.callSiteTableEntrySymRefs().set(symRef->getReferenceNumber());
531
return symRef;
532
}
533
534
TR::SymbolReference *
535
J9::SymbolReferenceTable::findOrCreateMethodTypeTableEntrySymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
536
{
537
TR::SymbolReference *symRef;
538
TR_SymRefIterator i(aliasBuilder.methodTypeTableEntrySymRefs(), self());
539
TR_ResolvedMethod *owningMethod = owningMethodSymbol->getResolvedMethod();
540
void *entryLocation = owningMethod->methodTypeTableEntryAddress(cpIndex);
541
for (symRef = i.getNext(); symRef; symRef = i.getNext())
542
if ( owningMethodSymbol->getResolvedMethodIndex() == symRef->getOwningMethodIndex()
543
&& symRef->getSymbol()->castToStaticSymbol()->getStaticAddress() == entryLocation)
544
{
545
return symRef;
546
}
547
548
TR::StaticSymbol *sym = TR::StaticSymbol::createMethodTypeTableEntry(trHeapMemory(),cpIndex);
549
sym->setStaticAddress(entryLocation);
550
bool isUnresolved = owningMethod->isUnresolvedMethodTypeTableEntry(cpIndex);
551
552
TR::KnownObjectTable::Index knownObjectIndex = TR::KnownObjectTable::UNKNOWN;
553
if (!isUnresolved)
554
{
555
TR::KnownObjectTable *knot = comp()->getOrCreateKnownObjectTable();
556
if (knot)
557
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
558
knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)entryLocation, true);
559
#else
560
knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)entryLocation);
561
#endif
562
}
563
564
symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1,
565
(isUnresolved ? _numUnresolvedSymbols++ : 0), knownObjectIndex);
566
567
if (isUnresolved)
568
{
569
// Resolving method type table entries causes java code to run
570
symRef->setUnresolved();
571
symRef->setCanGCandReturn();
572
symRef->setCanGCandExcept();
573
}
574
575
aliasBuilder.methodTypeTableEntrySymRefs().set(symRef->getReferenceNumber());
576
return symRef;
577
}
578
579
#if defined(J9VM_OPT_METHOD_HANDLE)
580
TR::SymbolReference *
581
J9::SymbolReferenceTable::findOrCreateVarHandleMethodTypeTableEntrySymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
582
{
583
// This function does the same thing as what findOrCreateMethodTypeTableEntrySymbol does except the way it gets the method type table entry address
584
TR::SymbolReference *symRef;
585
TR_SymRefIterator i(aliasBuilder.methodTypeTableEntrySymRefs(), self());
586
TR_ResolvedJ9Method *owningMethod = (TR_ResolvedJ9Method*)(owningMethodSymbol->getResolvedMethod());
587
void *entryLocation = owningMethod->varHandleMethodTypeTableEntryAddress(cpIndex);
588
for (symRef = i.getNext(); symRef; symRef = i.getNext())
589
if ( owningMethodSymbol->getResolvedMethodIndex() == symRef->getOwningMethodIndex()
590
&& symRef->getSymbol()->castToStaticSymbol()->getStaticAddress() == entryLocation)
591
{
592
return symRef;
593
}
594
595
TR::StaticSymbol *sym = TR::StaticSymbol::createMethodTypeTableEntry(trHeapMemory(),cpIndex);
596
sym->setStaticAddress(entryLocation);
597
bool isUnresolved = owningMethod->isUnresolvedVarHandleMethodTypeTableEntry(cpIndex);
598
symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1,
599
isUnresolved ? _numUnresolvedSymbols++ : 0);
600
if (isUnresolved)
601
{
602
// Resolving method type table entries causes java code to run
603
symRef->setUnresolved();
604
symRef->setCanGCandReturn();
605
symRef->setCanGCandExcept();
606
}
607
608
aliasBuilder.methodTypeTableEntrySymRefs().set(symRef->getReferenceNumber());
609
return symRef;
610
}
611
#endif /* defined(J9VM_OPT_METHOD_HANDLE) */
612
613
614
TR::SymbolReference *
615
J9::SymbolReferenceTable::methodSymRefWithSignature(TR::SymbolReference *originalSymRef, char *effectiveSignature, int32_t effectiveSignatureLength)
616
{
617
TR::ResolvedMethodSymbol *originalSymbol = originalSymRef->getSymbol()->castToResolvedMethodSymbol();
618
TR_ASSERT(originalSymbol, "methodSymRefWithSignature requires a resolved method symref");
619
TR_ASSERT(!originalSymbol->isVirtual(), "methodSymRefFromName doesn't support virtual methods"); // Until we're able to look up vtable index
620
int32_t cpIndex = originalSymRef->getCPIndex();
621
622
// Check _methodsBySignature to see if we've already created a symref for this one
623
//
624
TR::Method *originalMethod = originalSymbol->getMethod();
625
626
TR::StackMemoryRegion stackMemoryRegion(*trMemory());
627
628
int32_t fullSignatureLength = originalMethod->classNameLength() + 1 + originalMethod->nameLength() + effectiveSignatureLength;
629
char *fullSignature = (char*)trMemory()->allocateMemory(1 + fullSignatureLength, stackAlloc);
630
sprintf(fullSignature, "%.*s.%.*s%.*s", originalMethod->classNameLength(), originalMethod->classNameChars(), originalMethod->nameLength(), originalMethod->nameChars(), effectiveSignatureLength, effectiveSignature);
631
TR_ASSERT(strlen(fullSignature) == fullSignatureLength, "Computed fullSignatureLength must match actual length of fullSignature");
632
CS2::HashIndex hashIndex = 0;
633
static char *ignoreMBSCache = feGetEnv("TR_ignoreMBSCache");
634
OwningMethodAndString key(originalSymRef->getOwningMethodIndex(), fullSignature);
635
if (_methodsBySignature.Locate(key, hashIndex) && !ignoreMBSCache)
636
{
637
TR::SymbolReference *result = _methodsBySignature[hashIndex];
638
if (comp()->getOption(TR_TraceMethodIndex))
639
traceMsg(comp(), "-- MBS cache hit (2): M%p\n", result->getSymbol()->getResolvedMethodSymbol()->getResolvedMethod());
640
return result;
641
}
642
else
643
{
644
// fullSignature will be kept as a key by _methodsBySignature, so it needs heapAlloc
645
//
646
key = OwningMethodAndString(originalSymRef->getOwningMethodIndex(), self()->strdup(fullSignature));
647
if (comp()->getOption(TR_TraceMethodIndex))
648
traceMsg(comp(), "-- MBS cache miss (2) owning method #%d, signature %s\n", originalSymRef->getOwningMethodIndex().value(), fullSignature);
649
}
650
651
//
652
// No existing symref. Create a new one.
653
//
654
655
TR_OpaqueMethodBlock *method = originalSymbol->getResolvedMethod()->getPersistentIdentifier();
656
657
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
658
// Note: we use cpIndex=-1 here so we don't end up getting back originalSymRef (which will not have the signature we want)
659
TR::SymbolReference *result = findOrCreateMethodSymbol(originalSymRef->getOwningMethodIndex(), -1,
660
fej9->createResolvedMethodWithSignature(comp()->trMemory(), method, NULL, effectiveSignature, effectiveSignatureLength, originalSymbol->getResolvedMethod()->owningMethod()), originalSymbol->getMethodKind());
661
662
result->setCPIndex(cpIndex);
663
_methodsBySignature.Add(key, result);
664
TR_ASSERT(_methodsBySignature.Locate(key), "After _methodsBySignature.Add, _methodsBySignature.Locate must be true");
665
666
return result;
667
}
668
669
670
TR::SymbolReference *
671
J9::SymbolReferenceTable::findOrCreateTypeCheckArrayStoreSymbolRef(TR::ResolvedMethodSymbol *)
672
{
673
return findOrCreateRuntimeHelper(TR_typeCheckArrayStore, false, true, true);
674
}
675
676
677
TR::SymbolReference *
678
J9::SymbolReferenceTable::findOrCreateArrayClassRomPtrSymbolRef()
679
{
680
if (!element(arrayClassRomPtrSymbol))
681
{
682
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
683
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);
684
element(arrayClassRomPtrSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), arrayClassRomPtrSymbol, sym);
685
element(arrayClassRomPtrSymbol)->setOffset(fej9->getOffsetOfArrayClassRomPtrField());
686
if (!TR::Compiler->cls.romClassObjectsMayBeCollected())
687
sym->setNotCollected();
688
}
689
return element(arrayClassRomPtrSymbol);
690
}
691
692
693
TR::SymbolReference *
694
J9::SymbolReferenceTable::findOrCreateJavaLangReferenceReferentShadowSymbol(
695
TR::ResolvedMethodSymbol * owningMethodSymbol,
696
bool isResolved,
697
TR::DataType type,
698
uint32_t offset, bool isUnresolvedInCP)
699
{
700
TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();
701
702
TR::SymbolReference * symRef = NULL;
703
symRef = findJavaLangReferenceReferentShadowSymbol(owningMethod, TR::Address, offset);
704
if (!symRef)
705
{
706
symRef = createShadowSymbolWithoutCpIndex(owningMethodSymbol, true, TR::Address, offset, false);
707
}
708
return symRef;
709
}
710
711
712
// Right now it only works for private fields or fields that are guaranteed to be accessed only from one class
713
// because searchRecognizedField only does a name comparison, t does not work if the field is accessed from a subclass of the expected one
714
TR::SymbolReference *
715
J9::SymbolReferenceTable::findOrFabricateShadowSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, TR::Symbol::RecognizedField recognizedField, TR::DataType type, uint32_t offset, bool isVolatile, bool isPrivate, bool isFinal, char* name)
716
{
717
TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();
718
719
//The following code (up to and including the call to initShadowSymbol) has been adapted from
720
//J9::SymbolReferenceTable::findOrCreateShadowSymbol
721
TR::SymbolReference * symRef = NULL;
722
TR::Symbol * sym = NULL;
723
724
if (!comp()->compileRelocatableCode()
725
#if defined(J9VM_OPT_JITSERVER)
726
&& !comp()->isOutOfProcessCompilation()
727
#endif
728
)
729
{
730
symRef = findShadowSymbol(owningMethod, -1, type, &recognizedField);
731
732
if (symRef)
733
return symRef;
734
}
735
sym = createShadowSymbol(
736
type,
737
isVolatile,
738
isPrivate,
739
isFinal,
740
name,
741
recognizedField);
742
743
symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1);
744
// isResolved = true, isUnresolvedInCP = false
745
initShadowSymbol(owningMethod, symRef, true, type, offset, false);
746
return symRef;
747
}
748
749
TR::SymbolReference *
750
J9::SymbolReferenceTable::findResolvedFieldShadow(
751
ResolvedFieldShadowKey key,
752
bool isVolatile,
753
bool isPrivate,
754
bool isFinal)
755
{
756
const auto entry = _resolvedFieldShadows.find(key);
757
if (entry == _resolvedFieldShadows.end())
758
return NULL;
759
760
TR::SymbolReference *symRef = entry->second;
761
int32_t refNum = symRef->getReferenceNumber();
762
TR::Symbol *sym = symRef->getSymbol();
763
764
// The following asserts enforce restrictions on certain symbols properties.
765
//
766
// Taking volatility as an example, it is possible to find a symref in _resolvedFieldShadows
767
// whose symbols is marked isVolatile but that is for a non-volatile field. Consider a scenario
768
// where, during compilation, an unresolved field reference is encountered. We will create a
769
// symbol and conservatively mark is volatile. Later, a resolved reference for the same field is
770
// encountered (note that it need not have the same cpIndex as the first field ref). Being
771
// resolved, we determine that it is non-volatile. Because a symref for the field
772
// already exists but has a different resolution state, a new *symref* is created but the found
773
// *symbol* is reused. Since volatility is a property of the symbol, the new symref will share
774
// the volatility of the first symref (which was unresolved and must therefore be conservatively
775
// considered volatile). The new symref is then added to _resolvedFieldShadows. The next time
776
// the same field reference is encountered, the symref for it is found in _resolvedFieldShadows
777
// and once again its symbol is marked as volatile despite the field being non-volatile.
778
//
779
// The inverse condition, however, is not currently possible (i.e. finding a non-volatile symbol
780
// for a volatile field). Still, it's possible that could change in the future (for accesses
781
// with different memory ordering effects). If so, it should be made part of the key, and the
782
// two symRefs differing only in isVolatile should be considered to possibly alias.
783
//
784
// Similar restrictions apply to the isPrivate and isFinal symbol properties, although the truth
785
// conditions are reversed.
786
TR_ASSERT_FATAL(sym->isVolatile() || !isVolatile, "expecting volatile symref but found non-volatile symref #%d\n", refNum);
787
TR_ASSERT_FATAL(!sym->isPrivate() || isPrivate, "expecting non-private symref but found private symref #%d\n", refNum);
788
TR_ASSERT_FATAL(!sym->isFinal() || isFinal, "expecting non-final symref but found final symref #%d\n", refNum);
789
790
return symRef;
791
}
792
793
TR::SymbolReference *
794
J9::SymbolReferenceTable::findOrFabricateShadowSymbol(
795
TR_OpaqueClassBlock *containingClass,
796
TR::DataType type,
797
uint32_t offset,
798
bool isVolatile,
799
bool isPrivate,
800
bool isFinal,
801
const char *name,
802
const char *signature)
803
{
804
ResolvedFieldShadowKey key(containingClass, offset, type);
805
TR::SymbolReference *symRef = findResolvedFieldShadow(key, isVolatile, isPrivate, isFinal);
806
if (symRef != NULL)
807
return symRef;
808
809
int32_t classNameLen = 0;
810
const char *className =
811
TR::Compiler->cls.classNameChars(comp(), containingClass, classNameLen);
812
813
int qualifiedFieldNameSize = classNameLen + 1 + strlen(name) + 1 + strlen(signature) + 1;
814
char *qualifiedFieldName = (char*)trHeapMemory().allocate(qualifiedFieldNameSize);
815
TR::snprintfNoTrunc(
816
qualifiedFieldName,
817
qualifiedFieldNameSize,
818
"%.*s.%s %s",
819
classNameLen,
820
className,
821
name,
822
signature);
823
824
TR::Symbol *sym = createShadowSymbol(
825
type,
826
isVolatile,
827
isPrivate,
828
isFinal,
829
qualifiedFieldName,
830
TR::Symbol::UnknownField);
831
832
mcount_t methodIndex = mcount_t::valueOf(0);
833
int32_t cpIndex = -1;
834
symRef = new (trHeapMemory()) TR::SymbolReference(
835
self(),
836
sym,
837
methodIndex,
838
cpIndex);
839
840
bool isResolved = true;
841
bool isUnresolvedInCP = false;
842
initShadowSymbol(NULL, symRef, isResolved, type, offset, isUnresolvedInCP);
843
844
_resolvedFieldShadows.insert(std::make_pair(key, symRef));
845
return symRef;
846
}
847
848
TR::SymbolReference *
849
J9::SymbolReferenceTable::findFlattenedArrayElementFieldShadow(
850
ResolvedFieldShadowKey key,
851
bool isPrivate)
852
{
853
const auto entry = _flattenedArrayElementFieldShadows.find(key);
854
if (entry == _flattenedArrayElementFieldShadows.end())
855
return NULL;
856
857
TR::SymbolReference *symRef = entry->second;
858
int32_t refNum = symRef->getReferenceNumber();
859
TR::Symbol *sym = symRef->getSymbol();
860
861
TR_ASSERT_FATAL(sym->isPrivate() == isPrivate, "expecting %s symref but found %s: symref #%d\n",
862
isPrivate ? "private" : "non-private", sym->isPrivate() ? "private" : "non-private", refNum);
863
864
// When an array element is flattened, a write through this field shadow doesn't represent a write
865
// to the field. It is a partial write to an array element which is non volatile.
866
TR_ASSERT_FATAL(sym->isVolatile() == false, "expecting non-volatile symref but found volatile: symref #%d\n", refNum);
867
// The field is flattened into the array element which is mutable.
868
TR_ASSERT_FATAL(sym->isFinal() == false, "expecting non-final symref but found final: symref #%d\n", refNum);
869
870
return symRef;
871
}
872
873
TR::SymbolReference *
874
J9::SymbolReferenceTable::findOrFabricateFlattenedArrayElementFieldShadowSymbol(
875
TR_OpaqueClassBlock *arrayComponentClass,
876
TR::DataType type,
877
uint32_t fieldOffset,
878
bool isPrivate,
879
const char *fieldName,
880
const char *fieldSignature)
881
{
882
int32_t flattenedFieldOffset = (int32_t)fieldOffset - (int32_t)TR::Compiler->om.objectHeaderSizeInBytes();
883
884
TR_ASSERT_FATAL(flattenedFieldOffset >= 0, "flattenedFieldOffset %d is invalid: fieldOffset %u objectHeaderSizeInBytes %" OMR_PRIuPTR " \n", flattenedFieldOffset, fieldOffset, TR::Compiler->om.objectHeaderSizeInBytes());
885
886
ResolvedFieldShadowKey key(arrayComponentClass, flattenedFieldOffset, type);
887
888
TR::SymbolReference *symRef = findFlattenedArrayElementFieldShadow(key, isPrivate);
889
if (symRef != NULL)
890
return symRef;
891
892
int32_t classNameLen = 0;
893
const char *className = TR::Compiler->cls.classNameChars(comp(), arrayComponentClass, classNameLen);
894
895
// "<Q-className-array-shadow>.fieldName fieldSignature"
896
char qNameMem[128];
897
TR::StringBuf qNameBuf(trMemory()->currentStackRegion(), qNameMem, sizeof(qNameMem));
898
qNameBuf.appendf("<Q-%.*s-array-shadow>.%s %s", classNameLen, className, fieldName, fieldSignature);
899
900
size_t qualifiedFieldNameSize = qNameBuf.len() + 1; // +1 for NULL terminator
901
char *qualifiedFieldName = (char*)trHeapMemory().allocate(qualifiedFieldNameSize);
902
memcpy(qualifiedFieldName, qNameBuf.text(), qualifiedFieldNameSize);
903
904
// isVolatile is false because when an array element is flattened, a write through
905
// this field shadow doesn't represent a write to the field. It is a partial write
906
// to an array element which is non volatile.
907
// isFinal is false because the field is flattened into the array element which is mutable.
908
TR::Symbol *sym = createShadowSymbol(
909
type,
910
false /*isVolatile*/,
911
isPrivate,
912
false /*isFinal*/,
913
qualifiedFieldName,
914
TR::Symbol::UnknownField);
915
916
mcount_t methodIndex = mcount_t::valueOf(0);
917
int32_t cpIndex = -1;
918
symRef = new (trHeapMemory()) TR::SymbolReference(
919
self(),
920
sym,
921
methodIndex,
922
cpIndex);
923
924
bool isResolved = true;
925
bool isUnresolvedInCP = false;
926
initShadowSymbol(NULL, symRef, isResolved, type, flattenedFieldOffset, isUnresolvedInCP);
927
928
_flattenedArrayElementFieldShadows.insert(std::make_pair(key, symRef));
929
return symRef;
930
}
931
932
TR::Symbol *
933
J9::SymbolReferenceTable::createShadowSymbol(
934
TR::DataType type,
935
bool isVolatile,
936
bool isPrivate,
937
bool isFinal,
938
const char *name,
939
TR::Symbol::RecognizedField recognizedField)
940
{
941
TR::Symbol *sym = TR::Symbol::createPossiblyRecognizedShadowWithFlags(
942
trHeapMemory(), type, isVolatile, isFinal, isPrivate, recognizedField);
943
944
if (name != NULL)
945
{
946
sym->setNamedShadowSymbol();
947
sym->setName(name);
948
}
949
950
static char *dontAliasShadowsToEarlierGISEnv = feGetEnv("TR_dontAliasShadowsToEarlierGIS");
951
bool dontAliasShadowsToEarlierGIS = dontAliasShadowsToEarlierGISEnv != NULL;
952
953
if (aliasBuilder.mutableGenericIntShadowHasBeenCreated() && !dontAliasShadowsToEarlierGIS)
954
{
955
// Some previously-created GIS might actually refer to this shadow
956
aliasBuilder.setConservativeGenericIntShadowAliasing(true);
957
}
958
959
return sym;
960
}
961
962
TR::SymbolReference *
963
J9::SymbolReferenceTable::findOrCreateShadowSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, bool isStore)
964
{
965
TR_ResolvedJ9Method * owningMethod =
966
static_cast<TR_ResolvedJ9Method*>(owningMethodSymbol->getResolvedMethod());
967
968
bool isVolatile = true, isFinal = false, isPrivate = false, isUnresolvedInCP;
969
TR::DataType type = TR::NoType;
970
uint32_t offset = 0;
971
bool resolved = owningMethod->fieldAttributes(comp(), cpIndex, &offset, &type, &isVolatile, &isFinal, &isPrivate, isStore, &isUnresolvedInCP, true);
972
bool sharesSymbol = false;
973
974
TR_OpaqueClassBlock *containingClass = NULL;
975
TR::Symbol::RecognizedField recognizedField = TR::Symbol::searchRecognizedField(comp(), owningMethod, cpIndex, false);
976
977
if (isStore && isPrivate && !comp()->getOptions()->realTimeGC() &&
978
owningMethodSymbol->getResolvedMethod()->getRecognizedMethod() == TR::java_lang_ref_SoftReference_get &&
979
recognizedField == TR::Symbol::Java_lang_ref_SoftReference_age)
980
{
981
isVolatile = false;
982
}
983
984
if (resolved)
985
{
986
bool isStatic = false;
987
TR_OpaqueClassBlock* fromResolvedJ9Method = NULL;
988
containingClass =
989
owningMethod->definingClassFromCPFieldRef(comp(), cpIndex, isStatic, &fromResolvedJ9Method);
990
991
// Normally, the expectation is that if a cp field ref is resolved, then the cp ref pointing
992
// to the containing class must also be resolved. However, in #9416, it was discovered that
993
// this assumption does not hold in some cases. Under AOT, loading class data from the SCC
994
// using findSharedData() may fail, which is propagated to the JIT as a NULL containing class.
995
// In addition, if a class is redefined between the point where a field is looked up and
996
// where the defining class is looked, the latter may become NULL.
997
//
998
// Having a NULL containing class would imply two fields from different classes could have
999
// the same lookup key, which is a problem. So, until the above issues are resolved, the
1000
// safe thing to do is to abort compilation in these (rare) cases.
1001
if (containingClass == NULL)
1002
comp()->failCompilation<TR::CompilationException>(
1003
"failed to get defining class of resolved field ref cpIndex=%d in owning method J9Method=%p",
1004
cpIndex,
1005
owningMethod->getNonPersistentIdentifier());
1006
1007
ResolvedFieldShadowKey key(containingClass, offset, type);
1008
TR::SymbolReference *symRef =
1009
findResolvedFieldShadow(key, isVolatile, isPrivate, isFinal);
1010
1011
if (symRef != NULL)
1012
return symRef;
1013
}
1014
1015
TR::Symbol * sym = 0;
1016
1017
TR::SymbolReference * symRef = findShadowSymbol(owningMethod, cpIndex, type, &recognizedField);
1018
if (symRef)
1019
{
1020
if ((resolved && !symRef->isUnresolved()) ||
1021
(!resolved && symRef->isUnresolved() && owningMethod == symRef->getOwningMethod(comp())))
1022
return symRef;
1023
sym = symRef->getSymbol()->castToShadowSymbol();
1024
sharesSymbol = true;
1025
}
1026
else
1027
{
1028
sym = createShadowSymbol(
1029
type,
1030
isVolatile,
1031
isPrivate,
1032
isFinal,
1033
NULL,
1034
recognizedField);
1035
}
1036
1037
int32_t unresolvedIndex = resolved ? 0 : _numUnresolvedSymbols++;
1038
1039
if (sharesSymbol)
1040
symRef->setReallySharesSymbol();
1041
1042
symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), cpIndex, unresolvedIndex);
1043
checkUserField(symRef);
1044
1045
if (sharesSymbol)
1046
symRef->setReallySharesSymbol();
1047
1048
initShadowSymbol(owningMethod, symRef, resolved, type, offset, isUnresolvedInCP);
1049
1050
if (cpIndex > 0)
1051
aliasBuilder.cpSymRefs().set(symRef->getReferenceNumber());
1052
1053
if (containingClass != NULL)
1054
{
1055
ResolvedFieldShadowKey key(containingClass, offset, type);
1056
_resolvedFieldShadows.insert(std::make_pair(key, symRef));
1057
}
1058
1059
return symRef;
1060
}
1061
1062
TR::SymbolReference *
1063
J9::SymbolReferenceTable::findOrCreateObjectNewInstanceImplSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol)
1064
{
1065
if (!_ObjectNewInstanceImplSymRef)
1066
{
1067
TR_J9VMBase *fej9 = (TR_J9VMBase *)fe();
1068
TR_ResolvedMethod * resolvedMethod = fej9->getObjectNewInstanceImplMethod(trMemory());
1069
TR::ResolvedMethodSymbol * sym = TR::ResolvedMethodSymbol::create(trHeapMemory(),resolvedMethod,comp());
1070
sym->setMethodKind(TR::MethodSymbol::Virtual);
1071
1072
mcount_t owningMethodIndex = owningMethodSymbol->getResolvedMethodIndex();
1073
1074
_ObjectNewInstanceImplSymRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodIndex, -1, 0);
1075
_ObjectNewInstanceImplSymRef->setCanGCandReturn();
1076
_ObjectNewInstanceImplSymRef->setCanGCandExcept();
1077
_ObjectNewInstanceImplSymRef->setOffset(fej9->getNewInstanceImplVirtualCallOffset());
1078
1079
aliasBuilder.methodSymRefs().set(_ObjectNewInstanceImplSymRef->getReferenceNumber()); // cmvc defect 193493
1080
1081
// This is a dummy resolved method - would never be called. However, we set
1082
// the count to zero here to make sure that the optimizer does not think that
1083
// this method is cold and never being called
1084
//
1085
resolvedMethod->setInvocationCount(resolvedMethod->getInvocationCount(), 0);
1086
}
1087
return _ObjectNewInstanceImplSymRef;
1088
}
1089
1090
1091
TR::SymbolReference *
1092
J9::SymbolReferenceTable::findOrCreateDLTBlockSymbolRef()
1093
{
1094
if (!element(dltBlockSymbol))
1095
{
1096
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1097
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "DLTBlockMeta");
1098
sym->setDataType(TR::Address);
1099
sym->setNotCollected();
1100
element(dltBlockSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), dltBlockSymbol, sym);
1101
element(dltBlockSymbol)->setOffset(fej9->thisThreadGetDLTBlockOffset());
1102
1103
// We can't let the load/store of the exception symbol swing down
1104
//
1105
aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(dltBlockSymbol)); // add the symRef to the statics list to get correct aliasing info
1106
aliasBuilder.gcSafePointSymRefNumbers().set(getNonhelperIndex(dltBlockSymbol));
1107
}
1108
return element(dltBlockSymbol);
1109
}
1110
1111
1112
TR::SymbolReference *
1113
J9::SymbolReferenceTable::findDLTBlockSymbolRef()
1114
{
1115
return element(dltBlockSymbol);
1116
}
1117
1118
1119
TR::SymbolReference *
1120
J9::SymbolReferenceTable::findOrCreateMultiANewArraySymbolRef(TR::ResolvedMethodSymbol *)
1121
{
1122
return findOrCreateRuntimeHelper(TR_multiANewArray, true, true, true);
1123
}
1124
1125
1126
TR::SymbolReference *
1127
J9::SymbolReferenceTable::findOrCreateInstanceShapeSymbolRef()
1128
{
1129
if (!element(instanceShapeSymbol))
1130
{
1131
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1132
TR::Symbol * sym;
1133
if (self()->comp()->target().is64Bit())
1134
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);
1135
else
1136
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);
1137
element(instanceShapeSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), instanceShapeSymbol, sym);
1138
element(instanceShapeSymbol)->setOffset(fej9->getOffsetOfInstanceShapeFromClassField());
1139
}
1140
return element(instanceShapeSymbol);
1141
}
1142
1143
1144
TR::SymbolReference *
1145
J9::SymbolReferenceTable::findOrCreateInstanceDescriptionSymbolRef()
1146
{
1147
if (!element(instanceDescriptionSymbol))
1148
{
1149
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1150
TR::Symbol * sym;
1151
if (self()->comp()->target().is64Bit())
1152
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);
1153
else
1154
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);
1155
element(instanceDescriptionSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), instanceDescriptionSymbol, sym);
1156
element(instanceDescriptionSymbol)->setOffset(fej9->getOffsetOfInstanceDescriptionFromClassField());
1157
}
1158
return element(instanceDescriptionSymbol);
1159
}
1160
1161
1162
1163
TR::SymbolReference *
1164
J9::SymbolReferenceTable::findOrCreateDescriptionWordFromPtrSymbolRef()
1165
{
1166
if (!element(descriptionWordFromPtrSymbol))
1167
{
1168
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1169
TR::Symbol * sym;
1170
if (self()->comp()->target().is64Bit())
1171
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);
1172
else
1173
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);
1174
element(descriptionWordFromPtrSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), descriptionWordFromPtrSymbol, sym);
1175
element(descriptionWordFromPtrSymbol)->setOffset(fej9->getOffsetOfDescriptionWordFromPtrField());
1176
}
1177
return element(descriptionWordFromPtrSymbol);
1178
}
1179
1180
1181
TR::SymbolReference *
1182
J9::SymbolReferenceTable::findOrCreateClassFlagsSymbolRef()
1183
{
1184
if (!element(isClassFlagsSymbol))
1185
{
1186
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1187
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);
1188
element(isClassFlagsSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), isClassFlagsSymbol, sym);
1189
element(isClassFlagsSymbol)->setOffset(fej9->getOffsetOfClassFlags());
1190
}
1191
return element(isClassFlagsSymbol);
1192
}
1193
1194
1195
TR::SymbolReference *
1196
J9::SymbolReferenceTable::findOrCreateClassAndDepthFlagsSymbolRef()
1197
{
1198
if (!element(isClassAndDepthFlagsSymbol))
1199
{
1200
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1201
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);
1202
element(isClassAndDepthFlagsSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), isClassAndDepthFlagsSymbol, sym);
1203
element(isClassAndDepthFlagsSymbol)->setOffset(fej9->getOffsetOfClassAndDepthFlags());
1204
}
1205
return element(isClassAndDepthFlagsSymbol);
1206
}
1207
1208
1209
TR::SymbolReference *
1210
J9::SymbolReferenceTable::findOrCreateArrayComponentTypeAsPrimitiveSymbolRef()
1211
{
1212
if (!element(componentClassAsPrimitiveSymbol))
1213
{
1214
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1215
TR::Symbol * sym;
1216
if (self()->comp()->target().is64Bit())
1217
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);
1218
else
1219
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);
1220
1221
element(componentClassAsPrimitiveSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), componentClassAsPrimitiveSymbol, sym);
1222
element(componentClassAsPrimitiveSymbol)->setOffset(fej9->getOffsetOfArrayComponentTypeField());
1223
if (!TR::Compiler->cls.classObjectsMayBeCollected())
1224
sym->setNotCollected();
1225
}
1226
return element(componentClassAsPrimitiveSymbol);
1227
}
1228
1229
1230
TR::SymbolReference *
1231
J9::SymbolReferenceTable::findOrCreateMethodTypeCheckSymbolRef(TR::ResolvedMethodSymbol *)
1232
{
1233
return findOrCreateRuntimeHelper(TR_methodTypeCheck, false, true, true);
1234
}
1235
1236
TR::SymbolReference *
1237
J9::SymbolReferenceTable::findOrCreateIncompatibleReceiverSymbolRef(TR::ResolvedMethodSymbol *)
1238
{
1239
return findOrCreateRuntimeHelper(TR_incompatibleReceiver, false, true, true);
1240
}
1241
1242
TR::SymbolReference *
1243
J9::SymbolReferenceTable::findOrCreateIncompatibleClassChangeErrorSymbolRef(TR::ResolvedMethodSymbol *)
1244
{
1245
return findOrCreateRuntimeHelper(TR_IncompatibleClassChangeError, false, true, true);
1246
}
1247
1248
TR::SymbolReference *
1249
J9::SymbolReferenceTable::findOrCreateReportStaticMethodEnterSymbolRef(TR::ResolvedMethodSymbol *)
1250
{
1251
return findOrCreateRuntimeHelper(TR_reportStaticMethodEnter, true, false, true);
1252
}
1253
1254
1255
TR::SymbolReference *
1256
J9::SymbolReferenceTable::findOrCreateReportMethodExitSymbolRef(TR::ResolvedMethodSymbol *)
1257
{
1258
return findOrCreateRuntimeHelper(TR_reportMethodExit, true, false, true);
1259
}
1260
1261
TR::SymbolReference *
1262
J9::SymbolReferenceTable::findOrCreateHeaderFlagsSymbolRef()
1263
{
1264
if (!element(headerFlagsSymbol))
1265
{
1266
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1267
TR::SymbolReference * symRef;
1268
// object header flags now occupy 4bytes on 64-bit
1269
symRef = new (trHeapMemory()) TR::SymbolReference(self(), headerFlagsSymbol, TR::Symbol::createShadow(trHeapMemory(),TR::Int32));
1270
symRef->setOffset(TR::Compiler->om.offsetOfHeaderFlags());
1271
element(headerFlagsSymbol) = symRef;
1272
aliasBuilder.intShadowSymRefs().set(symRef->getReferenceNumber());
1273
}
1274
1275
return element(headerFlagsSymbol);
1276
}
1277
1278
1279
TR::SymbolReference *
1280
J9::SymbolReferenceTable::findOrCreateDiscontiguousArraySizeSymbolRef()
1281
{
1282
if (!element(discontiguousArraySizeSymbol))
1283
{
1284
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1285
TR::Symbol * sym;
1286
1287
// Size field is 32-bits on ALL header shapes.
1288
//
1289
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);
1290
element(discontiguousArraySizeSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), discontiguousArraySizeSymbol, sym);
1291
element(discontiguousArraySizeSymbol)->setOffset(fej9->getOffsetOfDiscontiguousArraySizeField());
1292
}
1293
return element(discontiguousArraySizeSymbol);
1294
}
1295
1296
1297
TR::SymbolReference *
1298
J9::SymbolReferenceTable::findOrCreateClassLoaderSymbolRef(TR_ResolvedMethod * method)
1299
{
1300
ListIterator<TR::SymbolReference> i(&_classLoaderSymbolRefs);
1301
TR::SymbolReference * symRef;
1302
for (symRef = i.getFirst(); symRef; symRef = i.getNext())
1303
if (symRef->getOwningMethod(comp()) == method)
1304
return symRef;
1305
1306
TR::StaticSymbol * sym = TR::StaticSymbol::create(trHeapMemory(),TR::Address);
1307
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1308
sym->setStaticAddress(fej9->getLocationOfClassLoaderObjectPointer(method->classOfMethod()));
1309
mcount_t index = comp()->getOwningMethodSymbol(method)->getResolvedMethodIndex();
1310
symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, index, -1);
1311
1312
aliasBuilder.addressStaticSymRefs().set(symRef->getReferenceNumber()); // add the symRef to the statics list to get correct aliasing info
1313
1314
_classLoaderSymbolRefs.add(symRef);
1315
1316
return symRef;
1317
}
1318
1319
1320
TR::SymbolReference *
1321
J9::SymbolReferenceTable::findOrCreateCurrentThreadSymbolRef()
1322
{
1323
if (!element(currentThreadSymbol))
1324
{
1325
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1326
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "CurrentThread");
1327
sym->setDataType(TR::Address);
1328
sym->setImmutableField();
1329
element(currentThreadSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), currentThreadSymbol, sym);
1330
element(currentThreadSymbol)->setOffset(fej9->thisThreadGetCurrentThreadOffset());
1331
}
1332
return element(currentThreadSymbol);
1333
}
1334
1335
TR::SymbolReference *
1336
J9::SymbolReferenceTable::findOrCreateJ9MethodConstantPoolFieldSymbolRef(intptr_t offset)
1337
{
1338
if (!element(j9methodConstantPoolSymbol))
1339
{
1340
TR::Symbol * sym;
1341
if (self()->comp()->target().is64Bit())
1342
sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int64);
1343
else
1344
sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int32);
1345
1346
element(j9methodConstantPoolSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), j9methodConstantPoolSymbol, sym);
1347
element(j9methodConstantPoolSymbol)->setOffset(offset);
1348
}
1349
TR::SymbolReference *result = element(j9methodConstantPoolSymbol);
1350
TR_ASSERT(result->getOffset() == offset, "findOrCreateJ9MethodConstantPoolFieldSymbolRef must use the right offset! %d != %d", result->getOffset(), offset);
1351
return result;
1352
}
1353
1354
TR::SymbolReference *
1355
J9::SymbolReferenceTable::findOrCreateJ9MethodExtraFieldSymbolRef(intptr_t offset)
1356
{
1357
if (!element(j9methodExtraFieldSymbol))
1358
{
1359
TR::Symbol * sym;
1360
if (self()->comp()->target().is64Bit())
1361
sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int64);
1362
else
1363
sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int32);
1364
1365
element(j9methodExtraFieldSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), j9methodExtraFieldSymbol, sym);
1366
element(j9methodExtraFieldSymbol)->setOffset(offset);
1367
}
1368
TR::SymbolReference *result = element(j9methodExtraFieldSymbol);
1369
TR_ASSERT(result->getOffset() == offset, "findOrCreateJ9MethodExtraFieldSymbolRef must use the right offset! %d != %d", result->getOffset(), offset);
1370
return result;
1371
}
1372
1373
TR::SymbolReference *
1374
J9::SymbolReferenceTable::findOrCreateJ9JNIMethodIDvTableIndexFieldSymbol(intptr_t offset)
1375
{
1376
if (!element(J9JNIMethodIDvTableIndexFieldSymbol))
1377
{
1378
TR::Symbol * sym;
1379
if (self()->comp()->target().is64Bit())
1380
sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int64);
1381
else
1382
sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int32);
1383
1384
element(J9JNIMethodIDvTableIndexFieldSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), J9JNIMethodIDvTableIndexFieldSymbol, sym);
1385
element(J9JNIMethodIDvTableIndexFieldSymbol)->setOffset(offset);
1386
}
1387
return element(J9JNIMethodIDvTableIndexFieldSymbol);
1388
}
1389
1390
TR::SymbolReference *
1391
J9::SymbolReferenceTable::findOrCreateStartPCLinkageInfoSymbolRef(intptr_t offset)
1392
{
1393
if (!element(startPCLinkageInfoSymbol))
1394
{
1395
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int32);
1396
element(startPCLinkageInfoSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), startPCLinkageInfoSymbol, sym);
1397
element(startPCLinkageInfoSymbol)->setOffset(offset);
1398
}
1399
TR::SymbolReference *result = element(startPCLinkageInfoSymbol);
1400
TR_ASSERT(result->getOffset() == offset, "findOrCreateStartPCLinkageInfoSymbolRef must use the right offset! %d != %d", result->getOffset(), offset);
1401
return result;
1402
}
1403
1404
1405
TR::SymbolReference *
1406
J9::SymbolReferenceTable::findOrCreatePerCodeCacheHelperSymbolRef(TR_CCPreLoadedCode helper, uintptr_t helperAddr)
1407
{
1408
CommonNonhelperSymbol index = (CommonNonhelperSymbol)(firstPerCodeCacheHelperSymbol + helper);
1409
if (!element(index))
1410
{
1411
TR::MethodSymbol * methodSymbol = TR::MethodSymbol::create(trHeapMemory(),TR_Private);
1412
methodSymbol->setHelper();
1413
// The address of the helper depends on the current codecache, which can change during compilation, so we don't have a single method address
1414
methodSymbol->setMethodAddress(NULL);
1415
element(index) = new (trHeapMemory()) TR::SymbolReference(self(), index, methodSymbol);
1416
}
1417
return element(index);
1418
}
1419
1420
1421
TR::SymbolReference *
1422
J9::SymbolReferenceTable::findOrCreateANewArraySymbolRef(TR::ResolvedMethodSymbol *)
1423
{
1424
return findOrCreateRuntimeHelper(TR_aNewArray, true, true, true);
1425
}
1426
1427
1428
TR::SymbolReference *
1429
J9::SymbolReferenceTable::findOrCreateStringSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
1430
{
1431
TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();
1432
void * stringConst = owningMethod->stringConstant(cpIndex);
1433
TR::SymbolReference * symRef;
1434
bool isString = true;
1435
if (owningMethod->isUnresolvedString(cpIndex))
1436
{
1437
symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, false, 0);
1438
symRef->setOffset((uintptr_t)stringConst);
1439
}
1440
else
1441
{
1442
TR::KnownObjectTable::Index knownObjectIndex = TR::KnownObjectTable::UNKNOWN;
1443
if (!comp()->compileRelocatableCode())
1444
{
1445
TR::KnownObjectTable *knot = comp()->getOrCreateKnownObjectTable();
1446
if (knot)
1447
{
1448
knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)stringConst);
1449
}
1450
}
1451
symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, true, stringConst, knownObjectIndex);
1452
}
1453
1454
TR::StaticSymbol * sym = (TR::StaticSymbol *)symRef->getSymbol();
1455
1456
// If the cp entry is patched, it's resolved during the patching
1457
// Unresolved cp entry will always contain a const string
1458
if (symRef->isUnresolved())
1459
{
1460
sym->setConstString();
1461
}
1462
// If symbol is created the first time, check if the const object is String
1463
else if (!sym->isConstString() &&
1464
!sym->isNonSpecificConstObject())
1465
{
1466
TR::VMAccessCriticalSection constantCriticalSection(comp()->fej9());
1467
TR_OpaqueClassBlock *clazz = comp()->fej9()->getObjectClassAt((uintptr_t)stringConst);
1468
if (comp()->fej9()->isString(clazz))
1469
{
1470
sym->setConstString();
1471
}
1472
else
1473
{
1474
if (comp()->compileRelocatableCode())
1475
comp()->failCompilation<J9::AOTHasPatchedCPConstant>("Patched Constant not supported in AOT.");
1476
1477
sym->setNonSpecificConstObject();
1478
}
1479
}
1480
1481
return symRef;
1482
}
1483
1484
TR::SymbolReference *
1485
J9::SymbolReferenceTable::findOrCreateConstantDynamicSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, char* symbolTypeSig, int32_t symbolTypeSigLength, bool isCondyPrimitive)
1486
{
1487
TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();
1488
void * dynamicConst = owningMethod->dynamicConstant(cpIndex, NULL);
1489
TR::SymbolReference * symRef;
1490
if (owningMethod->isUnresolvedConstantDynamic(cpIndex))
1491
{
1492
symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, false, 0);
1493
symRef->setOffset((uintptr_t)dynamicConst);
1494
}
1495
else
1496
{
1497
symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, true, dynamicConst);
1498
}
1499
TR::StaticSymbol * sym = (TR::StaticSymbol *)symRef->getSymbol();
1500
sym->setConstantDynamic();
1501
sym->makeConstantDynamic(symbolTypeSig, symbolTypeSigLength, isCondyPrimitive);
1502
return symRef;
1503
}
1504
1505
TR::SymbolReference *
1506
J9::SymbolReferenceTable::findOrCreateMethodMonitorEntrySymbolRef(TR::ResolvedMethodSymbol *)
1507
{
1508
return findOrCreateRuntimeHelper(TR_methodMonitorEntry, true, false, true);
1509
}
1510
1511
1512
TR::SymbolReference *
1513
J9::SymbolReferenceTable::findOrCreateMethodMonitorExitSymbolRef(TR::ResolvedMethodSymbol *)
1514
{
1515
return findOrCreateRuntimeHelper(TR_methodMonitorExit, true /* canGCandReturn */, true /* canGCandExcept */, true /* preservesAllRegisters */);
1516
}
1517
1518
1519
TR::SymbolReference *
1520
J9::SymbolReferenceTable::findOrCreateCompiledMethodSymbolRef()
1521
{
1522
if (!element(compiledMethodSymbol))
1523
{
1524
TR::StaticSymbol * sym = TR::StaticSymbol::create(trHeapMemory(),TR::Address);
1525
sym->setStaticAddress(comp()->getCurrentMethod()->getPersistentIdentifier());
1526
sym->setCompiledMethod();
1527
sym->setNotDataAddress();
1528
element(compiledMethodSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), compiledMethodSymbol, sym);
1529
}
1530
return element(compiledMethodSymbol);
1531
}
1532
1533
1534
TR::SymbolReference *
1535
J9::SymbolReferenceTable::findOrCreateMethodTypeSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
1536
{
1537
TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();
1538
void * methodTypeConst = owningMethod->methodTypeConstant(cpIndex);
1539
TR::SymbolReference * symRef;
1540
if (owningMethod->isUnresolvedMethodType(cpIndex))
1541
{
1542
symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, false, 0);
1543
symRef->setOffset((uintptr_t)methodTypeConst);
1544
}
1545
else
1546
{
1547
symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, true, methodTypeConst);
1548
}
1549
TR::StaticSymbol * sym = (TR::StaticSymbol *)symRef->getSymbol();
1550
sym->setConstMethodType();
1551
return symRef;
1552
}
1553
1554
TR::SymbolReference *
1555
J9::SymbolReferenceTable::findOrCreateMethodHandleSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
1556
{
1557
TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();
1558
void * methodHandleConst = owningMethod->methodHandleConstant(cpIndex);
1559
TR::SymbolReference * symRef;
1560
if (owningMethod->isUnresolvedMethodHandle(cpIndex))
1561
{
1562
symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, false, 0);
1563
symRef->setOffset((uintptr_t)methodHandleConst);
1564
}
1565
else
1566
{
1567
TR::KnownObjectTable::Index knownObjectIndex = TR::KnownObjectTable::UNKNOWN;
1568
TR::KnownObjectTable *knot = comp()->getOrCreateKnownObjectTable();
1569
if (knot)
1570
knownObjectIndex = knot->getOrCreateIndexAt((uintptr_t*)methodHandleConst);
1571
symRef = findOrCreateCPSymbol(owningMethodSymbol, cpIndex, TR::Address, true, methodHandleConst, knownObjectIndex);
1572
}
1573
TR::StaticSymbol * sym = (TR::StaticSymbol *)symRef->getSymbol();
1574
sym->setConstMethodHandle();
1575
return symRef;
1576
}
1577
1578
1579
TR::SymbolReference *
1580
J9::SymbolReferenceTable::findOrCreateClassStaticsSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex)
1581
{
1582
TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();
1583
1584
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1585
void * classStatics = fej9->addressOfFirstClassStatic(owningMethod->classOfStatic(cpIndex, true));
1586
1587
ListIterator<TR::SymbolReference> i(&_classStaticsSymbolRefs);
1588
TR::SymbolReference * symRef;
1589
for (symRef = i.getFirst(); symRef; symRef = i.getNext())
1590
if (symRef->getSymbol()->getStaticSymbol()->getStaticAddress() == classStatics)
1591
return symRef;
1592
1593
TR::StaticSymbol * sym = TR::StaticSymbol::create(trHeapMemory(),TR::Address);
1594
sym->setStaticAddress(classStatics);
1595
if (!TR::Compiler->cls.classObjectsMayBeCollected())
1596
sym->setNotCollected();
1597
// cpIndex for resolved Class statics symbol is unused. Furthermore having a cpIndex here might create illusion for cases where we
1598
// care about cpIndex and also as Two or more (resolved) static field references belonging to same class will
1599
// share the same information (inlined call site index, cpIndex) , using a cpIndex for these cases will
1600
// need further changes to prevent any sharing hence it is set to -1 for static resolved fields.
1601
// For more detailed information take a look at PR#4322 in eclipse-openj9/openj9 repo
1602
symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1);
1603
1604
aliasBuilder.addressStaticSymRefs().set(symRef->getReferenceNumber()); // add the symRef to the statics list to get correct aliasing info
1605
1606
_classStaticsSymbolRefs.add(symRef);
1607
1608
return symRef;
1609
}
1610
1611
1612
TR::SymbolReference *
1613
J9::SymbolReferenceTable::findOrCreateClassFromJavaLangClassAsPrimitiveSymbolRef()
1614
{
1615
if (!element(classFromJavaLangClassAsPrimitiveSymbol))
1616
{
1617
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1618
TR::Symbol * sym;
1619
if (self()->comp()->target().is64Bit())
1620
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);
1621
else
1622
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);
1623
1624
element(classFromJavaLangClassAsPrimitiveSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), classFromJavaLangClassAsPrimitiveSymbol, sym);
1625
element(classFromJavaLangClassAsPrimitiveSymbol)->setOffset(fej9->getOffsetOfClassFromJavaLangClassField());
1626
}
1627
return element(classFromJavaLangClassAsPrimitiveSymbol);
1628
}
1629
1630
1631
TR::SymbolReference *
1632
J9::SymbolReferenceTable::findClassFromJavaLangClassAsPrimitiveSymbolRef()
1633
{
1634
return element(classFromJavaLangClassAsPrimitiveSymbol);
1635
}
1636
1637
1638
TR::SymbolReference *
1639
J9::SymbolReferenceTable::createShadowSymbolWithoutCpIndex(TR::ResolvedMethodSymbol * owningMethodSymbol, bool isResolved,
1640
TR::DataType type, uint32_t offset, bool isUnresolvedInCP)
1641
{
1642
TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();
1643
1644
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(),type);
1645
TR::SymbolReference * symRef;
1646
1647
int32_t unresolvedIndex = isResolved ? 0 : _numUnresolvedSymbols++;
1648
symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), -1);
1649
initShadowSymbol(owningMethod, symRef, isResolved, type, offset, isUnresolvedInCP);
1650
return symRef;
1651
}
1652
1653
1654
TR::SymbolReference *
1655
J9::SymbolReferenceTable::findJavaLangReferenceReferentShadowSymbol(TR_ResolvedMethod * owningMethod, TR::DataType type, uint32_t offset)
1656
{
1657
TR::SymbolReference * symRef;
1658
TR_SymRefIterator i(type == TR::Address ? aliasBuilder.addressShadowSymRefs() :
1659
(type == TR::Int32 ? aliasBuilder.intShadowSymRefs() : aliasBuilder.nonIntPrimitiveShadowSymRefs()), self());
1660
while ((symRef = i.getNext()) != NULL)
1661
if (symRef->getSymbol()->getDataType() == type &&
1662
symRef->getOffset() == offset &&
1663
symRef->getOwningMethod(comp()) == owningMethod)
1664
return symRef;
1665
return 0;
1666
}
1667
1668
1669
void
1670
J9::SymbolReferenceTable::initShadowSymbol(TR_ResolvedMethod * owningMethod, TR::SymbolReference *symRef, bool isResolved,
1671
TR::DataType type, uint32_t offset, bool isUnresolvedInCP)
1672
{
1673
if (isResolved)
1674
{
1675
symRef->setOffset(offset);
1676
}
1677
else
1678
{
1679
symRef->setUnresolved();
1680
symRef->setCanGCandExcept();
1681
aliasBuilder.unresolvedShadowSymRefs().set(symRef->getReferenceNumber());
1682
}
1683
1684
symRef->setHasBeenAccessedAtRuntime(isUnresolvedInCP? TR_no : TR_maybe);
1685
1686
if (type == TR::Address)
1687
aliasBuilder.addressShadowSymRefs().set(symRef->getReferenceNumber());
1688
else if (type == TR::Int32)
1689
aliasBuilder.intShadowSymRefs().set(symRef->getReferenceNumber());
1690
else
1691
aliasBuilder.nonIntPrimitiveShadowSymRefs().set(symRef->getReferenceNumber());
1692
1693
if (shouldMarkBlockAsCold(owningMethod, isUnresolvedInCP))
1694
markBlockAsCold();
1695
1696
return;
1697
}
1698
1699
1700
List<TR::SymbolReference> *
1701
J9::SymbolReferenceTable::dynamicMethodSymrefsByCallSiteIndex(int32_t index)
1702
{
1703
if (!_dynamicMethodSymrefsByCallSiteIndex[index])
1704
_dynamicMethodSymrefsByCallSiteIndex[index] = new (trHeapMemory()) List<TR::SymbolReference>(comp()->trMemory());
1705
return _dynamicMethodSymrefsByCallSiteIndex[index];
1706
}
1707
1708
bool
1709
J9::SymbolReferenceTable::isFieldClassObject(TR::SymbolReference *symRef)
1710
{
1711
int32_t len;
1712
const char *fieldName = symRef->getOwningMethod(comp())->fieldSignatureChars(symRef->getCPIndex(), len);
1713
dumpOptDetails(comp(), "got fieldsig as %s\n", fieldName);
1714
return false;
1715
}
1716
1717
static bool isSignatureTypeBool(const char *fieldSignature, int32_t len)
1718
{
1719
return len == 1 && fieldSignature[0] == 'Z';
1720
}
1721
1722
static bool isSignatureReturnTypeBool(const char *methodSignature, int32_t len)
1723
{
1724
TR_ASSERT(len > 1, "Method signature is unexpectedly short %d", len);
1725
// Method signature must end with ")Z" to have a boolean result type
1726
return len > 1 && (')' == methodSignature[len-2]) && ('Z' == methodSignature[len-1]);
1727
}
1728
1729
bool
1730
J9::SymbolReferenceTable::isFieldTypeBool(TR::SymbolReference *symRef)
1731
{
1732
int32_t len;
1733
const char *fieldSignature = symRef->getOwningMethod(comp())->fieldSignatureChars(symRef->getCPIndex(), len);
1734
dumpOptDetails(comp(), "got field signature as %s\n", fieldSignature);
1735
return isSignatureTypeBool(fieldSignature, len);
1736
}
1737
1738
bool
1739
J9::SymbolReferenceTable::isStaticTypeBool(TR::SymbolReference *symRef)
1740
{
1741
int32_t len;
1742
const char *fieldSignature = symRef->getOwningMethod(comp())->staticSignatureChars(symRef->getCPIndex(), len);
1743
dumpOptDetails(comp(), "got static signature as %s\n", fieldSignature);
1744
return isSignatureTypeBool(fieldSignature, len);
1745
}
1746
1747
bool
1748
J9::SymbolReferenceTable::isReturnTypeBool(TR::SymbolReference *symRef)
1749
{
1750
TR::Method *method = symRef->getSymbol()->castToResolvedMethodSymbol()->getMethod();
1751
char *methodSignature = method->signatureChars();
1752
const int32_t len = method->signatureLength();
1753
dumpOptDetails(comp(), "got method signature as %.*s\n", len, methodSignature);
1754
return isSignatureReturnTypeBool(methodSignature, len);
1755
}
1756
1757
static bool parmSlotCameFromExpandingAnArchetypeArgPlaceholder(int32_t slot, TR::ResolvedMethodSymbol *sym)
1758
{
1759
TR_ResolvedJ9Method *meth = (TR_ResolvedJ9Method *) sym->getResolvedMethod();
1760
if (meth->convertToMethod()->isArchetypeSpecimen())
1761
return slot >= meth->archetypeArgPlaceholderSlot();
1762
else
1763
return false;
1764
}
1765
1766
1767
void
1768
J9::SymbolReferenceTable::addParameters(TR::ResolvedMethodSymbol * methodSymbol)
1769
{
1770
mcount_t index = methodSymbol->getResolvedMethodIndex();
1771
methodSymbol->setParameterList();
1772
ListIterator<TR::ParameterSymbol> parms(&methodSymbol->getParameterList());
1773
for (TR::ParameterSymbol * p = parms.getFirst(); p; p = parms.getNext())
1774
{
1775
TR::KnownObjectTable::Index knownObjectIndex = methodSymbol->getKnownObjectIndexForParm(p->getOrdinal());
1776
TR::SymbolReference *symRef = NULL;
1777
if (knownObjectIndex == TR::KnownObjectTable::UNKNOWN)
1778
symRef = new (trHeapMemory()) TR::SymbolReference(self(), p, index, p->getSlot());
1779
else
1780
symRef = createTempSymRefWithKnownObject(p, index, p->getSlot(), knownObjectIndex);
1781
methodSymbol->setParmSymRef(p->getSlot(), symRef);
1782
if (!parmSlotCameFromExpandingAnArchetypeArgPlaceholder(p->getSlot(), methodSymbol))
1783
methodSymbol->getAutoSymRefs(p->getSlot()).add(symRef);
1784
}
1785
}
1786
1787
1788
TR::SymbolReference *
1789
J9::SymbolReferenceTable::findOrCreateStaticSymbol(TR::ResolvedMethodSymbol * owningMethodSymbol, int32_t cpIndex, bool isStore)
1790
{
1791
TR_ResolvedMethod * owningMethod = owningMethodSymbol->getResolvedMethod();
1792
void * dataAddress;
1793
TR::DataType type = TR::NoType;
1794
bool isVolatile, isFinal, isPrivate, isUnresolvedInCP;
1795
bool resolved = owningMethod->staticAttributes(comp(), cpIndex, &dataAddress, &type, &isVolatile, &isFinal, &isPrivate, isStore, &isUnresolvedInCP);
1796
1797
bool sharesSymbol = false;
1798
1799
TR::StaticSymbol * sym = 0;
1800
TR::SymbolReference * symRef = findStaticSymbol(owningMethod, cpIndex, type);
1801
if (symRef)
1802
{
1803
if ((resolved && !symRef->isUnresolved()) ||
1804
(!resolved && symRef->isUnresolved() && owningMethod == symRef->getOwningMethod(comp())))
1805
{
1806
symRef->setHasBeenAccessedAtRuntime(isUnresolvedInCP ? TR_no: TR_maybe);
1807
if (shouldMarkBlockAsCold(owningMethod, isUnresolvedInCP))
1808
markBlockAsCold();
1809
1810
return symRef;
1811
}
1812
1813
sym = symRef->getSymbol()->castToStaticSymbol();
1814
sharesSymbol = true;
1815
}
1816
else
1817
{
1818
TR::Symbol::RecognizedField recognizedField = TR::Symbol::searchRecognizedField(comp(), owningMethod, cpIndex, true);
1819
if (recognizedField != TR::Symbol::UnknownField)
1820
sym = TR::StaticSymbol::createRecognized(trHeapMemory(), type, recognizedField);
1821
else
1822
sym = TR::StaticSymbol::create(trHeapMemory(), type);
1823
1824
if (isVolatile)
1825
sym->setVolatile();
1826
if (isFinal)
1827
sym->setFinal();
1828
if (isPrivate)
1829
sym->setPrivate();
1830
}
1831
1832
int32_t unresolvedIndex = resolved ? 0 : _numUnresolvedSymbols++;
1833
1834
if (sharesSymbol)
1835
symRef->setReallySharesSymbol();
1836
1837
TR::KnownObjectTable::Index knownObjectIndex = TR::KnownObjectTable::UNKNOWN;
1838
if (resolved && isFinal && type == TR::Address)
1839
{
1840
knownObjectIndex = TR::TransformUtil::knownObjectFromFinalStatic(
1841
comp(), owningMethod, cpIndex, dataAddress);
1842
}
1843
1844
symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), cpIndex, unresolvedIndex, knownObjectIndex);
1845
1846
checkUserField(symRef);
1847
1848
if (sharesSymbol)
1849
symRef->setReallySharesSymbol();
1850
1851
if (resolved)
1852
{
1853
sym->setStaticAddress(dataAddress);
1854
}
1855
else
1856
{
1857
symRef->setUnresolved();
1858
symRef->setCanGCandReturn();
1859
symRef->setCanGCandExcept();
1860
}
1861
1862
symRef->setHasBeenAccessedAtRuntime(isUnresolvedInCP? TR_no : TR_maybe);
1863
1864
if (type == TR::Address)
1865
aliasBuilder.addressStaticSymRefs().set(symRef->getReferenceNumber());
1866
else if (type == TR::Int32)
1867
aliasBuilder.intStaticSymRefs().set(symRef->getReferenceNumber());
1868
else
1869
aliasBuilder.nonIntPrimitiveStaticSymRefs().set(symRef->getReferenceNumber());
1870
1871
if (shouldMarkBlockAsCold(owningMethod, isUnresolvedInCP))
1872
markBlockAsCold();
1873
1874
return symRef;
1875
}
1876
1877
1878
static struct N { const char * name; } pnames[] =
1879
{
1880
"java/",
1881
"javax/",
1882
"com/ibm/",
1883
"com/sun/"
1884
};
1885
1886
1887
void
1888
J9::SymbolReferenceTable::checkUserField(TR::SymbolReference *symRef)
1889
{
1890
static const char *userField = feGetEnv("TR_UserField");
1891
if (!userField)
1892
{
1893
// In the absence of further analysis, treat everything as user fields
1894
setHasUserField(true);
1895
return;
1896
}
1897
1898
if ((!symRef->getSymbol()->isShadow() && (!symRef->getSymbol()->isStatic() || symRef->getSymbol()->isMethod() || symRef->getSymbol()->isConstObjectRef())) || symRef->getCPIndex() <= 0)
1899
return;
1900
1901
int32_t length;
1902
char * name = symRef->getOwningMethod(comp())->classNameOfFieldOrStatic(symRef->getCPIndex(), length);
1903
1904
if (name == NULL || length == 0)
1905
return;
1906
1907
TR_ASSERT(sizeof(pnames)/sizeof(char *) == _numNonUserFieldClasses,"Size of package names array is not correct\n");
1908
int32_t i;
1909
bool isNonUserField = false;
1910
for (i = 0; i < _numNonUserFieldClasses; i++)
1911
{
1912
if (!strncmp(pnames[i].name, name, strlen(pnames[i].name)))
1913
{
1914
isNonUserField = true;
1915
//printf ("User field symref %d name=%s length=%d cpindex=%d\n", symRef->getReferenceNumber(), name, length, symRef->getCPIndex());
1916
break;
1917
}
1918
}
1919
1920
if (isNonUserField)
1921
{
1922
// At the moment this is conservative. i.e. any field in any of the above packages will not be considered
1923
// a user field in any of the other packages. However it is possible to have fields from one package (or class) that we
1924
// may want to consider as a user field in another package (class) in which case having the different array elements
1925
// below would then be the way to acomplish this. The population of the array would need to be more selective.
1926
//
1927
}
1928
else
1929
{
1930
setHasUserField(true);
1931
for (i = 0; i < _numNonUserFieldClasses; i++)
1932
aliasBuilder.userFieldSymRefNumbers()[i]->set(symRef->getReferenceNumber());
1933
}
1934
}
1935
1936
1937
TR::SymbolReference *
1938
J9::SymbolReferenceTable::findOrCreateThreadLowTenureAddressSymbolRef()
1939
{
1940
if (!element(lowTenureAddressSymbol))
1941
{
1942
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1943
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "lowTenureAddress");
1944
sym->setDataType(TR::Address);
1945
sym->setNotCollected();
1946
element(lowTenureAddressSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), lowTenureAddressSymbol, sym);
1947
element(lowTenureAddressSymbol)->setOffset(fej9->getThreadLowTenureAddressPointerOffset());
1948
}
1949
return element(lowTenureAddressSymbol);
1950
}
1951
1952
1953
TR::SymbolReference *
1954
J9::SymbolReferenceTable::findOrCreateThreadHighTenureAddressSymbolRef()
1955
{
1956
if (!element(highTenureAddressSymbol))
1957
{
1958
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1959
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "highTenureAddress");
1960
sym->setDataType(TR::Address);
1961
sym->setNotCollected();
1962
element(highTenureAddressSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), highTenureAddressSymbol, sym);
1963
element(highTenureAddressSymbol)->setOffset(fej9->getThreadHighTenureAddressPointerOffset());
1964
}
1965
return element(highTenureAddressSymbol);
1966
}
1967
1968
1969
TR::SymbolReference *
1970
J9::SymbolReferenceTable::findOrCreateRamStaticsFromClassSymbolRef()
1971
{
1972
if (!element(ramStaticsFromClassSymbol))
1973
{
1974
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1975
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);
1976
element(ramStaticsFromClassSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), ramStaticsFromClassSymbol, sym);
1977
element(ramStaticsFromClassSymbol)->setOffset(fej9->getOffsetOfRamStaticsFromClassField());
1978
sym->setNotCollected();
1979
}
1980
return element(ramStaticsFromClassSymbol);
1981
}
1982
1983
1984
TR::SymbolReference *
1985
J9::SymbolReferenceTable::findOrCreateJavaLangClassFromClassSymbolRef()
1986
{
1987
if (!element(javaLangClassFromClassSymbol))
1988
{
1989
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
1990
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);
1991
element(javaLangClassFromClassSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), javaLangClassFromClassSymbol, sym);
1992
element(javaLangClassFromClassSymbol)->setOffset(fej9->getOffsetOfJavaLangClassFromClassField());
1993
}
1994
return element(javaLangClassFromClassSymbol);
1995
}
1996
1997
1998
TR::SymbolReference *
1999
J9::SymbolReferenceTable::findOrCreateClassFromJavaLangClassSymbolRef()
2000
{
2001
if (!element(classFromJavaLangClassSymbol))
2002
{
2003
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2004
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);
2005
element(classFromJavaLangClassSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), classFromJavaLangClassSymbol, sym);
2006
element(classFromJavaLangClassSymbol)->setOffset(fej9->getOffsetOfClassFromJavaLangClassField());
2007
sym->setNotCollected();
2008
}
2009
return element(classFromJavaLangClassSymbol);
2010
}
2011
2012
TR::SymbolReference *
2013
J9::SymbolReferenceTable::findInitializeStatusFromClassSymbolRef()
2014
{
2015
return element(initializeStatusFromClassSymbol);
2016
}
2017
2018
TR::SymbolReference *
2019
J9::SymbolReferenceTable::findOrCreateInitializeStatusFromClassSymbolRef()
2020
{
2021
if (!element(initializeStatusFromClassSymbol))
2022
{
2023
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2024
TR::Symbol * sym = NULL;
2025
if (self()->comp()->target().is64Bit())
2026
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int64);
2027
else
2028
sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);
2029
element(initializeStatusFromClassSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), initializeStatusFromClassSymbol, sym);
2030
element(initializeStatusFromClassSymbol)->setOffset(fej9->getOffsetOfInitializeStatusFromClassField());
2031
}
2032
return element(initializeStatusFromClassSymbol);
2033
}
2034
2035
TR::SymbolReference *
2036
J9::SymbolReferenceTable::findOrCreateClassRomPtrSymbolRef()
2037
{
2038
if (!element(classRomPtrSymbol))
2039
{
2040
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2041
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);
2042
element(classRomPtrSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), classRomPtrSymbol, sym);
2043
element(classRomPtrSymbol)->setOffset(fej9->getOffsetOfClassRomPtrField());
2044
if (!TR::Compiler->cls.romClassObjectsMayBeCollected())
2045
sym->setNotCollected();
2046
}
2047
return element(classRomPtrSymbol);
2048
}
2049
2050
2051
TR::SymbolReference *
2052
J9::SymbolReferenceTable::findOrCreateGlobalFragmentSymbolRef()
2053
{
2054
if (!element(globalFragmentSymbol))
2055
{
2056
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2057
TR::Symbol * sym;
2058
if (self()->comp()->target().is64Bit())
2059
sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int64);
2060
else
2061
sym = TR::Symbol::createShadow(trHeapMemory(),TR::Int32);
2062
sym->setGlobalFragmentShadowSymbol();
2063
element(globalFragmentSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), globalFragmentSymbol, sym);
2064
element(globalFragmentSymbol)->setOffset(fej9->getRememberedSetGlobalFragmentOffset());
2065
}
2066
return element(globalFragmentSymbol);
2067
}
2068
2069
2070
TR::SymbolReference *
2071
J9::SymbolReferenceTable::findOrCreateFragmentParentSymbolRef()
2072
{
2073
if (!element(fragmentParentSymbol))
2074
{
2075
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2076
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "FragmentParent");
2077
sym->setDataType(TR::Address);
2078
sym->setNotCollected();
2079
element(fragmentParentSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), fragmentParentSymbol, sym);
2080
element(fragmentParentSymbol)->setOffset(fej9->thisThreadRememberedSetFragmentOffset() + fej9->getFragmentParentOffset());
2081
}
2082
return element(fragmentParentSymbol);
2083
}
2084
2085
2086
TR::SymbolReference *
2087
J9::SymbolReferenceTable::findOrCreateThreadDebugEventData(int32_t index)
2088
{
2089
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2090
intptr_t offset = fej9->getThreadDebugEventDataOffset(index);
2091
ListIterator<TR::SymbolReference> li(&_currentThreadDebugEventDataSymbolRefs);
2092
TR::SymbolReference * symRef;
2093
for (symRef = li.getFirst(); symRef; symRef = li.getNext())
2094
if (symRef->getOffset() == offset)
2095
return symRef;
2096
2097
// Not found; create
2098
if (!_currentThreadDebugEventDataSymbol)
2099
{
2100
_currentThreadDebugEventDataSymbol = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "debugEventData");
2101
_currentThreadDebugEventDataSymbol->setDataType(TR::Address);
2102
_currentThreadDebugEventDataSymbol->setNotCollected();
2103
}
2104
TR::SymbolReference *result = new (trHeapMemory()) TR::SymbolReference(self(), _currentThreadDebugEventDataSymbol, offset);
2105
_currentThreadDebugEventDataSymbolRefs.add(result);
2106
return result;
2107
}
2108
2109
TR::SymbolReference *
2110
J9::SymbolReferenceTable::findUnsafeSymbolRef(TR::DataType type, bool javaObjectReference, bool javaStaticReference, bool isVolatile)
2111
{
2112
TR_Array<TR::SymbolReference *> * unsafeSymRefs = NULL;
2113
2114
if (isVolatile)
2115
{
2116
unsafeSymRefs =
2117
javaStaticReference ?
2118
_unsafeJavaStaticVolatileSymRefs :
2119
_unsafeVolatileSymRefs;
2120
}
2121
else
2122
{
2123
unsafeSymRefs =
2124
javaStaticReference ?
2125
_unsafeJavaStaticSymRefs :
2126
_unsafeSymRefs;
2127
}
2128
2129
TR::SymbolReference * symRef = NULL;
2130
2131
if (unsafeSymRefs != NULL)
2132
{
2133
symRef = (*unsafeSymRefs)[type];
2134
}
2135
2136
return symRef;
2137
}
2138
2139
TR::SymbolReference *
2140
J9::SymbolReferenceTable::findOrCreateUnsafeSymbolRef(TR::DataType type, bool javaObjectReference, bool javaStaticReference, bool isVolatile)
2141
{
2142
TR_Array<TR::SymbolReference *> * unsafeSymRefs = NULL;
2143
2144
if (isVolatile)
2145
{
2146
if (javaStaticReference)
2147
{
2148
if (_unsafeJavaStaticVolatileSymRefs == NULL)
2149
_unsafeJavaStaticVolatileSymRefs = new (trHeapMemory()) TR_Array<TR::SymbolReference *>(comp()->trMemory(), TR::NumTypes);
2150
unsafeSymRefs = _unsafeJavaStaticVolatileSymRefs;
2151
}
2152
else
2153
{
2154
if (_unsafeVolatileSymRefs == NULL)
2155
_unsafeVolatileSymRefs = new (trHeapMemory()) TR_Array<TR::SymbolReference *>(comp()->trMemory(), TR::NumTypes);
2156
unsafeSymRefs = _unsafeVolatileSymRefs;
2157
}
2158
}
2159
else
2160
{
2161
if (javaStaticReference)
2162
{
2163
if (_unsafeJavaStaticSymRefs == NULL)
2164
_unsafeJavaStaticSymRefs = new (trHeapMemory()) TR_Array<TR::SymbolReference *>(comp()->trMemory(), TR::NumTypes);
2165
unsafeSymRefs = _unsafeJavaStaticSymRefs;
2166
}
2167
else
2168
{
2169
if (_unsafeSymRefs == NULL)
2170
_unsafeSymRefs = new (trHeapMemory()) TR_Array<TR::SymbolReference *>(comp()->trMemory(), TR::NumTypes);
2171
unsafeSymRefs = _unsafeSymRefs;
2172
}
2173
}
2174
2175
TR::SymbolReference * symRef = (*unsafeSymRefs)[type];
2176
2177
if (symRef == NULL)
2178
{
2179
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(),type);
2180
sym->setUnsafeShadowSymbol();
2181
sym->setArrayShadowSymbol();
2182
if (isVolatile)
2183
sym->setVolatile();
2184
(*unsafeSymRefs)[type] = symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, comp()->getMethodSymbol()->getResolvedMethodIndex(), -1);
2185
aliasBuilder.unsafeSymRefNumbers().set(symRef->getReferenceNumber());
2186
}
2187
2188
// For unsafe symbols created by a call that contained an object and an offset we'll alias
2189
// the symbol against all shadow and statics. If the Unsafe symbol was created using only an
2190
// address then we won't alias against other Java objects.
2191
//
2192
if (javaObjectReference)
2193
comp()->setHasUnsafeSymbol();
2194
else
2195
symRef->setReallySharesSymbol();
2196
2197
return symRef;
2198
}
2199
2200
2201
void
2202
J9::SymbolReferenceTable::performClassLookahead(TR_PersistentClassInfo *classInfo, TR_ResolvedMethod *method)
2203
{
2204
// Do not perform class lookahead when peeking (including recursive class lookahead)
2205
//
2206
((TR_J9ByteCodeIlGenerator *)(comp()->getCurrentIlGenerator()))->performClassLookahead(classInfo);
2207
}
2208
2209
2210
int32_t
2211
J9::SymbolReferenceTable::userFieldMethodId(TR::MethodSymbol *methodSymbol)
2212
{
2213
static const char *userField = feGetEnv("TR_UserField");
2214
if (userField)
2215
{
2216
TR::RecognizedMethod method = methodSymbol->getRecognizedMethod();
2217
if (method == TR::java_util_HashMap_rehash)
2218
return J9::nonUser_java_util_HashMap_rehash - 1;
2219
else if (method == TR::java_util_HashMap_analyzeMap)
2220
return J9::nonUser_java_util_HashMap_analyzeMap - 1;
2221
else if (method == TR::java_util_HashMap_calculateCapacity)
2222
return J9::nonUser_java_util_HashMap_calculateCapacity - 1;
2223
else if (method == TR::java_util_HashMap_findNullKeyEntry)
2224
return J9::nonUser_java_util_HashMap_findNullKeyEntry - 1;
2225
}
2226
return -1;
2227
}
2228
2229
2230
int32_t
2231
J9::SymbolReferenceTable::immutableConstructorId(TR::MethodSymbol *methodSymbol)
2232
{
2233
TR::RecognizedMethod method = methodSymbol->getRecognizedMethod();
2234
switch (method)
2235
{
2236
case TR::java_lang_String_init_String:
2237
case TR::java_lang_String_init_String_char:
2238
case TR::java_lang_String_init_int_int_char_boolean:
2239
// All String constructors share the same ID
2240
method = TR::java_lang_String_init;
2241
break;
2242
default:
2243
break;
2244
}
2245
2246
if (TR::java_lang_Boolean_init <= method && method <= TR::java_lang_String_init)
2247
return method - TR::java_lang_Boolean_init;
2248
else
2249
return -1;
2250
}
2251
2252
2253
bool
2254
J9::SymbolReferenceTable::isImmutable(TR::SymbolReference *symRef)
2255
{
2256
if (!_hasImmutable)
2257
return false;
2258
2259
int32_t i;
2260
for (i = 0; i < _numImmutableClasses; i++)
2261
{
2262
if (_immutableSymRefNumbers[i]->get(symRef->getReferenceNumber()))
2263
return true;
2264
}
2265
2266
ListElement<TR_ImmutableInfo> *immutableClassInfoElem = _immutableInfo.getListHead();
2267
while (immutableClassInfoElem)
2268
{
2269
TR_ImmutableInfo *immutableClassInfo = immutableClassInfoElem->getData();
2270
if (immutableClassInfo->_immutableSymRefNumbers->get(symRef->getReferenceNumber()))
2271
return true;
2272
immutableClassInfoElem = immutableClassInfoElem->getNextElement();
2273
}
2274
2275
return false;
2276
}
2277
2278
2279
TR_ImmutableInfo *
2280
J9::SymbolReferenceTable::findOrCreateImmutableInfo(TR_OpaqueClassBlock *clazz)
2281
{
2282
ListElement<TR_ImmutableInfo> *immutableClassInfoElem = _immutableInfo.getListHead();
2283
while (immutableClassInfoElem)
2284
{
2285
TR_ImmutableInfo *immutableClassInfo = immutableClassInfoElem->getData();
2286
if (immutableClassInfo->_clazz == clazz)
2287
return immutableClassInfo;
2288
immutableClassInfoElem = immutableClassInfoElem->getNextElement();
2289
}
2290
2291
TR_ImmutableInfo *newImmutableInfo = new (trHeapMemory()) TR_ImmutableInfo(clazz,
2292
new (trHeapMemory()) TR_BitVector(_size_hint, comp()->trMemory(), heapAlloc, growable),
2293
NULL);
2294
_immutableInfo.add(newImmutableInfo);
2295
return newImmutableInfo;
2296
}
2297
2298
2299
void
2300
J9::SymbolReferenceTable::checkImmutable(TR::SymbolReference *symRef)
2301
{
2302
if (!symRef->getSymbol()->isShadow() || symRef->getCPIndex() < 0)
2303
return;
2304
2305
int32_t length;
2306
char * name = symRef->getOwningMethod(comp())->classNameOfFieldOrStatic(symRef->getCPIndex(), length);
2307
2308
if (name == NULL || length == 0)
2309
return;
2310
2311
static struct N { const char * name; } names[] =
2312
{
2313
"java/lang/Boolean",
2314
"java/lang/Character",
2315
"java/lang/Byte",
2316
"java/lang/Short",
2317
"java/lang/Integer",
2318
"java/lang/Long",
2319
"java/lang/Float",
2320
"java/lang/Double",
2321
"java/lang/String"
2322
};
2323
2324
if (!comp()->getOption(TR_DisableImmutableFieldAliasing))
2325
{
2326
TR_ASSERT(sizeof(names)/sizeof(char *) == _numImmutableClasses,"Size of names array is not correct\n");
2327
int32_t i;
2328
for (i = 0; i < _numImmutableClasses; i++)
2329
{
2330
if (strcmp(names[i].name, name) == 0)
2331
{
2332
_hasImmutable = true;
2333
_immutableSymRefNumbers[i]->set(symRef->getReferenceNumber());
2334
break;
2335
}
2336
}
2337
}
2338
2339
if (true)
2340
{
2341
if (!symRef->getSymbol()->isArrayShadowSymbol())
2342
{
2343
TR::Symbol *sym = symRef->getSymbol();
2344
if (sym->isPrivate() || sym->isFinal())
2345
{
2346
int32_t len;
2347
char *classNameOfFieldOrStatic = symRef->getOwningMethod(comp())->classNameOfFieldOrStatic(symRef->getCPIndex(), len);
2348
TR_OpaqueClassBlock * classOfStatic = comp()->fe()->getClassFromSignature(classNameOfFieldOrStatic, len, symRef->getOwningMethod(comp()));
2349
2350
bool isClassInitialized = false;
2351
TR_PersistentClassInfo * classInfo =
2352
comp()->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(classOfStatic, comp());
2353
if (classInfo && classInfo->isInitialized())
2354
isClassInitialized = true;
2355
2356
if ((classOfStatic != comp()->getSystemClassPointer()) &&
2357
isClassInitialized && TR::Compiler->cls.isClassFinal(comp(), classOfStatic))
2358
{
2359
if (!classInfo->getFieldInfo() &&
2360
(comp()->getMethodHotness() >= hot))
2361
{
2362
performClassLookahead(classInfo, symRef->getOwningMethod(comp()));
2363
}
2364
2365
if (classInfo->getFieldInfo())
2366
{
2367
TR_PersistentFieldInfo * fieldInfo = classInfo->getFieldInfo()->find(comp(), sym, symRef);
2368
if (fieldInfo && fieldInfo->isImmutable())
2369
{
2370
setHasImmutable(true);
2371
TR_ImmutableInfo *clazzImmutableInfo = findOrCreateImmutableInfo(classOfStatic);
2372
clazzImmutableInfo->_immutableSymRefNumbers->set(symRef->getReferenceNumber());
2373
}
2374
}
2375
}
2376
}
2377
}
2378
}
2379
}
2380
2381
2382
TR::SymbolReference *
2383
J9::SymbolReferenceTable::findOrCreateImmutableGenericIntShadowSymbolReference(intptr_t offset)
2384
{
2385
static char *disableImmutableIntShadows = feGetEnv("TR_disableImmutableIntShadows");
2386
if (disableImmutableIntShadows)
2387
return findOrCreateGenericIntShadowSymbolReference(offset);
2388
TR::SymbolReference * symRef = new (trHeapMemory()) TR::SymbolReference(self(), findOrCreateGenericIntShadowSymbol(), comp()->getMethodSymbol()->getResolvedMethodIndex(), -1);
2389
symRef->setOffset(offset);
2390
return symRef;
2391
}
2392
2393
TR::SymbolReference *
2394
J9::SymbolReferenceTable::findOrCreateCheckCastForArrayStoreSymbolRef(TR::ResolvedMethodSymbol *)
2395
{
2396
return findOrCreateRuntimeHelper(TR_checkCastForArrayStore, false, true, true);
2397
}
2398
2399
2400
2401
TR::SymbolReference *
2402
J9::SymbolReferenceTable::findOrCreateProfilingBufferCursorSymbolRef()
2403
{
2404
if (!element(profilingBufferCursorSymbol))
2405
{
2406
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2407
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "ProfilingBufferCursor");
2408
sym->setDataType(TR::Address);
2409
element(profilingBufferCursorSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), profilingBufferCursorSymbol, sym);
2410
element(profilingBufferCursorSymbol)->setOffset(fej9->thisThreadGetProfilingBufferCursorOffset());
2411
2412
// We can't let the load/store of the exception symbol swing down
2413
aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(profilingBufferCursorSymbol)); // add the symRef to the statics list to get correct aliasing info
2414
}
2415
return element(profilingBufferCursorSymbol);
2416
}
2417
2418
2419
TR::SymbolReference *
2420
J9::SymbolReferenceTable::findOrCreateProfilingBufferEndSymbolRef()
2421
{
2422
if (!element(profilingBufferEndSymbol))
2423
{
2424
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2425
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(),"profilingBufferEnd");
2426
sym->setDataType(TR::Address);
2427
element(profilingBufferEndSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), profilingBufferEndSymbol, sym);
2428
element(profilingBufferEndSymbol)->setOffset(fej9->thisThreadGetProfilingBufferEndOffset());
2429
2430
// We can't let the load/store of the exception symbol swing down
2431
aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(profilingBufferEndSymbol)); // add the symRef to the statics list to get correct aliasing info
2432
}
2433
return element(profilingBufferEndSymbol);
2434
}
2435
2436
TR::SymbolReference *
2437
J9::SymbolReferenceTable::findOrCreateVMThreadTempSlotFieldSymbolRef()
2438
{
2439
if (!element(j9VMThreadTempSlotFieldSymbol))
2440
{
2441
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2442
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "j9VMThreadTempSlotField");
2443
sym->setDataType(TR::Address);
2444
element(j9VMThreadTempSlotFieldSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), j9VMThreadTempSlotFieldSymbol, sym);
2445
element(j9VMThreadTempSlotFieldSymbol)->setOffset(fej9->thisThreadGetTempSlotOffset());
2446
aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(j9VMThreadTempSlotFieldSymbol));
2447
}
2448
return element(j9VMThreadTempSlotFieldSymbol);
2449
}
2450
2451
TR::SymbolReference *
2452
J9::SymbolReferenceTable::findOrCreateProfilingBufferSymbolRef(intptr_t offset)
2453
{
2454
if (!element(profilingBufferSymbol))
2455
{
2456
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory());
2457
sym->setDataType(TR::Int32);
2458
TR::SymbolReference *symRef = new (trHeapMemory()) TR::SymbolReference(self(), profilingBufferSymbol, sym);
2459
element(profilingBufferSymbol) = symRef;
2460
element(profilingBufferSymbol)->setOffset(offset);
2461
}
2462
return element(profilingBufferSymbol);
2463
}
2464
2465
2466
TR::SymbolReference *
2467
J9::SymbolReferenceTable::findShadowSymbol(TR_ResolvedMethod * owningMethod, int32_t cpIndex, TR::DataType type, TR::Symbol::RecognizedField *recognizedField)
2468
{
2469
TR::SymbolReference * symRef;
2470
TR_SymRefIterator i(type == TR::Address ? aliasBuilder.addressShadowSymRefs() :
2471
(type == TR::Int32 ? aliasBuilder.intShadowSymRefs() : aliasBuilder.nonIntPrimitiveShadowSymRefs()), self());
2472
while ((symRef = i.getNext()) != NULL)
2473
{
2474
if ((recognizedField &&
2475
*recognizedField != TR::Symbol::UnknownField &&
2476
*recognizedField == symRef->getSymbol()->getRecognizedField())||
2477
(symRef->getSymbol()->getDataType() == type &&
2478
symRef->getCPIndex() != -1 &&
2479
cpIndex != -1 &&
2480
TR::Compiler->cls.jitFieldsAreSame(comp(), owningMethod, cpIndex,
2481
symRef->getOwningMethod(comp()), symRef->getCPIndex(), symRef->getSymbol()->isStatic())))
2482
{
2483
if (cpIndex != -1 && owningMethod->classOfMethod() != symRef->getOwningMethod(comp())->classOfMethod())
2484
{
2485
bool isVolatile = true, isFinal = false, isPrivate = false, isUnresolvedInCP ;
2486
TR::DataType type = TR::DataTypes::NoType;
2487
uint32_t offset = 0;
2488
// isStore is a hardcoded false here since we only really want to set hasBeenAccessed correctly
2489
bool resolved = owningMethod->fieldAttributes(comp(), cpIndex, &offset, &type, &isVolatile, &isFinal, &isPrivate, false, &isUnresolvedInCP, true);
2490
symRef->setHasBeenAccessedAtRuntime(isUnresolvedInCP ? TR_no : TR_maybe);
2491
}
2492
return symRef;
2493
}
2494
}
2495
return 0;
2496
}
2497
2498
2499
TR::SymbolReference *
2500
J9::SymbolReferenceTable::findOrCreateClassIsArraySymbolRef()
2501
{
2502
if (!element(isArraySymbol))
2503
{
2504
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2505
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Int32);
2506
element(isArraySymbol) = new (trHeapMemory()) TR::SymbolReference(self(), isArraySymbol, sym);
2507
element(isArraySymbol)->setOffset(fej9->getOffsetOfIsArrayFieldFromRomClass());
2508
}
2509
return element(isArraySymbol);
2510
}
2511
2512
2513
TR::SymbolReference *
2514
J9::SymbolReferenceTable::findOrCreateArrayComponentTypeSymbolRef()
2515
{
2516
if (!element(componentClassSymbol))
2517
{
2518
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2519
TR::Symbol * sym = TR::Symbol::createShadow(trHeapMemory(), TR::Address);
2520
element(componentClassSymbol) = new (trHeapMemory()) TR::SymbolReference(self(), componentClassSymbol, sym);
2521
element(componentClassSymbol)->setOffset(fej9->getOffsetOfArrayComponentTypeField());
2522
if (!TR::Compiler->cls.classObjectsMayBeCollected())
2523
sym->setNotCollected();
2524
}
2525
return element(componentClassSymbol);
2526
}
2527
2528
TR::SymbolReference *
2529
J9::SymbolReferenceTable::findOrCreateVMThreadFloatTemp1SymbolRef()
2530
{
2531
if (!element(j9VMThreadFloatTemp1Symbol))
2532
{
2533
TR_J9VMBase *fej9 = (TR_J9VMBase *)(fe());
2534
TR::Symbol * sym = TR::RegisterMappedSymbol::createMethodMetaDataSymbol(trHeapMemory(), "j9VMThreadFloatTemp1");
2535
sym->setDataType(TR::Address);
2536
element(j9VMThreadFloatTemp1Symbol) = new (trHeapMemory()) TR::SymbolReference(self(), j9VMThreadFloatTemp1Symbol, sym);
2537
element(j9VMThreadFloatTemp1Symbol)->setOffset(fej9->thisThreadGetFloatTemp1Offset());
2538
aliasBuilder.addressStaticSymRefs().set(getNonhelperIndex(j9VMThreadFloatTemp1Symbol));
2539
}
2540
return element(j9VMThreadFloatTemp1Symbol);
2541
}
2542
2543
TR::SymbolReference *
2544
J9::SymbolReferenceTable::findOrCreateObjectInequalityComparisonSymbolRef()
2545
{
2546
TR::SymbolReference *symRef = element(objectInequalityComparisonSymbol);
2547
if (symRef != NULL)
2548
return symRef;
2549
2550
symRef = self()->findOrCreateCodeGenInlinedHelper(objectInequalityComparisonSymbol);
2551
symRef->setCanGCandReturn();
2552
symRef->setCanGCandExcept();
2553
return symRef;
2554
}
2555
2556
TR::SymbolReference *
2557
J9::SymbolReferenceTable::findOrCreateObjectEqualityComparisonSymbolRef()
2558
{
2559
TR::SymbolReference *symRef = element(objectEqualityComparisonSymbol);
2560
if (symRef != NULL)
2561
return symRef;
2562
2563
symRef = self()->findOrCreateCodeGenInlinedHelper(objectEqualityComparisonSymbol);
2564
symRef->setCanGCandReturn();
2565
symRef->setCanGCandExcept();
2566
return symRef;
2567
}
2568
2569
TR::SymbolReference *
2570
J9::SymbolReferenceTable::findOrCreateEncodeASCIISymbolRef()
2571
{
2572
TR::SymbolReference *symRef = element(encodeASCIISymbol);
2573
if (symRef != NULL)
2574
return symRef;
2575
2576
symRef = self()->findOrCreateCodeGenInlinedHelper(encodeASCIISymbol);
2577
return symRef;
2578
}
2579
2580
TR::SymbolReference *
2581
J9::SymbolReferenceTable::findOrCreateNonNullableArrayNullStoreCheckSymbolRef()
2582
{
2583
TR::SymbolReference *symRef = element(nonNullableArrayNullStoreCheckSymbol);
2584
if (symRef != NULL)
2585
return symRef;
2586
2587
symRef = self()->findOrCreateCodeGenInlinedHelper(nonNullableArrayNullStoreCheckSymbol);
2588
symRef->setCanGCandExcept();
2589
return symRef;
2590
}
2591
2592
TR::ParameterSymbol *
2593
J9::SymbolReferenceTable::createParameterSymbol(
2594
TR::ResolvedMethodSymbol *owningMethodSymbol,
2595
int32_t slot,
2596
TR::DataType type,
2597
TR::KnownObjectTable::Index knownObjectIndex)
2598
{
2599
TR::ParameterSymbol * sym = TR::ParameterSymbol::create(trHeapMemory(),type,slot);
2600
2601
if (comp()->getOption(TR_MimicInterpreterFrameShape))
2602
{
2603
int32_t parameterSlots = owningMethodSymbol->getNumParameterSlots();
2604
sym->setGCMapIndex(-slot + parameterSlots - sym->getNumberOfSlots());
2605
}
2606
2607
TR::SymbolReference *symRef = NULL;
2608
if (knownObjectIndex == TR::KnownObjectTable::UNKNOWN)
2609
symRef = new (trHeapMemory()) TR::SymbolReference(self(), sym, owningMethodSymbol->getResolvedMethodIndex(), slot);
2610
else
2611
symRef = createTempSymRefWithKnownObject(sym, owningMethodSymbol->getResolvedMethodIndex(), slot, knownObjectIndex);
2612
2613
owningMethodSymbol->setParmSymRef(slot, symRef);
2614
if (!parmSlotCameFromExpandingAnArchetypeArgPlaceholder(slot, owningMethodSymbol))
2615
owningMethodSymbol->getAutoSymRefs(slot).add(symRef);
2616
2617
return sym;
2618
}
2619
2620
TR::SymbolReference *
2621
J9::SymbolReferenceTable::findArrayClassRomPtrSymbolRef()
2622
{
2623
return element(arrayClassRomPtrSymbol);
2624
}
2625
2626
TR::SymbolReference *
2627
J9::SymbolReferenceTable::findClassRomPtrSymbolRef()
2628
{
2629
return element(classRomPtrSymbol);
2630
}
2631
2632
const char *J9::SymbolReferenceTable::_commonNonHelperSymbolNames[] =
2633
{
2634
"<classRomPtr>",
2635
"<ramStaticsFromClass>",
2636
"<componentClassAsPrimitive>",
2637
"<initializeStatusFromClass>",
2638
"<threadPrivateFlags>",
2639
"<arrayletSpineFirstElement>",
2640
"<dltBlock>",
2641
"<classFromJavaLangClassAsPrimitive>",
2642
"<javaVM>",
2643
"<j9methodExtraField>",
2644
"<j9methodConstantPoolField>",
2645
"<startPCLinkageInfo>",
2646
"<instanceShapeFromROMClass>",
2647
"<j9VMThreadTempSlotField>"
2648
};
2649
2650
2651
const char *
2652
J9::SymbolReferenceTable::getNonHelperSymbolName(CommonNonhelperSymbol nonHelper)
2653
{
2654
#ifdef OMR_ENABLE_NONHELPER_EXTENSIBLE_ENUM
2655
TR_ASSERT_FATAL(nonHelper <= J9lastNonhelperSymbol, "unknown nonhelper %" OMR_PRId32, static_cast<int32_t>(nonHelper));
2656
2657
static_assert(sizeof(_commonNonHelperSymbolNames)/sizeof(_commonNonHelperSymbolNames[0]) ==
2658
static_cast<int32_t>(J9lastNonhelperSymbol - J9firstNonhelperSymbol + 1),
2659
"_commonNonHelperSymbolNames array must match CommonNonHelperSymbol enumeration");
2660
2661
if (nonHelper >= J9firstNonhelperSymbol)
2662
{
2663
return _commonNonHelperSymbolNames[static_cast<int32_t>(nonHelper - J9firstNonhelperSymbol)];
2664
}
2665
else
2666
{
2667
return OMR::SymbolReferenceTableConnector::getNonHelperSymbolName(nonHelper);
2668
}
2669
#else
2670
return NULL;
2671
#endif
2672
}
2673
2674