Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/c1/c1_ValueStack.hpp
40931 views
1
/*
2
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#ifndef SHARE_C1_C1_VALUESTACK_HPP
26
#define SHARE_C1_C1_VALUESTACK_HPP
27
28
#include "c1/c1_Instruction.hpp"
29
30
class ValueStack: public CompilationResourceObj {
31
public:
32
enum Kind {
33
Parsing, // During abstract interpretation in GraphBuilder
34
CallerState, // Caller state when inlining
35
StateBefore, // Before before execution of instruction
36
StateAfter, // After execution of instruction
37
ExceptionState, // Exception handling of instruction
38
EmptyExceptionState, // Exception handling of instructions not covered by an xhandler
39
BlockBeginState // State of BlockBegin instruction with phi functions of this block
40
};
41
42
private:
43
IRScope* _scope; // the enclosing scope
44
ValueStack* _caller_state;
45
int _bci;
46
Kind _kind;
47
48
Values _locals; // the locals
49
Values _stack; // the expression stack
50
Values* _locks; // the monitor stack (holding the locked values)
51
52
Value check(ValueTag tag, Value t) {
53
assert(tag == t->type()->tag() || tag == objectTag && t->type()->tag() == addressTag, "types must correspond");
54
return t;
55
}
56
57
Value check(ValueTag tag, Value t, Value h) {
58
assert(h == NULL, "hi-word of doubleword value must be NULL");
59
return check(tag, t);
60
}
61
62
// helper routine
63
static void apply(const Values& list, ValueVisitor* f);
64
65
// for simplified copying
66
ValueStack(ValueStack* copy_from, Kind kind, int bci);
67
68
int locals_size_for_copy(Kind kind) const;
69
int stack_size_for_copy(Kind kind) const;
70
public:
71
// creation
72
ValueStack(IRScope* scope, ValueStack* caller_state);
73
74
ValueStack* copy() { return new ValueStack(this, _kind, _bci); }
75
ValueStack* copy(Kind new_kind, int new_bci) { return new ValueStack(this, new_kind, new_bci); }
76
ValueStack* copy_for_parsing() { return new ValueStack(this, Parsing, -99); }
77
78
void set_caller_state(ValueStack* s) {
79
assert(kind() == EmptyExceptionState ||
80
(Compilation::current()->env()->should_retain_local_variables() && kind() == ExceptionState),
81
"only EmptyExceptionStates can be modified");
82
_caller_state = s;
83
}
84
85
bool is_same(ValueStack* s); // returns true if this & s's types match (w/o checking locals)
86
87
// accessors
88
IRScope* scope() const { return _scope; }
89
ValueStack* caller_state() const { return _caller_state; }
90
int bci() const { return _bci; }
91
Kind kind() const { return _kind; }
92
93
int locals_size() const { return _locals.length(); }
94
int stack_size() const { return _stack.length(); }
95
int locks_size() const { return _locks == NULL ? 0 : _locks->length(); }
96
bool stack_is_empty() const { return _stack.is_empty(); }
97
bool no_active_locks() const { return _locks == NULL || _locks->is_empty(); }
98
int total_locks_size() const;
99
100
// locals access
101
void clear_locals(); // sets all locals to NULL;
102
103
void invalidate_local(int i) {
104
assert(!_locals.at(i)->type()->is_double_word() ||
105
_locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL");
106
_locals.at_put(i, NULL);
107
}
108
109
Value local_at(int i) const {
110
Value x = _locals.at(i);
111
assert(x == NULL || !x->type()->is_double_word() ||
112
_locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL");
113
return x;
114
}
115
116
void store_local(int i, Value x) {
117
// When overwriting local i, check if i - 1 was the start of a
118
// double word local and kill it.
119
if (i > 0) {
120
Value prev = _locals.at(i - 1);
121
if (prev != NULL && prev->type()->is_double_word()) {
122
_locals.at_put(i - 1, NULL);
123
}
124
}
125
126
_locals.at_put(i, x);
127
if (x->type()->is_double_word()) {
128
// hi-word of doubleword value is always NULL
129
_locals.at_put(i + 1, NULL);
130
}
131
}
132
133
// stack access
134
Value stack_at(int i) const {
135
Value x = _stack.at(i);
136
assert(!x->type()->is_double_word() ||
137
_stack.at(i + 1) == NULL, "hi-word of doubleword value must be NULL");
138
return x;
139
}
140
141
Value stack_at_inc(int& i) const {
142
Value x = stack_at(i);
143
i += x->type()->size();
144
return x;
145
}
146
147
void stack_at_put(int i, Value x) {
148
_stack.at_put(i, x);
149
}
150
151
// pinning support
152
void pin_stack_for_linear_scan();
153
154
// iteration
155
void values_do(ValueVisitor* f);
156
157
// untyped manipulation (for dup_x1, etc.)
158
void truncate_stack(int size) { _stack.trunc_to(size); }
159
void raw_push(Value t) { _stack.push(t); }
160
Value raw_pop() { return _stack.pop(); }
161
162
// typed manipulation
163
void ipush(Value t) { _stack.push(check(intTag , t)); }
164
void fpush(Value t) { _stack.push(check(floatTag , t)); }
165
void apush(Value t) { _stack.push(check(objectTag , t)); }
166
void rpush(Value t) { _stack.push(check(addressTag, t)); }
167
void lpush(Value t) { _stack.push(check(longTag , t)); _stack.push(NULL); }
168
void dpush(Value t) { _stack.push(check(doubleTag , t)); _stack.push(NULL); }
169
170
void push(ValueType* type, Value t) {
171
switch (type->tag()) {
172
case intTag : ipush(t); return;
173
case longTag : lpush(t); return;
174
case floatTag : fpush(t); return;
175
case doubleTag : dpush(t); return;
176
case objectTag : apush(t); return;
177
case addressTag: rpush(t); return;
178
default : ShouldNotReachHere(); return;
179
}
180
}
181
182
Value ipop() { return check(intTag , _stack.pop()); }
183
Value fpop() { return check(floatTag , _stack.pop()); }
184
Value apop() { return check(objectTag , _stack.pop()); }
185
Value rpop() { return check(addressTag, _stack.pop()); }
186
Value lpop() { Value h = _stack.pop(); return check(longTag , _stack.pop(), h); }
187
Value dpop() { Value h = _stack.pop(); return check(doubleTag, _stack.pop(), h); }
188
189
Value pop(ValueType* type) {
190
switch (type->tag()) {
191
case intTag : return ipop();
192
case longTag : return lpop();
193
case floatTag : return fpop();
194
case doubleTag : return dpop();
195
case objectTag : return apop();
196
case addressTag: return rpop();
197
default : ShouldNotReachHere(); return NULL;
198
}
199
}
200
201
Values* pop_arguments(int argument_size);
202
203
// locks access
204
int lock (Value obj);
205
int unlock();
206
Value lock_at(int i) const { return _locks->at(i); }
207
208
// SSA form IR support
209
void setup_phi_for_stack(BlockBegin* b, int index);
210
void setup_phi_for_local(BlockBegin* b, int index);
211
212
// debugging
213
void print() PRODUCT_RETURN;
214
void verify() PRODUCT_RETURN;
215
};
216
217
218
219
// Macro definitions for simple iteration of stack and local values of a ValueStack
220
// The macros can be used like a for-loop. All variables (state, index and value)
221
// must be defined before the loop.
222
// When states are nested because of inlining, the stack of the innermost state
223
// cumulates also the stack of the nested states. In contrast, the locals of all
224
// states must be iterated each.
225
// Use the following code pattern to iterate all stack values and all nested local values:
226
//
227
// ValueStack* state = ... // state that is iterated
228
// int index; // current loop index (overwritten in loop)
229
// Value value; // value at current loop index (overwritten in loop)
230
//
231
// for_each_stack_value(state, index, value {
232
// do something with value and index
233
// }
234
//
235
// for_each_state(state) {
236
// for_each_local_value(state, index, value) {
237
// do something with value and index
238
// }
239
// }
240
// as an invariant, state is NULL now
241
242
243
// construct a unique variable name with the line number where the macro is used
244
#define temp_var3(x) temp__ ## x
245
#define temp_var2(x) temp_var3(x)
246
#define temp_var temp_var2(__LINE__)
247
248
#define for_each_state(state) \
249
for (; state != NULL; state = state->caller_state())
250
251
#define for_each_local_value(state, index, value) \
252
int temp_var = state->locals_size(); \
253
for (index = 0; \
254
index < temp_var && (value = state->local_at(index), true); \
255
index += (value == NULL || value->type()->is_illegal() ? 1 : value->type()->size())) \
256
if (value != NULL)
257
258
259
#define for_each_stack_value(state, index, value) \
260
int temp_var = state->stack_size(); \
261
for (index = 0; \
262
index < temp_var && (value = state->stack_at(index), true); \
263
index += value->type()->size())
264
265
266
#define for_each_lock_value(state, index, value) \
267
int temp_var = state->locks_size(); \
268
for (index = 0; \
269
index < temp_var && (value = state->lock_at(index), true); \
270
index++) \
271
if (value != NULL)
272
273
274
// Macro definition for simple iteration of all state values of a ValueStack
275
// Because the code cannot be executed in a single loop, the code must be passed
276
// as a macro parameter.
277
// Use the following code pattern to iterate all stack values and all nested local values:
278
//
279
// ValueStack* state = ... // state that is iterated
280
// for_each_state_value(state, value,
281
// do something with value (note that this is a macro parameter)
282
// );
283
284
#define for_each_state_value(v_state, v_value, v_code) \
285
{ \
286
int cur_index; \
287
ValueStack* cur_state = v_state; \
288
Value v_value; \
289
for_each_state(cur_state) { \
290
{ \
291
for_each_local_value(cur_state, cur_index, v_value) { \
292
v_code; \
293
} \
294
} \
295
{ \
296
for_each_stack_value(cur_state, cur_index, v_value) { \
297
v_code; \
298
} \
299
} \
300
} \
301
}
302
303
304
// Macro definition for simple iteration of all phi functions of a block, i.e all
305
// phi functions of the ValueStack where the block matches.
306
// Use the following code pattern to iterate all phi functions of a block:
307
//
308
// BlockBegin* block = ... // block that is iterated
309
// for_each_phi_function(block, phi,
310
// do something with the phi function phi (note that this is a macro parameter)
311
// );
312
313
#define for_each_phi_fun(v_block, v_phi, v_code) \
314
{ \
315
int cur_index; \
316
ValueStack* cur_state = v_block->state(); \
317
Value value; \
318
{ \
319
for_each_stack_value(cur_state, cur_index, value) { \
320
Phi* v_phi = value->as_Phi(); \
321
if (v_phi != NULL && v_phi->block() == v_block) { \
322
v_code; \
323
} \
324
} \
325
} \
326
{ \
327
for_each_local_value(cur_state, cur_index, value) { \
328
Phi* v_phi = value->as_Phi(); \
329
if (v_phi != NULL && v_phi->block() == v_block) { \
330
v_code; \
331
} \
332
} \
333
} \
334
}
335
336
#endif // SHARE_C1_C1_VALUESTACK_HPP
337
338