1692
|
1 /*
|
|
2 * Copyright (c) 1999, 2007, 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 class SharkTopLevelBlock : public SharkBlock {
|
|
27 public:
|
|
28 SharkTopLevelBlock(SharkFunction* function, ciTypeFlow::Block* ciblock)
|
|
29 : SharkBlock(function),
|
|
30 _function(function),
|
|
31 _ciblock(ciblock),
|
|
32 _entered(false),
|
|
33 _has_trap(false),
|
|
34 _needs_phis(false),
|
|
35 _entry_state(NULL),
|
|
36 _entry_block(NULL) {}
|
|
37
|
|
38 private:
|
|
39 SharkFunction* _function;
|
|
40 ciTypeFlow::Block* _ciblock;
|
|
41
|
|
42 public:
|
|
43 SharkFunction* function() const {
|
|
44 return _function;
|
|
45 }
|
|
46 ciTypeFlow::Block* ciblock() const {
|
|
47 return _ciblock;
|
|
48 }
|
|
49
|
|
50 // Function properties
|
|
51 public:
|
|
52 SharkStack* stack() const {
|
|
53 return function()->stack();
|
|
54 }
|
|
55
|
|
56 // Typeflow properties
|
|
57 public:
|
|
58 int index() const {
|
|
59 return ciblock()->pre_order();
|
|
60 }
|
|
61 bool is_backedge_copy() const {
|
|
62 return ciblock()->is_backedge_copy();
|
|
63 }
|
|
64 int stack_depth_at_entry() const {
|
|
65 return ciblock()->stack_size();
|
|
66 }
|
|
67 ciType* local_type_at_entry(int index) const {
|
|
68 return ciblock()->local_type_at(index);
|
|
69 }
|
|
70 ciType* stack_type_at_entry(int slot) const {
|
|
71 return ciblock()->stack_type_at(slot);
|
|
72 }
|
|
73 int start() const {
|
|
74 return ciblock()->start();
|
|
75 }
|
|
76 int limit() const {
|
|
77 return ciblock()->limit();
|
|
78 }
|
|
79 bool falls_through() const {
|
|
80 return ciblock()->control() == ciBlock::fall_through_bci;
|
|
81 }
|
|
82 int num_successors() const {
|
|
83 return ciblock()->successors()->length();
|
|
84 }
|
|
85 SharkTopLevelBlock* successor(int index) const {
|
|
86 return function()->block(ciblock()->successors()->at(index)->pre_order());
|
|
87 }
|
|
88 SharkTopLevelBlock* bci_successor(int bci) const;
|
|
89
|
|
90 // Exceptions
|
|
91 private:
|
|
92 GrowableArray<ciExceptionHandler*>* _exc_handlers;
|
|
93 GrowableArray<SharkTopLevelBlock*>* _exceptions;
|
|
94
|
|
95 private:
|
|
96 void compute_exceptions();
|
|
97
|
|
98 private:
|
|
99 int num_exceptions() const {
|
|
100 return _exc_handlers->length();
|
|
101 }
|
|
102 ciExceptionHandler* exc_handler(int index) const {
|
|
103 return _exc_handlers->at(index);
|
|
104 }
|
|
105 SharkTopLevelBlock* exception(int index) const {
|
|
106 return _exceptions->at(index);
|
|
107 }
|
|
108
|
|
109 // Traps
|
|
110 private:
|
|
111 bool _has_trap;
|
|
112 int _trap_request;
|
|
113 int _trap_bci;
|
|
114
|
|
115 void set_trap(int trap_request, int trap_bci) {
|
|
116 assert(!has_trap(), "shouldn't have");
|
|
117 _has_trap = true;
|
|
118 _trap_request = trap_request;
|
|
119 _trap_bci = trap_bci;
|
|
120 }
|
|
121
|
|
122 private:
|
|
123 bool has_trap() {
|
|
124 return _has_trap;
|
|
125 }
|
|
126 int trap_request() {
|
|
127 assert(has_trap(), "should have");
|
|
128 return _trap_request;
|
|
129 }
|
|
130 int trap_bci() {
|
|
131 assert(has_trap(), "should have");
|
|
132 return _trap_bci;
|
|
133 }
|
|
134
|
|
135 private:
|
|
136 void scan_for_traps();
|
|
137
|
|
138 private:
|
|
139 bool static_field_ok_in_clinit(ciField* field);
|
|
140
|
|
141 // Entry state
|
|
142 private:
|
|
143 bool _entered;
|
|
144 bool _needs_phis;
|
|
145
|
|
146 public:
|
|
147 bool entered() const {
|
|
148 return _entered;
|
|
149 }
|
|
150 bool needs_phis() const {
|
|
151 return _needs_phis;
|
|
152 }
|
|
153
|
|
154 private:
|
|
155 void enter(SharkTopLevelBlock* predecessor, bool is_exception);
|
|
156
|
|
157 public:
|
|
158 void enter() {
|
|
159 enter(NULL, false);
|
|
160 }
|
|
161
|
|
162 private:
|
|
163 SharkState* _entry_state;
|
|
164
|
|
165 private:
|
|
166 SharkState* entry_state();
|
|
167
|
|
168 private:
|
|
169 llvm::BasicBlock* _entry_block;
|
|
170
|
|
171 public:
|
|
172 llvm::BasicBlock* entry_block() const {
|
|
173 return _entry_block;
|
|
174 }
|
|
175
|
|
176 public:
|
|
177 void initialize();
|
|
178
|
|
179 public:
|
|
180 void add_incoming(SharkState* incoming_state);
|
|
181
|
|
182 // Method
|
|
183 public:
|
|
184 llvm::Value* method() {
|
|
185 return current_state()->method();
|
|
186 }
|
|
187
|
|
188 // Temporary oop storage
|
|
189 public:
|
|
190 void set_oop_tmp(llvm::Value* value) {
|
|
191 assert(value, "value must be non-NULL (will be reset by get_oop_tmp)");
|
|
192 assert(!current_state()->oop_tmp(), "oop_tmp gets and sets must match");
|
|
193 current_state()->set_oop_tmp(value);
|
|
194 }
|
|
195 llvm::Value* get_oop_tmp() {
|
|
196 llvm::Value* value = current_state()->oop_tmp();
|
|
197 assert(value, "oop_tmp gets and sets must match");
|
|
198 current_state()->set_oop_tmp(NULL);
|
|
199 return value;
|
|
200 }
|
|
201
|
|
202 // Cache and decache
|
|
203 private:
|
|
204 void decache_for_Java_call(ciMethod* callee);
|
|
205 void cache_after_Java_call(ciMethod* callee);
|
|
206 void decache_for_VM_call();
|
|
207 void cache_after_VM_call();
|
|
208 void decache_for_trap();
|
|
209
|
|
210 // Monitors
|
|
211 private:
|
|
212 int num_monitors() {
|
|
213 return current_state()->num_monitors();
|
|
214 }
|
|
215 int set_num_monitors(int num_monitors) {
|
|
216 current_state()->set_num_monitors(num_monitors);
|
|
217 }
|
|
218
|
|
219 // Code generation
|
|
220 public:
|
|
221 void emit_IR();
|
|
222
|
|
223 // Branch helpers
|
|
224 private:
|
|
225 void do_branch(int successor_index);
|
|
226
|
|
227 // Zero checks
|
|
228 private:
|
|
229 void do_zero_check(SharkValue* value);
|
|
230 void zero_check_value(SharkValue* value, llvm::BasicBlock* continue_block);
|
|
231
|
|
232 public:
|
|
233 void do_deferred_zero_check(SharkValue* value,
|
|
234 int bci,
|
|
235 SharkState* saved_state,
|
|
236 llvm::BasicBlock* continue_block);
|
|
237 // Exceptions
|
|
238 private:
|
|
239 llvm::Value* pending_exception_address() const {
|
|
240 return builder()->CreateAddressOfStructEntry(
|
|
241 thread(), Thread::pending_exception_offset(),
|
|
242 llvm::PointerType::getUnqual(SharkType::oop_type()),
|
|
243 "pending_exception_addr");
|
|
244 }
|
|
245 llvm::LoadInst* get_pending_exception() const {
|
|
246 return builder()->CreateLoad(
|
|
247 pending_exception_address(), "pending_exception");
|
|
248 }
|
|
249 void clear_pending_exception() const {
|
|
250 builder()->CreateStore(LLVMValue::null(), pending_exception_address());
|
|
251 }
|
|
252 public:
|
|
253 enum ExceptionActionMask {
|
|
254 // The actual bitmasks that things test against
|
|
255 EAM_CHECK = 1, // whether to check for pending exceptions
|
|
256 EAM_HANDLE = 2, // whether to attempt to handle pending exceptions
|
|
257 EAM_MONITOR_FUDGE = 4, // whether the monitor count needs adjusting
|
|
258
|
|
259 // More convenient values for passing
|
|
260 EX_CHECK_NONE = 0,
|
|
261 EX_CHECK_NO_CATCH = EAM_CHECK,
|
|
262 EX_CHECK_FULL = EAM_CHECK | EAM_HANDLE
|
|
263 };
|
|
264 void check_pending_exception(int action);
|
|
265 void handle_exception(llvm::Value* exception, int action);
|
|
266 void marshal_exception_fast(int num_options);
|
|
267 void marshal_exception_slow(int num_options);
|
|
268 llvm::BasicBlock* handler_for_exception(int index);
|
|
269
|
|
270 // VM calls
|
|
271 private:
|
|
272 llvm::CallInst* call_vm(llvm::Value* callee,
|
|
273 llvm::Value** args_start,
|
|
274 llvm::Value** args_end,
|
|
275 int exception_action) {
|
|
276 decache_for_VM_call();
|
|
277 stack()->CreateSetLastJavaFrame();
|
|
278 llvm::CallInst *res = builder()->CreateCall(callee, args_start, args_end);
|
|
279 stack()->CreateResetLastJavaFrame();
|
|
280 cache_after_VM_call();
|
|
281 if (exception_action & EAM_CHECK) {
|
|
282 check_pending_exception(exception_action);
|
|
283 current_state()->set_has_safepointed(true);
|
|
284 }
|
|
285 return res;
|
|
286 }
|
|
287
|
|
288 public:
|
|
289 llvm::CallInst* call_vm(llvm::Value* callee,
|
|
290 int exception_action) {
|
|
291 llvm::Value *args[] = {thread()};
|
|
292 return call_vm(callee, args, args + 1, exception_action);
|
|
293 }
|
|
294 llvm::CallInst* call_vm(llvm::Value* callee,
|
|
295 llvm::Value* arg1,
|
|
296 int exception_action) {
|
|
297 llvm::Value *args[] = {thread(), arg1};
|
|
298 return call_vm(callee, args, args + 2, exception_action);
|
|
299 }
|
|
300 llvm::CallInst* call_vm(llvm::Value* callee,
|
|
301 llvm::Value* arg1,
|
|
302 llvm::Value* arg2,
|
|
303 int exception_action) {
|
|
304 llvm::Value *args[] = {thread(), arg1, arg2};
|
|
305 return call_vm(callee, args, args + 3, exception_action);
|
|
306 }
|
|
307 llvm::CallInst* call_vm(llvm::Value* callee,
|
|
308 llvm::Value* arg1,
|
|
309 llvm::Value* arg2,
|
|
310 llvm::Value* arg3,
|
|
311 int exception_action) {
|
|
312 llvm::Value *args[] = {thread(), arg1, arg2, arg3};
|
|
313 return call_vm(callee, args, args + 4, exception_action);
|
|
314 }
|
|
315
|
|
316 // VM call oop return handling
|
|
317 private:
|
|
318 llvm::LoadInst* get_vm_result() const {
|
|
319 llvm::Value *addr = builder()->CreateAddressOfStructEntry(
|
|
320 thread(), JavaThread::vm_result_offset(),
|
|
321 llvm::PointerType::getUnqual(SharkType::oop_type()),
|
|
322 "vm_result_addr");
|
|
323 llvm::LoadInst *result = builder()->CreateLoad(addr, "vm_result");
|
|
324 builder()->CreateStore(LLVMValue::null(), addr);
|
|
325 return result;
|
|
326 }
|
|
327
|
|
328 // Synchronization
|
|
329 private:
|
|
330 void acquire_lock(llvm::Value* lockee, int exception_action);
|
|
331 void release_lock(int exception_action);
|
|
332
|
|
333 public:
|
|
334 void acquire_method_lock();
|
|
335
|
|
336 // Bounds checks
|
|
337 private:
|
|
338 void check_bounds(SharkValue* array, SharkValue* index);
|
|
339
|
|
340 // Safepoints
|
|
341 private:
|
|
342 void maybe_add_safepoint();
|
|
343 void maybe_add_backedge_safepoint();
|
|
344
|
|
345 // Loop safepoint removal
|
|
346 private:
|
|
347 bool _can_reach_visited;
|
|
348
|
|
349 bool can_reach(SharkTopLevelBlock* other);
|
|
350 bool can_reach_helper(SharkTopLevelBlock* other);
|
|
351
|
|
352 // Traps
|
|
353 private:
|
|
354 llvm::BasicBlock* make_trap(int trap_bci, int trap_request);
|
|
355 void do_trap(int trap_request);
|
|
356
|
|
357 // Returns
|
|
358 private:
|
|
359 void call_register_finalizer(llvm::Value* receiver);
|
|
360 void handle_return(BasicType type, llvm::Value* exception);
|
|
361
|
|
362 // arraylength
|
|
363 private:
|
|
364 void do_arraylength();
|
|
365
|
|
366 // *aload and *astore
|
|
367 private:
|
|
368 void do_aload(BasicType basic_type);
|
|
369 void do_astore(BasicType basic_type);
|
|
370
|
|
371 // *return and athrow
|
|
372 private:
|
|
373 void do_return(BasicType type);
|
|
374 void do_athrow();
|
|
375
|
|
376 // goto*
|
|
377 private:
|
|
378 void do_goto();
|
|
379
|
|
380 // jsr* and ret
|
|
381 private:
|
|
382 void do_jsr();
|
|
383 void do_ret();
|
|
384
|
|
385 // if*
|
|
386 private:
|
|
387 void do_if_helper(llvm::ICmpInst::Predicate p,
|
|
388 llvm::Value* b,
|
|
389 llvm::Value* a,
|
|
390 SharkState* if_taken_state,
|
|
391 SharkState* not_taken_state);
|
|
392 void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a);
|
|
393
|
|
394 // tableswitch and lookupswitch
|
|
395 private:
|
|
396 void do_switch();
|
|
397
|
|
398 // invoke*
|
|
399 private:
|
|
400 ciMethod* improve_virtual_call(ciMethod* caller,
|
|
401 ciInstanceKlass* klass,
|
|
402 ciMethod* dest_method,
|
|
403 ciType* receiver_type);
|
|
404 llvm::Value* get_direct_callee(ciMethod* method);
|
|
405 llvm::Value* get_virtual_callee(SharkValue* receiver, int vtable_index);
|
|
406 llvm::Value* get_interface_callee(SharkValue* receiver, ciMethod* method);
|
|
407
|
|
408 void do_call();
|
|
409
|
|
410 // checkcast and instanceof
|
|
411 private:
|
|
412 bool static_subtype_check(ciKlass* check_klass, ciKlass* object_klass);
|
|
413 void do_full_instance_check(ciKlass* klass);
|
|
414 void do_trapping_instance_check(ciKlass* klass);
|
|
415
|
|
416 void do_instance_check();
|
|
417 bool maybe_do_instanceof_if();
|
|
418
|
|
419 // new and *newarray
|
|
420 private:
|
|
421 void do_new();
|
|
422 void do_newarray();
|
|
423 void do_anewarray();
|
|
424 void do_multianewarray();
|
|
425
|
|
426 // monitorenter and monitorexit
|
|
427 private:
|
|
428 void do_monitorenter();
|
|
429 void do_monitorexit();
|
|
430 };
|