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:

@@ -49,10 +49,19 @@
 
 
 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
 
+  if (_info->deoptimize_on_exception()) {
+    address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
+    __ call(a, relocInfo::runtime_call_type);
+    __ delayed()->nop();
+    ce->add_call_info_here(_info);
+    debug_only(__ should_not_reach_here());
+    return;
+  }
+
   if (_index->is_register()) {
     __ mov(_index->as_register(), G4);
   } else {
     __ set(_index->as_jint(), G4);
   }

@@ -67,10 +76,23 @@
 #ifdef ASSERT
   __ should_not_reach_here();
 #endif
 }
 
+PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) { 
+  _info = new CodeEmitInfo(info);
+}
+
+void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry); 
+  address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
+  __ call(a, relocInfo::runtime_call_type);
+  __ delayed()->nop();
+  ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info); 
+  debug_only(__ should_not_reach_here()); 
+}
 
 void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
   __ set(_bci, G4);
   __ call(Runtime1::entry_for(Runtime1::counter_overflow_id), relocInfo::runtime_call_type);

@@ -97,14 +119,21 @@
 #endif
 }
 
 
 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
+  address a;
+  if (_info->deoptimize_on_exception()) {
+    // Deoptimize, do not throw the exception, because it is probably wrong to do it here.
+    a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
+  } else {
+    a = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id);
+  }
+
   ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
   __ bind(_entry);
-  __ call(Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id),
-          relocInfo::runtime_call_type);
+  __ call(a, relocInfo::runtime_call_type);
   __ delayed()->nop();
   ce->add_call_info_here(_info);
   ce->verify_oop_map(_info);
 #ifdef ASSERT
   __ should_not_reach_here();