src/share/vm/shark/sharkTopLevelBlock.hpp

Tue, 08 Aug 2017 15:57:29 +0800

author
aoqi
date
Tue, 08 Aug 2017 15:57:29 +0800
changeset 6876
710a3c8b516e
parent 4314
2cd5e15048e6
parent 0
f90c822e73f8
permissions
-rw-r--r--

merge

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

mercurial