Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/codegen/CodeGenRA.cpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2021 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
#if defined(J9ZOS390)
24
//On zOS XLC linker can't handle files with same name at link time
25
//This workaround with pragma is needed. What this does is essentially
26
//give a different name to the codesection (csect) for this file. So it
27
//doesn't conflict with another file with same name.
28
29
#pragma csect(CODE,"TRJ9CGRABase#C")
30
#pragma csect(STATIC,"TRJ9CGRABase#S")
31
#pragma csect(TEST,"TRJ9CGRABase#T")
32
#endif
33
34
#include "codegen/J9CodeGenerator.hpp"
35
36
#include <limits.h>
37
#include <stdint.h>
38
#include <stdlib.h>
39
#include <algorithm>
40
#include "codegen/BackingStore.hpp"
41
#include "codegen/CodeGenerator.hpp"
42
#include "codegen/CodeGenerator_inlines.hpp"
43
#include "env/FrontEnd.hpp"
44
#include "codegen/GCStackAtlas.hpp"
45
#include "codegen/Instruction.hpp"
46
#include "codegen/Linkage.hpp"
47
#include "codegen/Linkage_inlines.hpp"
48
#include "codegen/LinkageConventionsEnum.hpp"
49
#include "codegen/LiveReference.hpp"
50
#include "codegen/LiveRegister.hpp"
51
#include "codegen/Register.hpp"
52
#include "codegen/RegisterConstants.hpp"
53
#include "codegen/TreeEvaluator.hpp"
54
#include "compile/Compilation.hpp"
55
#include "control/Options.hpp"
56
#include "control/Options_inlines.hpp"
57
#include "env/CompilerEnv.hpp"
58
#include "env/IO.hpp"
59
#include "env/ObjectModel.hpp"
60
#include "env/StackMemoryRegion.hpp"
61
#include "env/TRMemory.hpp"
62
#include "il/AliasSetInterface.hpp"
63
#include "il/AutomaticSymbol.hpp"
64
#include "il/Block.hpp"
65
#include "il/DataTypes.hpp"
66
#include "il/ILOpCodes.hpp"
67
#include "il/ILOps.hpp"
68
#include "il/MethodSymbol.hpp"
69
#include "il/Node.hpp"
70
#include "il/Node_inlines.hpp"
71
#include "il/ParameterSymbol.hpp"
72
#include "il/ResolvedMethodSymbol.hpp"
73
#include "il/Symbol.hpp"
74
#include "il/SymbolReference.hpp"
75
#include "il/TreeTop.hpp"
76
#include "il/TreeTop_inlines.hpp"
77
#include "infra/Array.hpp"
78
#include "infra/Assert.hpp"
79
#include "infra/BitVector.hpp"
80
#include "infra/Cfg.hpp"
81
#include "infra/Flags.hpp"
82
#include "infra/Link.hpp"
83
#include "infra/List.hpp"
84
#include "infra/TRCfgEdge.hpp"
85
#include "infra/TRCfgNode.hpp"
86
#include "optimizer/Optimizations.hpp"
87
#include "optimizer/RegisterCandidate.hpp"
88
#include "optimizer/Structure.hpp"
89
#include "ras/Debug.hpp"
90
91
TR::AutomaticSymbol *
92
J9::CodeGenerator::allocateVariableSizeSymbol(int32_t size)
93
{
94
TR::AutomaticSymbol *sym = TR::AutomaticSymbol::createVariableSized(self()->trHeapMemory(), size);
95
self()->comp()->getMethodSymbol()->addVariableSizeSymbol(sym);
96
if (self()->getDebug())
97
self()->getDebug()->newVariableSizeSymbol(sym);
98
return sym;
99
}
100
101
TR::SymbolReference *
102
J9::CodeGenerator::allocateVariableSizeSymRef(int32_t byteLength)
103
{
104
if (self()->traceBCDCodeGen())
105
traceMsg(self()->comp(),"\tallocateVariableSizeSymbolReference: length = %d\n",byteLength);
106
TR::SymbolReference *symRef = self()->getFreeVariableSizeSymRef(byteLength);
107
TR::AutomaticSymbol *sym = NULL;
108
if (symRef == NULL)
109
{
110
sym = self()->allocateVariableSizeSymbol(byteLength);
111
symRef = new (self()->trHeapMemory()) TR::SymbolReference(self()->comp()->getSymRefTab(), sym);
112
symRef->setIsTempVariableSizeSymRef();
113
if (self()->traceBCDCodeGen())
114
traceMsg(self()->comp(),"\t\tno available symRef allocate symRef #%d : %s (%p) of length = %d\n",symRef->getReferenceNumber(),self()->getDebug()->getName(sym),sym,byteLength);
115
_variableSizeSymRefAllocList.push_front(symRef);
116
}
117
else
118
{
119
sym = symRef->getSymbol()->getVariableSizeSymbol();
120
if (self()->traceBCDCodeGen())
121
traceMsg(self()->comp(),"\t\treuse available symRef #%d : %s (%p) with length = %d\n",symRef->getReferenceNumber(),self()->getDebug()->getName(sym),sym,byteLength);
122
}
123
sym->setActiveSize(byteLength);
124
sym->setReferenceCount(0);
125
if (self()->traceBCDCodeGen())
126
traceMsg(self()->comp(),"\treturning symRef #%d (%s) : activeSize set to %d (length = %d)\n",
127
symRef->getReferenceNumber(),self()->getDebug()->getName(sym),sym->getActiveSize(),sym->getSize());
128
return symRef;
129
}
130
131
void
132
J9::CodeGenerator::freeAllVariableSizeSymRefs()
133
{
134
if (!_variableSizeSymRefPendingFreeList.empty())
135
{
136
auto it = _variableSizeSymRefPendingFreeList.begin();
137
while (it != _variableSizeSymRefPendingFreeList.end())
138
{
139
TR_ASSERT((*it)->getSymbol()->isVariableSizeSymbol(),"symRef #%d must contain a variable size symbol\n",(*it)->getReferenceNumber());
140
self()->freeVariableSizeSymRef(*(it++), true); // freeAddressTakenSymbols=true
141
}
142
}
143
}
144
145
void
146
J9::CodeGenerator::freeVariableSizeSymRef(
147
TR::SymbolReference *symRef,
148
bool freeAddressTakenSymbol)
149
{
150
TR_ASSERT(symRef->getSymbol()->isVariableSizeSymbol(),"symRef #%d must contain a variable size symbol\n",symRef->getReferenceNumber());
151
auto *sym = symRef->getSymbol()->getVariableSizeSymbol();
152
if (self()->traceBCDCodeGen())
153
traceMsg(self()->comp(),"\tfreeVariableSizeSymbol: #%d (%s)%s%s%s\n",
154
symRef->getReferenceNumber(),self()->getDebug()->getName(sym),
155
sym->isSingleUse()?", isSingleUse=true":"",freeAddressTakenSymbol?", freeAddressTakenSymbol=true":"",sym->isAddressTaken()?", symAddrTaken=true":"");
156
TR_ASSERT(!(std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), symRef) != _variableSizeSymRefFreeList.end())
157
,"symRef #%d has already been freed\n",symRef->getReferenceNumber());
158
if (sym->isAddressTaken() && !freeAddressTakenSymbol)
159
{
160
if (self()->traceBCDCodeGen())
161
traceMsg(self()->comp(),"\t\tsym->isAddressTaken()=true and freeAddressTakenSymbol=false so do not free sym #%d (%s %p)\n",symRef->getReferenceNumber(),self()->getDebug()->getName(sym),sym);
162
return;
163
}
164
else
165
{
166
if (self()->traceBCDCodeGen())
167
traceMsg(self()->comp(),"\t\tfree symRef #%d (%s %p)\n",symRef->getReferenceNumber(),self()->getDebug()->getName(sym),sym);
168
sym->setIsSingleUse(false);
169
sym->setIsAddressTaken(false);
170
sym->setNodeToFreeAfter(NULL);
171
sym->setReferenceCount(0);
172
symRef->resetHasTemporaryNegativeOffset();
173
bool found = (std::find(_variableSizeSymRefPendingFreeList.begin(), _variableSizeSymRefPendingFreeList.end(), symRef) != _variableSizeSymRefPendingFreeList.end());
174
if (!_variableSizeSymRefPendingFreeList.empty() && found)
175
_variableSizeSymRefPendingFreeList.remove(symRef);
176
_variableSizeSymRefFreeList.push_front(symRef);
177
}
178
}
179
180
void
181
J9::CodeGenerator::pendingFreeVariableSizeSymRef(TR::SymbolReference *symRef)
182
{
183
TR_ASSERT(symRef->getSymbol()->isVariableSizeSymbol(),"symRef #%d must contain a variable size symbol\n",symRef->getReferenceNumber());
184
bool found = (std::find(_variableSizeSymRefPendingFreeList.begin(), _variableSizeSymRefPendingFreeList.end(), symRef) != _variableSizeSymRefPendingFreeList.end());
185
if (self()->traceBCDCodeGen())
186
traceMsg(self()->comp(),"\tpendingFreeVariableSizeSymRef: #%d (%s) %s to pending free list\n",
187
symRef->getReferenceNumber(),self()->getDebug()->getName(symRef->getSymbol()),found ?"do not add (already present)":"add");
188
if (!found)
189
_variableSizeSymRefPendingFreeList.push_front(symRef);
190
}
191
192
193
TR::SymbolReference *
194
J9::CodeGenerator::getFreeVariableSizeSymRef(int32_t byteLength)
195
{
196
TR::SymbolReference *biggestSymRef;
197
if(_variableSizeSymRefFreeList.empty())
198
return NULL;
199
else
200
biggestSymRef = _variableSizeSymRefFreeList.front();
201
202
TR::SymbolReference *previous = NULL;
203
TR::SymbolReference *savedPrevious = NULL;
204
TR::SymbolReference *biggestPrevious = NULL;
205
if (self()->traceBCDCodeGen())
206
traceMsg(self()->comp(),"\tgetFreeVariableSizeSymRef of length %d\n",byteLength);
207
208
if (biggestSymRef)
209
{
210
if (self()->traceBCDCodeGen())
211
traceMsg(self()->comp(),"\t\tset initial biggestSymRef to #%d (%s) with length %d\n",
212
biggestSymRef->getReferenceNumber(),self()->getDebug()->getName(biggestSymRef->getSymbol()),biggestSymRef->getSymbol()->getSize());
213
auto i = _variableSizeSymRefFreeList.begin();
214
while (i != _variableSizeSymRefFreeList.end())
215
{
216
previous = savedPrevious;
217
if (self()->traceBCDCodeGen())
218
traceMsg(self()->comp(),"\t\texamine free symRef #%d (%s) with length %d\n",(*i)->getReferenceNumber(),self()->getDebug()->getName((*i)->getSymbol()),(*i)->getSymbol()->getSize());
219
if ((*i)->getSymbol()->getSize() >= byteLength)
220
{
221
if (self()->traceBCDCodeGen())
222
{
223
traceMsg(self()->comp(),"\t\tfound big enough free symRef #%d (%s) with length >= req length of %d\n",(*i)->getReferenceNumber(),self()->getDebug()->getName((*i)->getSymbol()),byteLength);
224
traceMsg(self()->comp(),"\t\tremove free symRef #%d (%s) from list, previous is %p\n",(*i)->getReferenceNumber(),self()->getDebug()->getName((*i)->getSymbol()),previous ? previous:(void *)0);
225
}
226
TR::SymbolReference *symRef = *i;
227
if(previous == NULL)
228
_variableSizeSymRefFreeList.pop_front();
229
else
230
{
231
auto foundIt = std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), previous);
232
if(foundIt != _variableSizeSymRefFreeList.end())
233
{
234
++foundIt;
235
_variableSizeSymRefFreeList.erase(foundIt); // pops head if previous==NULL
236
}
237
}
238
TR_ASSERT(!(std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), (*i)) != _variableSizeSymRefFreeList.end())
239
,"shouldn't find symRef #%d as it was just removed\n",(*i)->getReferenceNumber());
240
return symRef;
241
}
242
else if ((*i)->getSymbol()->getSize() > biggestSymRef->getSymbol()->getSize())
243
{
244
if (self()->traceBCDCodeGen())
245
traceMsg(self()->comp(),"\t\tupdate biggest symRef seen to #%d (%s) with length %d\n",(*i)->getReferenceNumber(),self()->getDebug()->getName((*i)->getSymbol()),byteLength);
246
biggestPrevious = previous;
247
biggestSymRef = *i;
248
}
249
savedPrevious = *i;
250
++i;
251
}
252
if (self()->traceBCDCodeGen())
253
traceMsg(self()->comp(),"\t\tincrease biggestSymRef #%d (%s) size from %d -> %d\n",
254
biggestSymRef->getReferenceNumber(),self()->getDebug()->getName(biggestSymRef->getSymbol()),biggestSymRef->getSymbol()->getSize(),byteLength);
255
biggestSymRef->getSymbol()->setSize(byteLength);
256
}
257
258
if (self()->traceBCDCodeGen() && biggestSymRef)
259
traceMsg(self()->comp(),"\t\tremove free symRef #%d (%s) from list, previous is %p\n",biggestSymRef->getReferenceNumber(),self()->getDebug()->getName(biggestSymRef->getSymbol()),previous ? previous:(void *)9999);
260
if(biggestPrevious == NULL)
261
_variableSizeSymRefFreeList.pop_front();
262
else
263
{
264
auto foundIt = std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), biggestPrevious);
265
if(foundIt != _variableSizeSymRefFreeList.end())
266
{
267
auto nextIt = ++foundIt;
268
_variableSizeSymRefFreeList.remove(*nextIt); // pops head if previous==NULL
269
}
270
}
271
TR_ASSERT(!biggestSymRef || !(std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), biggestSymRef) != _variableSizeSymRefFreeList.end())
272
,"shouldn't find biggestSymRef #%d as it was just removed\n",biggestSymRef->getReferenceNumber());
273
return biggestSymRef;
274
}
275
276
void
277
J9::CodeGenerator::checkForUnfreedVariableSizeSymRefs()
278
{
279
bool foundUnfreedSlot = false;
280
for (auto i = _variableSizeSymRefAllocList.begin(); i != _variableSizeSymRefAllocList.end(); ++i)
281
{
282
bool found = (std::find(_variableSizeSymRefFreeList.begin(), _variableSizeSymRefFreeList.end(), (*i)) != _variableSizeSymRefFreeList.end());
283
if (!found)
284
{
285
TR_ASSERT((*i)->getSymbol()->isVariableSizeSymbol(),"symRef #%d must contain a variable size symbol\n",(*i)->getReferenceNumber());
286
if (self()->traceBCDCodeGen())
287
traceMsg(self()->comp(),"Variable size symRef #%d (%s) has not been freed (symbol refCount is %d)\n",
288
(*i)->getReferenceNumber(),self()->getDebug()->getName((*i)->getSymbol()),(*i)->getSymbol()->getVariableSizeSymbol()->getReferenceCount());
289
foundUnfreedSlot = true;
290
}
291
}
292
TR_ASSERT(!foundUnfreedSlot,"Unfreed variable size symRefs found at end of method\n");
293
}
294
295