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