Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp
32285 views
1
/*
2
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3
* Copyright 2008, 2009, 2010 Red Hat, Inc.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*
24
*/
25
26
#ifndef SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP
27
#define SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP
28
29
#include "ci/ciStreams.hpp"
30
#include "ci/ciType.hpp"
31
#include "ci/ciTypeFlow.hpp"
32
#include "interpreter/bytecodes.hpp"
33
#include "memory/allocation.hpp"
34
#include "shark/llvmHeaders.hpp"
35
#include "shark/sharkBlock.hpp"
36
#include "shark/sharkBuilder.hpp"
37
#include "shark/sharkFunction.hpp"
38
#include "shark/sharkState.hpp"
39
#include "shark/sharkValue.hpp"
40
41
class SharkTopLevelBlock : public SharkBlock {
42
public:
43
SharkTopLevelBlock(SharkFunction* function, ciTypeFlow::Block* ciblock)
44
: SharkBlock(function),
45
_function(function),
46
_ciblock(ciblock),
47
_entered(false),
48
_has_trap(false),
49
_needs_phis(false),
50
_entry_state(NULL),
51
_entry_block(NULL) {}
52
53
private:
54
SharkFunction* _function;
55
ciTypeFlow::Block* _ciblock;
56
57
public:
58
SharkFunction* function() const {
59
return _function;
60
}
61
ciTypeFlow::Block* ciblock() const {
62
return _ciblock;
63
}
64
65
// Function properties
66
public:
67
SharkStack* stack() const {
68
return function()->stack();
69
}
70
71
// Typeflow properties
72
public:
73
int index() const {
74
return ciblock()->pre_order();
75
}
76
bool is_backedge_copy() const {
77
return ciblock()->is_backedge_copy();
78
}
79
int stack_depth_at_entry() const {
80
return ciblock()->stack_size();
81
}
82
ciType* local_type_at_entry(int index) const {
83
return ciblock()->local_type_at(index);
84
}
85
ciType* stack_type_at_entry(int slot) const {
86
return ciblock()->stack_type_at(slot);
87
}
88
int start() const {
89
return ciblock()->start();
90
}
91
int limit() const {
92
return ciblock()->limit();
93
}
94
bool falls_through() const {
95
return ciblock()->control() == ciBlock::fall_through_bci;
96
}
97
int num_successors() const {
98
return ciblock()->successors()->length();
99
}
100
SharkTopLevelBlock* successor(int index) const {
101
return function()->block(ciblock()->successors()->at(index)->pre_order());
102
}
103
SharkTopLevelBlock* bci_successor(int bci) const;
104
105
// Exceptions
106
private:
107
GrowableArray<ciExceptionHandler*>* _exc_handlers;
108
GrowableArray<SharkTopLevelBlock*>* _exceptions;
109
110
private:
111
void compute_exceptions();
112
113
private:
114
int num_exceptions() const {
115
return _exc_handlers->length();
116
}
117
ciExceptionHandler* exc_handler(int index) const {
118
return _exc_handlers->at(index);
119
}
120
SharkTopLevelBlock* exception(int index) const {
121
return _exceptions->at(index);
122
}
123
124
// Traps
125
private:
126
bool _has_trap;
127
int _trap_request;
128
int _trap_bci;
129
130
void set_trap(int trap_request, int trap_bci) {
131
assert(!has_trap(), "shouldn't have");
132
_has_trap = true;
133
_trap_request = trap_request;
134
_trap_bci = trap_bci;
135
}
136
137
private:
138
bool has_trap() {
139
return _has_trap;
140
}
141
int trap_request() {
142
assert(has_trap(), "should have");
143
return _trap_request;
144
}
145
int trap_bci() {
146
assert(has_trap(), "should have");
147
return _trap_bci;
148
}
149
150
private:
151
void scan_for_traps();
152
153
private:
154
bool static_field_ok_in_clinit(ciField* field);
155
156
// Entry state
157
private:
158
bool _entered;
159
bool _needs_phis;
160
161
public:
162
bool entered() const {
163
return _entered;
164
}
165
bool needs_phis() const {
166
return _needs_phis;
167
}
168
169
private:
170
void enter(SharkTopLevelBlock* predecessor, bool is_exception);
171
172
public:
173
void enter() {
174
enter(NULL, false);
175
}
176
177
private:
178
SharkState* _entry_state;
179
180
private:
181
SharkState* entry_state();
182
183
private:
184
llvm::BasicBlock* _entry_block;
185
186
public:
187
llvm::BasicBlock* entry_block() const {
188
return _entry_block;
189
}
190
191
public:
192
void initialize();
193
194
public:
195
void add_incoming(SharkState* incoming_state);
196
197
// Method
198
public:
199
llvm::Value* method() {
200
return current_state()->method();
201
}
202
203
// Temporary oop storage
204
public:
205
void set_oop_tmp(llvm::Value* value) {
206
assert(value, "value must be non-NULL (will be reset by get_oop_tmp)");
207
assert(!current_state()->oop_tmp(), "oop_tmp gets and sets must match");
208
current_state()->set_oop_tmp(value);
209
}
210
llvm::Value* get_oop_tmp() {
211
llvm::Value* value = current_state()->oop_tmp();
212
assert(value, "oop_tmp gets and sets must match");
213
current_state()->set_oop_tmp(NULL);
214
return value;
215
}
216
217
// Cache and decache
218
private:
219
void decache_for_Java_call(ciMethod* callee);
220
void cache_after_Java_call(ciMethod* callee);
221
void decache_for_VM_call();
222
void cache_after_VM_call();
223
void decache_for_trap();
224
225
// Monitors
226
private:
227
int num_monitors() {
228
return current_state()->num_monitors();
229
}
230
int set_num_monitors(int num_monitors) {
231
current_state()->set_num_monitors(num_monitors);
232
}
233
234
// Code generation
235
public:
236
void emit_IR();
237
238
// Branch helpers
239
private:
240
void do_branch(int successor_index);
241
242
// Zero checks
243
private:
244
void do_zero_check(SharkValue* value);
245
void zero_check_value(SharkValue* value, llvm::BasicBlock* continue_block);
246
247
public:
248
void do_deferred_zero_check(SharkValue* value,
249
int bci,
250
SharkState* saved_state,
251
llvm::BasicBlock* continue_block);
252
// Exceptions
253
private:
254
llvm::Value* pending_exception_address() const {
255
return builder()->CreateAddressOfStructEntry(
256
thread(), Thread::pending_exception_offset(),
257
llvm::PointerType::getUnqual(SharkType::oop_type()),
258
"pending_exception_addr");
259
}
260
llvm::LoadInst* get_pending_exception() const {
261
return builder()->CreateLoad(
262
pending_exception_address(), "pending_exception");
263
}
264
void clear_pending_exception() const {
265
builder()->CreateStore(LLVMValue::null(), pending_exception_address());
266
}
267
public:
268
enum ExceptionActionMask {
269
// The actual bitmasks that things test against
270
EAM_CHECK = 1, // whether to check for pending exceptions
271
EAM_HANDLE = 2, // whether to attempt to handle pending exceptions
272
EAM_MONITOR_FUDGE = 4, // whether the monitor count needs adjusting
273
274
// More convenient values for passing
275
EX_CHECK_NONE = 0,
276
EX_CHECK_NO_CATCH = EAM_CHECK,
277
EX_CHECK_FULL = EAM_CHECK | EAM_HANDLE
278
};
279
void check_pending_exception(int action);
280
void handle_exception(llvm::Value* exception, int action);
281
void marshal_exception_fast(int num_options);
282
void marshal_exception_slow(int num_options);
283
llvm::BasicBlock* handler_for_exception(int index);
284
285
// VM calls
286
private:
287
llvm::CallInst* call_vm(llvm::Value* callee,
288
llvm::Value** args_start,
289
llvm::Value** args_end,
290
int exception_action) {
291
decache_for_VM_call();
292
stack()->CreateSetLastJavaFrame();
293
llvm::CallInst *res = builder()->CreateCall(callee, llvm::makeArrayRef(args_start, args_end));
294
stack()->CreateResetLastJavaFrame();
295
cache_after_VM_call();
296
if (exception_action & EAM_CHECK) {
297
check_pending_exception(exception_action);
298
current_state()->set_has_safepointed(true);
299
}
300
return res;
301
}
302
303
public:
304
llvm::CallInst* call_vm(llvm::Value* callee,
305
int exception_action) {
306
llvm::Value *args[] = {thread()};
307
return call_vm(callee, args, args + 1, exception_action);
308
}
309
llvm::CallInst* call_vm(llvm::Value* callee,
310
llvm::Value* arg1,
311
int exception_action) {
312
llvm::Value *args[] = {thread(), arg1};
313
return call_vm(callee, args, args + 2, exception_action);
314
}
315
llvm::CallInst* call_vm(llvm::Value* callee,
316
llvm::Value* arg1,
317
llvm::Value* arg2,
318
int exception_action) {
319
llvm::Value *args[] = {thread(), arg1, arg2};
320
return call_vm(callee, args, args + 3, exception_action);
321
}
322
llvm::CallInst* call_vm(llvm::Value* callee,
323
llvm::Value* arg1,
324
llvm::Value* arg2,
325
llvm::Value* arg3,
326
int exception_action) {
327
llvm::Value *args[] = {thread(), arg1, arg2, arg3};
328
return call_vm(callee, args, args + 4, exception_action);
329
}
330
331
// VM call oop return handling
332
private:
333
llvm::LoadInst* get_vm_result() const {
334
llvm::Value *addr = builder()->CreateAddressOfStructEntry(
335
thread(), JavaThread::vm_result_offset(),
336
llvm::PointerType::getUnqual(SharkType::oop_type()),
337
"vm_result_addr");
338
llvm::LoadInst *result = builder()->CreateLoad(addr, "vm_result");
339
builder()->CreateStore(LLVMValue::null(), addr);
340
return result;
341
}
342
343
// Synchronization
344
private:
345
void acquire_lock(llvm::Value* lockee, int exception_action);
346
void release_lock(int exception_action);
347
348
public:
349
void acquire_method_lock();
350
351
// Bounds checks
352
private:
353
void check_bounds(SharkValue* array, SharkValue* index);
354
355
// Safepoints
356
private:
357
void maybe_add_safepoint();
358
void maybe_add_backedge_safepoint();
359
360
// Loop safepoint removal
361
private:
362
bool _can_reach_visited;
363
364
bool can_reach(SharkTopLevelBlock* other);
365
bool can_reach_helper(SharkTopLevelBlock* other);
366
367
// Traps
368
private:
369
llvm::BasicBlock* make_trap(int trap_bci, int trap_request);
370
void do_trap(int trap_request);
371
372
// Returns
373
private:
374
void call_register_finalizer(llvm::Value* receiver);
375
void handle_return(BasicType type, llvm::Value* exception);
376
377
// arraylength
378
private:
379
void do_arraylength();
380
381
// *aload and *astore
382
private:
383
void do_aload(BasicType basic_type);
384
void do_astore(BasicType basic_type);
385
386
// *return and athrow
387
private:
388
void do_return(BasicType type);
389
void do_athrow();
390
391
// goto*
392
private:
393
void do_goto();
394
395
// jsr* and ret
396
private:
397
void do_jsr();
398
void do_ret();
399
400
// if*
401
private:
402
void do_if_helper(llvm::ICmpInst::Predicate p,
403
llvm::Value* b,
404
llvm::Value* a,
405
SharkState* if_taken_state,
406
SharkState* not_taken_state);
407
void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a);
408
409
// tableswitch and lookupswitch
410
private:
411
void do_switch();
412
413
// invoke*
414
private:
415
ciMethod* improve_virtual_call(ciMethod* caller,
416
ciInstanceKlass* klass,
417
ciMethod* dest_method,
418
ciType* receiver_type);
419
llvm::Value* get_direct_callee(ciMethod* method);
420
llvm::Value* get_virtual_callee(SharkValue* receiver, int vtable_index);
421
llvm::Value* get_interface_callee(SharkValue* receiver, ciMethod* method);
422
423
void do_call();
424
425
// checkcast and instanceof
426
private:
427
bool static_subtype_check(ciKlass* check_klass, ciKlass* object_klass);
428
void do_full_instance_check(ciKlass* klass);
429
void do_trapping_instance_check(ciKlass* klass);
430
431
void do_instance_check();
432
bool maybe_do_instanceof_if();
433
434
// new and *newarray
435
private:
436
void do_new();
437
void do_newarray();
438
void do_anewarray();
439
void do_multianewarray();
440
441
// monitorenter and monitorexit
442
private:
443
void do_monitorenter();
444
void do_monitorexit();
445
};
446
447
#endif // SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP
448
449