hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
changeset 1 489c9b5090e2
child 1374 4c24294029a9
equal deleted inserted replaced
0:fd16c54261b3 1:489c9b5090e2
       
     1 /*
       
     2  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "incls/_precompiled.incl"
       
    26 #include "incls/_c1_CodeStubs_sparc.cpp.incl"
       
    27 
       
    28 #define __ ce->masm()->
       
    29 
       
    30 RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
       
    31                                bool throw_index_out_of_bounds_exception)
       
    32   : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
       
    33   , _index(index)
       
    34 {
       
    35   _info = new CodeEmitInfo(info);
       
    36 }
       
    37 
       
    38 
       
    39 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
       
    40   __ bind(_entry);
       
    41 
       
    42   if (_index->is_register()) {
       
    43     __ mov(_index->as_register(), G4);
       
    44   } else {
       
    45     __ set(_index->as_jint(), G4);
       
    46   }
       
    47   if (_throw_index_out_of_bounds_exception) {
       
    48     __ call(Runtime1::entry_for(Runtime1::throw_index_exception_id), relocInfo::runtime_call_type);
       
    49   } else {
       
    50     __ call(Runtime1::entry_for(Runtime1::throw_range_check_failed_id), relocInfo::runtime_call_type);
       
    51   }
       
    52   __ delayed()->nop();
       
    53   ce->add_call_info_here(_info);
       
    54   ce->verify_oop_map(_info);
       
    55 #ifdef ASSERT
       
    56   __ should_not_reach_here();
       
    57 #endif
       
    58 }
       
    59 
       
    60 #ifdef TIERED
       
    61 
       
    62 void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
       
    63   __ bind(_entry);
       
    64   __ set(_bci, G4);
       
    65   __ call(Runtime1::entry_for(Runtime1::counter_overflow_id), relocInfo::runtime_call_type);
       
    66   __ delayed()->nop();
       
    67   ce->add_call_info_here(_info);
       
    68   ce->verify_oop_map(_info);
       
    69 
       
    70   __ br(Assembler::always, true, Assembler::pt, _continuation);
       
    71   __ delayed()->nop();
       
    72 }
       
    73 
       
    74 #endif // TIERED
       
    75 
       
    76 void DivByZeroStub::emit_code(LIR_Assembler* ce) {
       
    77   if (_offset != -1) {
       
    78     ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
       
    79   }
       
    80   __ bind(_entry);
       
    81   __ call(Runtime1::entry_for(Runtime1::throw_div0_exception_id), relocInfo::runtime_call_type);
       
    82   __ delayed()->nop();
       
    83   ce->add_call_info_here(_info);
       
    84   ce->verify_oop_map(_info);
       
    85 #ifdef ASSERT
       
    86   __ should_not_reach_here();
       
    87 #endif
       
    88 }
       
    89 
       
    90 
       
    91 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
       
    92   ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
       
    93   __ bind(_entry);
       
    94   __ call(Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id),
       
    95           relocInfo::runtime_call_type);
       
    96   __ delayed()->nop();
       
    97   ce->add_call_info_here(_info);
       
    98   ce->verify_oop_map(_info);
       
    99 #ifdef ASSERT
       
   100   __ should_not_reach_here();
       
   101 #endif
       
   102 }
       
   103 
       
   104 
       
   105 // Implementation of SimpleExceptionStub
       
   106 // Note: %g1 and %g3 are already in use
       
   107 void SimpleExceptionStub::emit_code(LIR_Assembler* ce) {
       
   108   __ bind(_entry);
       
   109   __ call(Runtime1::entry_for(_stub), relocInfo::runtime_call_type);
       
   110 
       
   111   if (_obj->is_valid()) {
       
   112     __ delayed()->mov(_obj->as_register(), G4); // _obj contains the optional argument to the stub
       
   113   } else {
       
   114     __ delayed()->mov(G0, G4);
       
   115   }
       
   116   ce->add_call_info_here(_info);
       
   117 #ifdef ASSERT
       
   118   __ should_not_reach_here();
       
   119 #endif
       
   120 }
       
   121 
       
   122 
       
   123 // Implementation of ArrayStoreExceptionStub
       
   124 
       
   125 ArrayStoreExceptionStub::ArrayStoreExceptionStub(CodeEmitInfo* info):
       
   126   _info(info) {
       
   127 }
       
   128 
       
   129 
       
   130 void ArrayStoreExceptionStub::emit_code(LIR_Assembler* ce) {
       
   131   __ bind(_entry);
       
   132   __ call(Runtime1::entry_for(Runtime1::throw_array_store_exception_id), relocInfo::runtime_call_type);
       
   133   __ delayed()->nop();
       
   134   ce->add_call_info_here(_info);
       
   135   ce->verify_oop_map(_info);
       
   136 #ifdef ASSERT
       
   137   __ should_not_reach_here();
       
   138 #endif
       
   139 }
       
   140 
       
   141 
       
   142 
       
   143 
       
   144 // Implementation of NewInstanceStub
       
   145 
       
   146 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) {
       
   147   _result = result;
       
   148   _klass = klass;
       
   149   _klass_reg = klass_reg;
       
   150   _info = new CodeEmitInfo(info);
       
   151   assert(stub_id == Runtime1::new_instance_id                 ||
       
   152          stub_id == Runtime1::fast_new_instance_id            ||
       
   153          stub_id == Runtime1::fast_new_instance_init_check_id,
       
   154          "need new_instance id");
       
   155   _stub_id   = stub_id;
       
   156 }
       
   157 
       
   158 
       
   159 void NewInstanceStub::emit_code(LIR_Assembler* ce) {
       
   160   __ bind(_entry);
       
   161   __ call(Runtime1::entry_for(_stub_id), relocInfo::runtime_call_type);
       
   162   __ delayed()->mov_or_nop(_klass_reg->as_register(), G5);
       
   163   ce->add_call_info_here(_info);
       
   164   ce->verify_oop_map(_info);
       
   165   __ br(Assembler::always, false, Assembler::pt, _continuation);
       
   166   __ delayed()->mov_or_nop(O0, _result->as_register());
       
   167 }
       
   168 
       
   169 
       
   170 // Implementation of NewTypeArrayStub
       
   171 NewTypeArrayStub::NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
       
   172   _klass_reg = klass_reg;
       
   173   _length = length;
       
   174   _result = result;
       
   175   _info = new CodeEmitInfo(info);
       
   176 }
       
   177 
       
   178 
       
   179 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
       
   180   __ bind(_entry);
       
   181 
       
   182   __ mov(_length->as_register(), G4);
       
   183   __ call(Runtime1::entry_for(Runtime1::new_type_array_id), relocInfo::runtime_call_type);
       
   184   __ delayed()->mov_or_nop(_klass_reg->as_register(), G5);
       
   185   ce->add_call_info_here(_info);
       
   186   ce->verify_oop_map(_info);
       
   187   __ br(Assembler::always, false, Assembler::pt, _continuation);
       
   188   __ delayed()->mov_or_nop(O0, _result->as_register());
       
   189 }
       
   190 
       
   191 
       
   192 // Implementation of NewObjectArrayStub
       
   193 
       
   194 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
       
   195   _klass_reg = klass_reg;
       
   196   _length = length;
       
   197   _result = result;
       
   198   _info = new CodeEmitInfo(info);
       
   199 }
       
   200 
       
   201 
       
   202 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
       
   203   __ bind(_entry);
       
   204 
       
   205   __ mov(_length->as_register(), G4);
       
   206   __ call(Runtime1::entry_for(Runtime1::new_object_array_id), relocInfo::runtime_call_type);
       
   207   __ delayed()->mov_or_nop(_klass_reg->as_register(), G5);
       
   208   ce->add_call_info_here(_info);
       
   209   ce->verify_oop_map(_info);
       
   210   __ br(Assembler::always, false, Assembler::pt, _continuation);
       
   211   __ delayed()->mov_or_nop(O0, _result->as_register());
       
   212 }
       
   213 
       
   214 
       
   215 // Implementation of MonitorAccessStubs
       
   216 MonitorEnterStub::MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info)
       
   217   : MonitorAccessStub(obj_reg, lock_reg) {
       
   218   _info = new CodeEmitInfo(info);
       
   219 }
       
   220 
       
   221 
       
   222 void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
       
   223   __ bind(_entry);
       
   224   __ mov(_obj_reg->as_register(), G4);
       
   225   if (ce->compilation()->has_fpu_code()) {
       
   226     __ call(Runtime1::entry_for(Runtime1::monitorenter_id), relocInfo::runtime_call_type);
       
   227   } else {
       
   228     __ call(Runtime1::entry_for(Runtime1::monitorenter_nofpu_id), relocInfo::runtime_call_type);
       
   229   }
       
   230   __ delayed()->mov_or_nop(_lock_reg->as_register(), G5);
       
   231   ce->add_call_info_here(_info);
       
   232   ce->verify_oop_map(_info);
       
   233   __ br(Assembler::always, true, Assembler::pt, _continuation);
       
   234   __ delayed()->nop();
       
   235 }
       
   236 
       
   237 
       
   238 void MonitorExitStub::emit_code(LIR_Assembler* ce) {
       
   239   __ bind(_entry);
       
   240   if (_compute_lock) {
       
   241     ce->monitor_address(_monitor_ix, _lock_reg);
       
   242   }
       
   243   if (ce->compilation()->has_fpu_code()) {
       
   244     __ call(Runtime1::entry_for(Runtime1::monitorexit_id), relocInfo::runtime_call_type);
       
   245   } else {
       
   246     __ call(Runtime1::entry_for(Runtime1::monitorexit_nofpu_id), relocInfo::runtime_call_type);
       
   247   }
       
   248 
       
   249   __ delayed()->mov_or_nop(_lock_reg->as_register(), G4);
       
   250   __ br(Assembler::always, true, Assembler::pt, _continuation);
       
   251   __ delayed()->nop();
       
   252 }
       
   253 
       
   254 // Implementation of patching:
       
   255 // - Copy the code at given offset to an inlined buffer (first the bytes, then the number of bytes)
       
   256 // - Replace original code with a call to the stub
       
   257 // At Runtime:
       
   258 // - call to stub, jump to runtime
       
   259 // - in runtime: preserve all registers (especially objects, i.e., source and destination object)
       
   260 // - in runtime: after initializing class, restore original code, reexecute instruction
       
   261 
       
   262 int PatchingStub::_patch_info_offset = -NativeGeneralJump::instruction_size;
       
   263 
       
   264 void PatchingStub::align_patch_site(MacroAssembler* ) {
       
   265   // patch sites on sparc are always properly aligned.
       
   266 }
       
   267 
       
   268 void PatchingStub::emit_code(LIR_Assembler* ce) {
       
   269   // copy original code here
       
   270   assert(NativeCall::instruction_size <= _bytes_to_copy && _bytes_to_copy <= 0xFF,
       
   271          "not enough room for call");
       
   272   assert((_bytes_to_copy & 0x3) == 0, "must copy a multiple of four bytes");
       
   273 
       
   274   Label call_patch;
       
   275 
       
   276   int being_initialized_entry = __ offset();
       
   277 
       
   278   if (_id == load_klass_id) {
       
   279     // produce a copy of the load klass instruction for use by the being initialized case
       
   280     address start = __ pc();
       
   281     Address addr = Address(_obj, address(NULL), oop_Relocation::spec(_oop_index));
       
   282     __ sethi(addr, true);
       
   283     __ add(addr, _obj, 0);
       
   284 
       
   285 #ifdef ASSERT
       
   286     for (int i = 0; i < _bytes_to_copy; i++) {
       
   287       address ptr = (address)(_pc_start + i);
       
   288       int a_byte = (*ptr) & 0xFF;
       
   289       assert(a_byte == *start++, "should be the same code");
       
   290     }
       
   291 #endif
       
   292   } else {
       
   293     // make a copy the code which is going to be patched.
       
   294     for (int i = 0; i < _bytes_to_copy; i++) {
       
   295       address ptr = (address)(_pc_start + i);
       
   296       int a_byte = (*ptr) & 0xFF;
       
   297       __ a_byte (a_byte);
       
   298     }
       
   299   }
       
   300 
       
   301   address end_of_patch = __ pc();
       
   302   int bytes_to_skip = 0;
       
   303   if (_id == load_klass_id) {
       
   304     int offset = __ offset();
       
   305     if (CommentedAssembly) {
       
   306       __ block_comment(" being_initialized check");
       
   307     }
       
   308 
       
   309     // static field accesses have special semantics while the class
       
   310     // initializer is being run so we emit a test which can be used to
       
   311     // check that this code is being executed by the initializing
       
   312     // thread.
       
   313     assert(_obj != noreg, "must be a valid register");
       
   314     assert(_oop_index >= 0, "must have oop index");
       
   315     __ ld_ptr(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
       
   316     __ cmp(G2_thread, G3);
       
   317     __ br(Assembler::notEqual, false, Assembler::pn, call_patch);
       
   318     __ delayed()->nop();
       
   319 
       
   320     // load_klass patches may execute the patched code before it's
       
   321     // copied back into place so we need to jump back into the main
       
   322     // code of the nmethod to continue execution.
       
   323     __ br(Assembler::always, false, Assembler::pt, _patch_site_continuation);
       
   324     __ delayed()->nop();
       
   325 
       
   326     // make sure this extra code gets skipped
       
   327     bytes_to_skip += __ offset() - offset;
       
   328   }
       
   329 
       
   330   // Now emit the patch record telling the runtime how to find the
       
   331   // pieces of the patch.  We only need 3 bytes but it has to be
       
   332   // aligned as an instruction so emit 4 bytes.
       
   333   int sizeof_patch_record = 4;
       
   334   bytes_to_skip += sizeof_patch_record;
       
   335 
       
   336   // emit the offsets needed to find the code to patch
       
   337   int being_initialized_entry_offset = __ offset() - being_initialized_entry + sizeof_patch_record;
       
   338 
       
   339   // Emit the patch record.  We need to emit a full word, so emit an extra empty byte
       
   340   __ a_byte(0);
       
   341   __ a_byte(being_initialized_entry_offset);
       
   342   __ a_byte(bytes_to_skip);
       
   343   __ a_byte(_bytes_to_copy);
       
   344   address patch_info_pc = __ pc();
       
   345   assert(patch_info_pc - end_of_patch == bytes_to_skip, "incorrect patch info");
       
   346 
       
   347   address entry = __ pc();
       
   348   NativeGeneralJump::insert_unconditional((address)_pc_start, entry);
       
   349   address target = NULL;
       
   350   switch (_id) {
       
   351     case access_field_id:  target = Runtime1::entry_for(Runtime1::access_field_patching_id); break;
       
   352     case load_klass_id:    target = Runtime1::entry_for(Runtime1::load_klass_patching_id); break;
       
   353     default: ShouldNotReachHere();
       
   354   }
       
   355   __ bind(call_patch);
       
   356 
       
   357   if (CommentedAssembly) {
       
   358     __ block_comment("patch entry point");
       
   359   }
       
   360   __ call(target, relocInfo::runtime_call_type);
       
   361   __ delayed()->nop();
       
   362   assert(_patch_info_offset == (patch_info_pc - __ pc()), "must not change");
       
   363   ce->add_call_info_here(_info);
       
   364   __ br(Assembler::always, false, Assembler::pt, _patch_site_entry);
       
   365   __ delayed()->nop();
       
   366   if (_id == load_klass_id) {
       
   367     CodeSection* cs = __ code_section();
       
   368     address pc = (address)_pc_start;
       
   369     RelocIterator iter(cs, pc, pc + 1);
       
   370     relocInfo::change_reloc_info_for_address(&iter, (address) pc, relocInfo::oop_type, relocInfo::none);
       
   371 
       
   372     pc = (address)(_pc_start + NativeMovConstReg::add_offset);
       
   373     RelocIterator iter2(cs, pc, pc+1);
       
   374     relocInfo::change_reloc_info_for_address(&iter2, (address) pc, relocInfo::oop_type, relocInfo::none);
       
   375   }
       
   376 
       
   377 }
       
   378 
       
   379 void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
       
   380   //---------------slow case: call to native-----------------
       
   381   __ bind(_entry);
       
   382   __ mov(src()->as_register(),     O0);
       
   383   __ mov(src_pos()->as_register(), O1);
       
   384   __ mov(dst()->as_register(),     O2);
       
   385   __ mov(dst_pos()->as_register(), O3);
       
   386   __ mov(length()->as_register(),  O4);
       
   387 
       
   388   ce->emit_static_call_stub();
       
   389 
       
   390   __ call(SharedRuntime::get_resolve_static_call_stub(), relocInfo::static_call_type);
       
   391   __ delayed()->nop();
       
   392   ce->add_call_info_here(info());
       
   393   ce->verify_oop_map(info());
       
   394 
       
   395 #ifndef PRODUCT
       
   396   __ set((intptr_t)&Runtime1::_arraycopy_slowcase_cnt, O0);
       
   397   __ ld(O0, 0, O1);
       
   398   __ inc(O1);
       
   399   __ st(O1, 0, O0);
       
   400 #endif
       
   401 
       
   402   __ br(Assembler::always, false, Assembler::pt, _continuation);
       
   403   __ delayed()->nop();
       
   404 }
       
   405 
       
   406 
       
   407 #undef __