Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/ilgen/J9ByteCodeIteratorWithState.hpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2019 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 "infra/Flags.hpp"
24
#include "infra/Link.hpp"
25
#include "infra/Stack.hpp"
26
#include "ilgen/J9ByteCode.hpp"
27
#include "ilgen/J9ByteCodeIterator.hpp"
28
#include "ilgen/ByteCodeIteratorWithState.hpp"
29
#include "il/Node.hpp"
30
#include "il/Node_inlines.hpp"
31
#include "il/ParameterSymbol.hpp"
32
#include "il/TreeTop.hpp"
33
#include "compiler/il/OMRTreeTop_inlines.hpp"
34
35
class TR_J9ByteCodeIteratorWithState :
36
public TR_ByteCodeIteratorWithState<TR_J9ByteCode, J9BCunknown, TR_J9ByteCodeIterator, TR::Node *>
37
{
38
typedef TR_ByteCodeIteratorWithState<TR_J9ByteCode, J9BCunknown, TR_J9ByteCodeIterator, TR::Node *> Base;
39
40
public:
41
TR_J9ByteCodeIteratorWithState(TR::ResolvedMethodSymbol * methodSymbol, TR_J9VMBase * fe, TR::Compilation * comp)
42
: Base(methodSymbol, comp),
43
_replacedSymRefs(NULL)
44
{
45
TR_J9ByteCodeIterator::initialize(static_cast<TR_ResolvedJ9Method *>(methodSymbol->getResolvedMethod()), fe);
46
}
47
48
protected:
49
50
void initialize()
51
{
52
Base::initialize();
53
}
54
55
void markAnySpecialBranchTargets(TR_J9ByteCode bc)
56
{
57
int32_t i = bcIndex();
58
if (bc == J9BCtableswitch)
59
{
60
int32_t index = defaultTargetIndex();
61
markTarget(i, nextSwitchValue(index));
62
int32_t low = nextSwitchValue(index);
63
int32_t high = nextSwitchValue(index) - low + 1;
64
for (int32_t j = 0; j < high; ++j)
65
markTarget(i, nextSwitchValue(index));
66
}
67
else if (bc == J9BClookupswitch)
68
{
69
int32_t index = defaultTargetIndex();
70
markTarget(i, nextSwitchValue(index));
71
int32_t tableSize = nextSwitchValue(index);
72
for (int32_t j = 0; j < tableSize; ++j)
73
{
74
index += 4; // match value
75
markTarget(i, nextSwitchValue(index));
76
}
77
}
78
}
79
80
void findAndMarkExceptionRanges()
81
{
82
int32_t handlerIndex=0;
83
for (;handlerIndex < method()->numberOfExceptionHandlers(); handlerIndex++)
84
{
85
int32_t start, end, type;
86
int32_t handler = method()->exceptionData(handlerIndex, &start, &end, &type);
87
markExceptionRange(handlerIndex, start, end, handler, type);
88
}
89
90
if (handlerIndex > 0)
91
_methodSymbol->setEHAware();
92
}
93
94
virtual void saveStack(int32_t) = 0;
95
96
void patchPartialInliningCallBack(int32_t slot, TR::SymbolReference *symRef, TR::SymbolReference *tempRef, TR::TreeTop *tt2) //TR::Block *restartBlock)
97
{
98
//printf("patchPartialInliningCallBack. Searching for Children with symref = %p\n",symRef);
99
TR::TreeTop *tt = tt2->getNextRealTreeTop(); //restartBlock->getEntry();
100
TR::Node *ttnode = tt->getNode();
101
TR::Node *callNode = ttnode->getFirstChild();
102
TR::Node *child = NULL;
103
104
for(int32_t i = 0 ; i < callNode->getNumChildren() ; i++)
105
{
106
child = callNode->getChild(i);
107
if(child->getSymbolReference() == symRef)
108
{
109
child->setSymbolReference(tempRef);
110
//printf("patchPartialInliningCallBack: setting Child %d %p symRef %p to tempRef %p\n",i,child,symRef,tempRef);
111
}
112
113
}
114
}
115
void addTempForPartialInliningCallBack(int32_t slot,TR::SymbolReference *tempRef, int32_t numParms)
116
{
117
//printf("addTempForPartialINliningCallBack. (Haven't generated CallBack yet.)\n");
118
119
if(_replacedSymRefs == 0)
120
_replacedSymRefs = new (_compilation->trStackMemory()) TR_Array<TR::SymbolReference*>(_compilation->trMemory(), numParms , true, stackAlloc);
121
122
(*_replacedSymRefs)[slot] = tempRef;
123
124
//printf("addTempForPartialInliningCallBack : _replacedSYmRefs = %p _replacedSymRefs->isEmpty() = %d\n",_replacedSymRefs,_replacedSymRefs->isEmpty());
125
}
126
127
TR::TreeTop *genPartialInliningCallBack(int32_t index, TR::TreeTop *callTreeTop)
128
{
129
// printf("Walker:genPartialInliningCallBack for index %d methodSymbol = %p\n",index, _methodSymbol);
130
genBBStart(index);
131
//printf("\tgenBBStart generated Block %p Block->getNumber %d\n",blocks(index),blocks(index)->getNumber());
132
133
TR::Node *ttNode = TR::Node::create(TR::treetop, 1);
134
TR::Node *callNode =TR::Node::copy(callTreeTop->getNode()->getFirstChild());
135
callNode->setReferenceCount(1);
136
//TR_ASSERT(callNode->getOpCode().isCall(), "node %p isn't a call!\n",callTreeTop->getNode()->getFirstChild());
137
ttNode->setFirst(callNode); //copying callnode. will replace children shortly
138
139
140
ListIterator<TR::ParameterSymbol> li (&_methodSymbol->getParameterList());
141
TR::ParameterSymbol *si = NULL;
142
int32_t i;
143
for(si = li.getFirst(), i=0 ; si != NULL ; si = li.getNext(), i++ )
144
{
145
// printf("si = %p datatype = %d loadOpCode = %d, i = %d, symreftab = %p\n",si, si->getDataType(),_compilation->il.opCodeForDirectLoad(si->getDataType()),i,_compilation->getSymRefTab() );
146
TR::SymbolReference *ref = _compilation->getSymRefTab()->findOrCreateAutoSymbol(_methodSymbol,si->getSlot(),si->getDataType());
147
if(_replacedSymRefs && (*_replacedSymRefs)[si->getSlot()])
148
{
149
ref = (*_replacedSymRefs)[si->getSlot()];
150
//printf("genPartialInliningCallBack: Found a replaced symRef for slot %d\n",si->getSlot());
151
}
152
153
if(callNode->getOpCode().isIndirect() && i==0) // need to generate vft offset & call
154
{
155
TR::Node *thisPointer = TR::Node::createWithSymRef(_compilation->il.opCodeForDirectLoad(si->getDataType()),0,ref);
156
callNode->setAndIncChild(0, TR::Node::createWithSymRef(TR::aloadi, 1, 1, thisPointer, _compilation->getSymRefTab()->findOrCreateVftSymbolRef()));
157
i++;
158
}
159
TR::Node *child = TR::Node::createWithSymRef(_compilation->il.opCodeForDirectLoad(si->getDataType()),0,ref);
160
callNode->setAndIncChild(i,child); //setChild doesn't modify the ref count. setAndIncChild() will properly inc the ref count.
161
}
162
blocks(index)->append(TR::TreeTop::create(_compilation, ttNode));
163
TR::Node *retNode = NULL;
164
if(TR::ILOpCode::returnOpCode(callNode->getDataType()) == TR::Return) //null return?
165
{
166
retNode = TR::Node::create(TR::ILOpCode::returnOpCode(callNode->getDataType()),0);
167
}
168
else
169
{
170
retNode = TR::Node::create(TR::ILOpCode::returnOpCode(callNode->getDataType()),1,callNode);
171
}
172
blocks(index)->append(TR::TreeTop::create(_compilation,retNode));
173
setIsGenerated(index);
174
return blocks(index)->getEntry();
175
}
176
177
TR::TreeTop *genGotoPartialInliningCallBack(int32_t index, TR::TreeTop *gotoTreeTop)
178
{
179
//printf("Walker:genGotoPartialInliningCallBack for index %d\n",index);
180
genBBStart(index);
181
if(!isGenerated(index)) // could also consider blocks(index)->isEmptyBlock()
182
{
183
blocks(index)->append(TR::TreeTop::create(_compilation,TR::Node::create(TR::Goto, 0, gotoTreeTop)));
184
}
185
setIsGenerated(index);
186
return blocks(index)->getEntry();
187
//genTreeTop(TR::Node::create(TR::Goto, 0, genTarget(target)));
188
}
189
190
bool hasExceptionHandlers()
191
{
192
return method()->numberOfExceptionHandlers() > 0;
193
}
194
195
// how many bytes is the given operand stack element's result?
196
int32_t getSize(TR::Node * n)
197
{
198
return n->getSize();
199
}
200
201
// what is the data type of the operand stack element's result?
202
TR::DataType getDataType(TR::Node * n)
203
{
204
return n->getDataType();
205
}
206
207
// how many bytes are used on the operand stack to hold the operand stack element's result?
208
// size of addresses depends on the target platform (32- or 64-bit)
209
//
210
int32_t numberOfByteCodeStackSlots(TR::Node * n)
211
{
212
// note, getSize(TR::Address) = 8 on 64-bit platforms
213
if (getDataType(n) == TR::Address)
214
return 4;
215
else
216
return getSize(n);
217
}
218
219
// duplicate the top two elements of the stack
220
void dup2()
221
{
222
TR::Node * &nWord1 = top();
223
224
if (numberOfByteCodeStackSlots(nWord1) == 4)
225
shift(2,2);// i think this can be just "shift"
226
else
227
shift(1,1);// i think this can be just "shift"
228
}
229
230
void dupx1()
231
{
232
shiftAndCopy(2, 1);
233
}
234
235
void dup2x1()
236
{
237
TR::Node * &nWord1 = node(_stack->topIndex());
238
239
if (numberOfByteCodeStackSlots(nWord1) == 4)
240
{
241
shiftAndCopy(3,2);
242
}
243
else
244
{
245
shiftAndCopy(2,1);
246
}
247
}
248
249
void dupx2()
250
{
251
TR::Node * &nWord2 = node(_stack->topIndex()-1);
252
253
if (numberOfByteCodeStackSlots(nWord2) == 4)
254
{
255
shiftAndCopy(3,1);
256
}
257
else
258
{
259
shiftAndCopy(2,1);
260
}
261
}
262
263
void dup2x2()
264
{
265
TR::Node * &nWord1 = node(_stack->topIndex());
266
267
if (numberOfByteCodeStackSlots(nWord1) == 4)
268
{
269
TR::Node * &nWord3 = node(_stack->topIndex() - 2);
270
271
if (numberOfByteCodeStackSlots(nWord3) == 4)
272
{
273
shiftAndCopy(4,2);
274
}
275
else
276
{
277
shiftAndCopy(3,2);
278
}
279
}
280
else
281
{
282
TR::Node * &nWord2 = node(_stack->topIndex() - 1);
283
284
if (numberOfByteCodeStackSlots(nWord2) == 4)
285
{
286
shiftAndCopy(3,1);
287
}
288
else
289
{
290
shiftAndCopy(2,1);
291
}
292
}
293
}
294
295
TR_Array<TR::SymbolReference *> * _replacedSymRefs; //Partial Inlining
296
};
297
298