src/cpu/x86/vm/c1_CodeStubs_x86.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:


  84   ce->store_parameter(_method->as_register(), 1);
  85   ce->store_parameter(_bci, 0);
  86   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::counter_overflow_id)));
  87   ce->add_call_info_here(_info);
  88   ce->verify_oop_map(_info);
  89   __ jmp(_continuation);
  90 }
  91 
  92 RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
  93                                bool throw_index_out_of_bounds_exception)
  94   : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
  95   , _index(index)
  96 {
  97   assert(info != NULL, "must have info");
  98   _info = new CodeEmitInfo(info);
  99 }
 100 
 101 
 102 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
 103   __ bind(_entry);








 104   // pass the array index on stack because all registers must be preserved
 105   if (_index->is_cpu_register()) {
 106     ce->store_parameter(_index->as_register(), 0);
 107   } else {
 108     ce->store_parameter(_index->as_jint(), 0);
 109   }
 110   Runtime1::StubID stub_id;
 111   if (_throw_index_out_of_bounds_exception) {
 112     stub_id = Runtime1::throw_index_exception_id;
 113   } else {
 114     stub_id = Runtime1::throw_range_check_failed_id;
 115   }
 116   __ call(RuntimeAddress(Runtime1::entry_for(stub_id)));
 117   ce->add_call_info_here(_info);
 118   debug_only(__ should_not_reach_here());
 119 }
 120 












 121 
 122 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
 123   if (_offset != -1) {
 124     ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
 125   }
 126   __ bind(_entry);
 127   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::throw_div0_exception_id)));
 128   ce->add_call_info_here(_info);
 129   debug_only(__ should_not_reach_here());
 130 }
 131 
 132 
 133 // Implementation of NewInstanceStub
 134 
 135 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) {
 136   _result = result;
 137   _klass = klass;
 138   _klass_reg = klass_reg;
 139   _info = new CodeEmitInfo(info);
 140   assert(stub_id == Runtime1::new_instance_id                 ||


 397   for (int j = __ offset() ; j < jmp_off + 5 ; j++ ) {
 398     __ nop();
 399   }
 400   if (_id == load_klass_id || _id == load_mirror_id) {
 401     CodeSection* cs = __ code_section();
 402     RelocIterator iter(cs, (address)_pc_start, (address)(_pc_start + 1));
 403     relocInfo::change_reloc_info_for_address(&iter, (address) _pc_start, reloc_type, relocInfo::none);
 404   }
 405 }
 406 
 407 
 408 void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
 409   __ bind(_entry);
 410   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::deoptimize_id)));
 411   ce->add_call_info_here(_info);
 412   DEBUG_ONLY(__ should_not_reach_here());
 413 }
 414 
 415 
 416 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {









 417   ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
 418   __ bind(_entry);
 419   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id)));
 420   ce->add_call_info_here(_info);
 421   debug_only(__ should_not_reach_here());
 422 }
 423 
 424 
 425 void SimpleExceptionStub::emit_code(LIR_Assembler* ce) {
 426   assert(__ rsp_offset() == 0, "frame size should be fixed");
 427 
 428   __ bind(_entry);
 429   // pass the object on stack because all registers must be preserved
 430   if (_obj->is_cpu_register()) {
 431     ce->store_parameter(_obj->as_register(), 0);
 432   }
 433   __ call(RuntimeAddress(Runtime1::entry_for(_stub)));
 434   ce->add_call_info_here(_info);
 435   debug_only(__ should_not_reach_here());
 436 }
 437 
 438 
 439 void ArrayCopyStub::emit_code(LIR_Assembler* ce) {




  84   ce->store_parameter(_method->as_register(), 1);
  85   ce->store_parameter(_bci, 0);
  86   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::counter_overflow_id)));
  87   ce->add_call_info_here(_info);
  88   ce->verify_oop_map(_info);
  89   __ jmp(_continuation);
  90 }
  91 
  92 RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
  93                                bool throw_index_out_of_bounds_exception)
  94   : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
  95   , _index(index)
  96 {
  97   assert(info != NULL, "must have info");
  98   _info = new CodeEmitInfo(info);
  99 }
 100 
 101 
 102 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
 103   __ bind(_entry);
 104   if (_info->deoptimize_on_exception()) {
 105     address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
 106     __ call(RuntimeAddress(a));
 107     ce->add_call_info_here(_info);
 108     debug_only(__ should_not_reach_here());
 109     return;
 110   }
 111 
 112   // pass the array index on stack because all registers must be preserved
 113   if (_index->is_cpu_register()) {
 114     ce->store_parameter(_index->as_register(), 0);
 115   } else {
 116     ce->store_parameter(_index->as_jint(), 0);
 117   }
 118   Runtime1::StubID stub_id;
 119   if (_throw_index_out_of_bounds_exception) {
 120     stub_id = Runtime1::throw_index_exception_id;
 121   } else {
 122     stub_id = Runtime1::throw_range_check_failed_id;
 123   }
 124   __ call(RuntimeAddress(Runtime1::entry_for(stub_id)));
 125   ce->add_call_info_here(_info);
 126   debug_only(__ should_not_reach_here());
 127 }
 128 
 129 PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) { 
 130   _info = new CodeEmitInfo(info);
 131 }
 132 
 133 void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
 134   __ bind(_entry); 
 135   address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
 136   __ call(RuntimeAddress(a));
 137   ce->add_call_info_here(_info);
 138   ce->verify_oop_map(_info); 
 139   debug_only(__ should_not_reach_here()); 
 140 }
 141 
 142 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
 143   if (_offset != -1) {
 144     ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
 145   }
 146   __ bind(_entry);
 147   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::throw_div0_exception_id)));
 148   ce->add_call_info_here(_info);
 149   debug_only(__ should_not_reach_here());
 150 }
 151 
 152 
 153 // Implementation of NewInstanceStub
 154 
 155 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) {
 156   _result = result;
 157   _klass = klass;
 158   _klass_reg = klass_reg;
 159   _info = new CodeEmitInfo(info);
 160   assert(stub_id == Runtime1::new_instance_id                 ||


 417   for (int j = __ offset() ; j < jmp_off + 5 ; j++ ) {
 418     __ nop();
 419   }
 420   if (_id == load_klass_id || _id == load_mirror_id) {
 421     CodeSection* cs = __ code_section();
 422     RelocIterator iter(cs, (address)_pc_start, (address)(_pc_start + 1));
 423     relocInfo::change_reloc_info_for_address(&iter, (address) _pc_start, reloc_type, relocInfo::none);
 424   }
 425 }
 426 
 427 
 428 void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
 429   __ bind(_entry);
 430   __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::deoptimize_id)));
 431   ce->add_call_info_here(_info);
 432   DEBUG_ONLY(__ should_not_reach_here());
 433 }
 434 
 435 
 436 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
 437  
 438   address a;
 439   if (_info->deoptimize_on_exception()) {
 440     // Deoptimize, do not throw the exception, because it is probably wrong to do it here.
 441     a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
 442   } else {
 443     a = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id);
 444   }
 445 
 446   ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
 447   __ bind(_entry);
 448   __ call(RuntimeAddress(a));
 449   ce->add_call_info_here(_info);
 450   debug_only(__ should_not_reach_here());
 451 }
 452 
 453 
 454 void SimpleExceptionStub::emit_code(LIR_Assembler* ce) {
 455   assert(__ rsp_offset() == 0, "frame size should be fixed");
 456 
 457   __ bind(_entry);
 458   // pass the object on stack because all registers must be preserved
 459   if (_obj->is_cpu_register()) {
 460     ce->store_parameter(_obj->as_register(), 0);
 461   }
 462   __ call(RuntimeAddress(Runtime1::entry_for(_stub)));
 463   ce->add_call_info_here(_info);
 464   debug_only(__ should_not_reach_here());
 465 }
 466 
 467 
 468 void ArrayCopyStub::emit_code(LIR_Assembler* ce) {