src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp

Print this page
rev 4136 : 7153771: array bound check elimination for c1
Summary: when possible optimize out array bound checks, inserting predicates when needed.
Reviewed-by:


  34 #include "vmreg_sparc.inline.hpp"
  35 #if INCLUDE_ALL_GCS
  36 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  37 #endif // INCLUDE_ALL_GCS
  38 
  39 #define __ ce->masm()->
  40 
  41 RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
  42                                bool throw_index_out_of_bounds_exception)
  43   : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
  44   , _index(index)
  45 {
  46   assert(info != NULL, "must have info");
  47   _info = new CodeEmitInfo(info);
  48 }
  49 
  50 
  51 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
  52   __ bind(_entry);
  53 









  54   if (_index->is_register()) {
  55     __ mov(_index->as_register(), G4);
  56   } else {
  57     __ set(_index->as_jint(), G4);
  58   }
  59   if (_throw_index_out_of_bounds_exception) {
  60     __ call(Runtime1::entry_for(Runtime1::throw_index_exception_id), relocInfo::runtime_call_type);
  61   } else {
  62     __ call(Runtime1::entry_for(Runtime1::throw_range_check_failed_id), relocInfo::runtime_call_type);
  63   }
  64   __ delayed()->nop();
  65   ce->add_call_info_here(_info);
  66   ce->verify_oop_map(_info);
  67 #ifdef ASSERT
  68   __ should_not_reach_here();
  69 #endif
  70 }
  71 













  72 
  73 void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
  74   __ bind(_entry);
  75   __ set(_bci, G4);
  76   __ call(Runtime1::entry_for(Runtime1::counter_overflow_id), relocInfo::runtime_call_type);
  77   __ delayed()->mov_or_nop(_method->as_register(), G5);
  78   ce->add_call_info_here(_info);
  79   ce->verify_oop_map(_info);
  80 
  81   __ br(Assembler::always, true, Assembler::pt, _continuation);
  82   __ delayed()->nop();
  83 }
  84 
  85 
  86 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
  87   if (_offset != -1) {
  88     ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
  89   }
  90   __ bind(_entry);
  91   __ call(Runtime1::entry_for(Runtime1::throw_div0_exception_id), relocInfo::runtime_call_type);
  92   __ delayed()->nop();
  93   ce->add_call_info_here(_info);
  94   ce->verify_oop_map(_info);
  95 #ifdef ASSERT
  96   __ should_not_reach_here();
  97 #endif
  98 }
  99 
 100 
 101 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {








 102   ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
 103   __ bind(_entry);
 104   __ call(Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id),
 105           relocInfo::runtime_call_type);
 106   __ delayed()->nop();
 107   ce->add_call_info_here(_info);
 108   ce->verify_oop_map(_info);
 109 #ifdef ASSERT
 110   __ should_not_reach_here();
 111 #endif
 112 }
 113 
 114 
 115 // Implementation of SimpleExceptionStub
 116 // Note: %g1 and %g3 are already in use
 117 void SimpleExceptionStub::emit_code(LIR_Assembler* ce) {
 118   __ bind(_entry);
 119   __ call(Runtime1::entry_for(_stub), relocInfo::runtime_call_type);
 120 
 121   if (_obj->is_valid()) {
 122     __ delayed()->mov(_obj->as_register(), G4); // _obj contains the optional argument to the stub
 123   } else {
 124     __ delayed()->mov(G0, G4);
 125   }




  34 #include "vmreg_sparc.inline.hpp"
  35 #if INCLUDE_ALL_GCS
  36 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  37 #endif // INCLUDE_ALL_GCS
  38 
  39 #define __ ce->masm()->
  40 
  41 RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
  42                                bool throw_index_out_of_bounds_exception)
  43   : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
  44   , _index(index)
  45 {
  46   assert(info != NULL, "must have info");
  47   _info = new CodeEmitInfo(info);
  48 }
  49 
  50 
  51 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
  52   __ bind(_entry);
  53 
  54   if (_info->deoptimize_on_exception()) {
  55     address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
  56     __ call(a, relocInfo::runtime_call_type);
  57     __ delayed()->nop();
  58     ce->add_call_info_here(_info);
  59     debug_only(__ should_not_reach_here());
  60     return;
  61   }
  62 
  63   if (_index->is_register()) {
  64     __ mov(_index->as_register(), G4);
  65   } else {
  66     __ set(_index->as_jint(), G4);
  67   }
  68   if (_throw_index_out_of_bounds_exception) {
  69     __ call(Runtime1::entry_for(Runtime1::throw_index_exception_id), relocInfo::runtime_call_type);
  70   } else {
  71     __ call(Runtime1::entry_for(Runtime1::throw_range_check_failed_id), relocInfo::runtime_call_type);
  72   }
  73   __ delayed()->nop();
  74   ce->add_call_info_here(_info);
  75   ce->verify_oop_map(_info);
  76 #ifdef ASSERT
  77   __ should_not_reach_here();
  78 #endif
  79 }
  80 
  81 PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) { 
  82   _info = new CodeEmitInfo(info);
  83 }
  84 
  85 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
  86   __ bind(_entry); 
  87   address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
  88   __ call(a, relocInfo::runtime_call_type);
  89   __ delayed()->nop();
  90   ce->add_call_info_here(_info);
  91   ce->verify_oop_map(_info); 
  92   debug_only(__ should_not_reach_here()); 
  93 }
  94 
  95 void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
  96   __ bind(_entry);
  97   __ set(_bci, G4);
  98   __ call(Runtime1::entry_for(Runtime1::counter_overflow_id), relocInfo::runtime_call_type);
  99   __ delayed()->mov_or_nop(_method->as_register(), G5);
 100   ce->add_call_info_here(_info);
 101   ce->verify_oop_map(_info);
 102 
 103   __ br(Assembler::always, true, Assembler::pt, _continuation);
 104   __ delayed()->nop();
 105 }
 106 
 107 
 108 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
 109   if (_offset != -1) {
 110     ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
 111   }
 112   __ bind(_entry);
 113   __ call(Runtime1::entry_for(Runtime1::throw_div0_exception_id), relocInfo::runtime_call_type);
 114   __ delayed()->nop();
 115   ce->add_call_info_here(_info);
 116   ce->verify_oop_map(_info);
 117 #ifdef ASSERT
 118   __ should_not_reach_here();
 119 #endif
 120 }
 121 
 122 
 123 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
 124   address a;
 125   if (_info->deoptimize_on_exception()) {
 126     // Deoptimize, do not throw the exception, because it is probably wrong to do it here.
 127     a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
 128   } else {
 129     a = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id);
 130   }
 131 
 132   ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
 133   __ bind(_entry);
 134   __ call(a, relocInfo::runtime_call_type);

 135   __ delayed()->nop();
 136   ce->add_call_info_here(_info);
 137   ce->verify_oop_map(_info);
 138 #ifdef ASSERT
 139   __ should_not_reach_here();
 140 #endif
 141 }
 142 
 143 
 144 // Implementation of SimpleExceptionStub
 145 // Note: %g1 and %g3 are already in use
 146 void SimpleExceptionStub::emit_code(LIR_Assembler* ce) {
 147   __ bind(_entry);
 148   __ call(Runtime1::entry_for(_stub), relocInfo::runtime_call_type);
 149 
 150   if (_obj->is_valid()) {
 151     __ delayed()->mov(_obj->as_register(), G4); // _obj contains the optional argument to the stub
 152   } else {
 153     __ delayed()->mov(G0, G4);
 154   }