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 |
|