hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp
changeset 6187 4fa7845f7c14
child 7397 5b173b4ca846
equal deleted inserted replaced
6186:7eef4cda471c 6187:4fa7845f7c14
       
     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 };