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