src/share/vm/shark/sharkTopLevelBlock.hpp

Mon, 04 Apr 2011 03:02:00 -0700

author
twisti
date
Mon, 04 Apr 2011 03:02:00 -0700
changeset 2729
e863062e521d
parent 2314
f95d63e2154a
child 4314
2cd5e15048e6
permissions
-rw-r--r--

7032458: Zero and Shark fixes
Reviewed-by: twisti
Contributed-by: Gary Benson <gbenson@redhat.com>

     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  */
    26 #ifndef SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP
    27 #define SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP
    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"
    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) {}
    53  private:
    54   SharkFunction*     _function;
    55   ciTypeFlow::Block* _ciblock;
    57  public:
    58   SharkFunction* function() const {
    59     return _function;
    60   }
    61   ciTypeFlow::Block* ciblock() const {
    62     return _ciblock;
    63   }
    65   // Function properties
    66  public:
    67   SharkStack* stack() const {
    68     return function()->stack();
    69   }
    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;
   105   // Exceptions
   106  private:
   107   GrowableArray<ciExceptionHandler*>* _exc_handlers;
   108   GrowableArray<SharkTopLevelBlock*>* _exceptions;
   110  private:
   111   void compute_exceptions();
   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   }
   124   // Traps
   125  private:
   126   bool _has_trap;
   127   int  _trap_request;
   128   int  _trap_bci;
   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   }
   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   }
   150  private:
   151   void scan_for_traps();
   153  private:
   154   bool static_field_ok_in_clinit(ciField* field);
   156   // Entry state
   157  private:
   158   bool _entered;
   159   bool _needs_phis;
   161  public:
   162   bool entered() const {
   163     return _entered;
   164   }
   165   bool needs_phis() const {
   166     return _needs_phis;
   167   }
   169  private:
   170   void enter(SharkTopLevelBlock* predecessor, bool is_exception);
   172  public:
   173   void enter() {
   174     enter(NULL, false);
   175   }
   177  private:
   178   SharkState* _entry_state;
   180  private:
   181   SharkState* entry_state();
   183  private:
   184   llvm::BasicBlock* _entry_block;
   186  public:
   187   llvm::BasicBlock* entry_block() const {
   188     return _entry_block;
   189   }
   191  public:
   192   void initialize();
   194  public:
   195   void add_incoming(SharkState* incoming_state);
   197   // Method
   198  public:
   199   llvm::Value* method() {
   200     return current_state()->method();
   201   }
   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   }
   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();
   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   }
   234   // Code generation
   235  public:
   236   void emit_IR();
   238   // Branch helpers
   239  private:
   240   void do_branch(int successor_index);
   242   // Zero checks
   243  private:
   244   void do_zero_check(SharkValue* value);
   245   void zero_check_value(SharkValue* value, llvm::BasicBlock* continue_block);
   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
   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);
   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, 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   }
   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   }
   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   }
   343   // Synchronization
   344  private:
   345   void acquire_lock(llvm::Value* lockee, int exception_action);
   346   void release_lock(int exception_action);
   348  public:
   349   void acquire_method_lock();
   351   // Bounds checks
   352  private:
   353   void check_bounds(SharkValue* array, SharkValue* index);
   355   // Safepoints
   356  private:
   357   void maybe_add_safepoint();
   358   void maybe_add_backedge_safepoint();
   360   // Loop safepoint removal
   361  private:
   362   bool _can_reach_visited;
   364   bool can_reach(SharkTopLevelBlock* other);
   365   bool can_reach_helper(SharkTopLevelBlock* other);
   367   // Traps
   368  private:
   369   llvm::BasicBlock* make_trap(int trap_bci, int trap_request);
   370   void do_trap(int trap_request);
   372   // Returns
   373  private:
   374   void call_register_finalizer(llvm::Value* receiver);
   375   void handle_return(BasicType type, llvm::Value* exception);
   377   // arraylength
   378  private:
   379   void do_arraylength();
   381   // *aload and *astore
   382  private:
   383   void do_aload(BasicType basic_type);
   384   void do_astore(BasicType basic_type);
   386   // *return and athrow
   387  private:
   388   void do_return(BasicType type);
   389   void do_athrow();
   391   // goto*
   392  private:
   393   void do_goto();
   395   // jsr* and ret
   396  private:
   397   void do_jsr();
   398   void do_ret();
   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);
   409   // tableswitch and lookupswitch
   410  private:
   411   void do_switch();
   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);
   423   void do_call();
   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);
   431   void do_instance_check();
   432   bool maybe_do_instanceof_if();
   434   // new and *newarray
   435  private:
   436   void do_new();
   437   void do_newarray();
   438   void do_anewarray();
   439   void do_multianewarray();
   441   // monitorenter and monitorexit
   442  private:
   443   void do_monitorenter();
   444   void do_monitorexit();
   445 };
   447 #endif // SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP

mercurial