Mercurial > hg > truffle
comparison src/cpu/sparc/vm/templateTable_sparc.cpp @ 3839:3d42f82cd811
7063628: Use cbcond on T4
Summary: Add new short branch instruction to Hotspot sparc assembler.
Reviewed-by: never, twisti, jrose
author | kvn |
---|---|
date | Thu, 21 Jul 2011 11:25:07 -0700 |
parents | ddd894528dbc |
children | fdb992d83a87 |
comparison
equal
deleted
inserted
replaced
3838:6a991dcb52bb | 3839:3d42f82cd811 |
---|---|
157 if (load_bc_into_scratch) __ set(bc, Rbyte_code); | 157 if (load_bc_into_scratch) __ set(bc, Rbyte_code); |
158 Label patch_done; | 158 Label patch_done; |
159 if (JvmtiExport::can_post_breakpoint()) { | 159 if (JvmtiExport::can_post_breakpoint()) { |
160 Label fast_patch; | 160 Label fast_patch; |
161 __ ldub(at_bcp(0), Rscratch); | 161 __ ldub(at_bcp(0), Rscratch); |
162 __ cmp(Rscratch, Bytecodes::_breakpoint); | 162 __ cmp_and_br_short(Rscratch, Bytecodes::_breakpoint, Assembler::notEqual, Assembler::pt, fast_patch); |
163 __ br(Assembler::notEqual, false, Assembler::pt, fast_patch); | |
164 __ delayed()->nop(); // don't bother to hoist the stb here | |
165 // perform the quickening, slowly, in the bowels of the breakpoint table | 163 // perform the quickening, slowly, in the bowels of the breakpoint table |
166 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), Lmethod, Lbcp, Rbyte_code); | 164 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), Lmethod, Lbcp, Rbyte_code); |
167 __ ba(false, patch_done); | 165 __ ba_short(patch_done); |
168 __ delayed()->nop(); | |
169 __ bind(fast_patch); | 166 __ bind(fast_patch); |
170 } | 167 } |
171 #ifdef ASSERT | 168 #ifdef ASSERT |
172 Bytecodes::Code orig_bytecode = Bytecodes::java_code(bc); | 169 Bytecodes::Code orig_bytecode = Bytecodes::java_code(bc); |
173 Label okay; | 170 Label okay; |
279 const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize; | 276 const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize; |
280 | 277 |
281 // get type from tags | 278 // get type from tags |
282 __ add(O2, tags_offset, O2); | 279 __ add(O2, tags_offset, O2); |
283 __ ldub(O2, O1, O2); | 280 __ ldub(O2, O1, O2); |
284 __ cmp(O2, JVM_CONSTANT_UnresolvedString); // unresolved string? If so, must resolve | 281 // unresolved string? If so, must resolve |
285 __ brx(Assembler::equal, true, Assembler::pt, call_ldc); | 282 __ cmp_and_brx_short(O2, JVM_CONSTANT_UnresolvedString, Assembler::equal, Assembler::pt, call_ldc); |
286 __ delayed()->nop(); | 283 |
287 | 284 // unresolved class? If so, must resolve |
288 __ cmp(O2, JVM_CONSTANT_UnresolvedClass); // unresolved class? If so, must resolve | 285 __ cmp_and_brx_short(O2, JVM_CONSTANT_UnresolvedClass, Assembler::equal, Assembler::pt, call_ldc); |
289 __ brx(Assembler::equal, true, Assembler::pt, call_ldc); | 286 |
290 __ delayed()->nop(); | 287 // unresolved class in error state |
291 | 288 __ cmp_and_brx_short(O2, JVM_CONSTANT_UnresolvedClassInError, Assembler::equal, Assembler::pn, call_ldc); |
292 __ cmp(O2, JVM_CONSTANT_UnresolvedClassInError); // unresolved class in error state | |
293 __ brx(Assembler::equal, true, Assembler::pn, call_ldc); | |
294 __ delayed()->nop(); | |
295 | 289 |
296 __ cmp(O2, JVM_CONSTANT_Class); // need to call vm to get java mirror of the class | 290 __ cmp(O2, JVM_CONSTANT_Class); // need to call vm to get java mirror of the class |
297 __ brx(Assembler::notEqual, true, Assembler::pt, notClass); | 291 __ brx(Assembler::notEqual, true, Assembler::pt, notClass); |
298 __ delayed()->add(O0, base_offset, O0); | 292 __ delayed()->add(O0, base_offset, O0); |
299 | 293 |
300 __ bind(call_ldc); | 294 __ bind(call_ldc); |
301 __ set(wide, O1); | 295 __ set(wide, O1); |
302 call_VM(Otos_i, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), O1); | 296 call_VM(Otos_i, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), O1); |
303 __ push(atos); | 297 __ push(atos); |
304 __ ba(false, exit); | 298 __ ba_short(exit); |
305 __ delayed()->nop(); | |
306 | 299 |
307 __ bind(notClass); | 300 __ bind(notClass); |
308 // __ add(O0, base_offset, O0); | 301 // __ add(O0, base_offset, O0); |
309 __ sll(O1, LogBytesPerWord, O1); | 302 __ sll(O1, LogBytesPerWord, O1); |
310 __ cmp(O2, JVM_CONSTANT_Integer); | 303 __ cmp(O2, JVM_CONSTANT_Integer); |
311 __ brx(Assembler::notEqual, true, Assembler::pt, notInt); | 304 __ brx(Assembler::notEqual, true, Assembler::pt, notInt); |
312 __ delayed()->cmp(O2, JVM_CONSTANT_String); | 305 __ delayed()->cmp(O2, JVM_CONSTANT_String); |
313 __ ld(O0, O1, Otos_i); | 306 __ ld(O0, O1, Otos_i); |
314 __ push(itos); | 307 __ push(itos); |
315 __ ba(false, exit); | 308 __ ba_short(exit); |
316 __ delayed()->nop(); | |
317 | 309 |
318 __ bind(notInt); | 310 __ bind(notInt); |
319 // __ cmp(O2, JVM_CONSTANT_String); | 311 // __ cmp(O2, JVM_CONSTANT_String); |
320 __ brx(Assembler::equal, true, Assembler::pt, isString); | 312 __ brx(Assembler::equal, true, Assembler::pt, isString); |
321 __ delayed()->cmp(O2, JVM_CONSTANT_Object); | 313 __ delayed()->cmp(O2, JVM_CONSTANT_Object); |
323 __ delayed()->ldf(FloatRegisterImpl::S, O0, O1, Ftos_f); | 315 __ delayed()->ldf(FloatRegisterImpl::S, O0, O1, Ftos_f); |
324 __ bind(isString); | 316 __ bind(isString); |
325 __ ld_ptr(O0, O1, Otos_i); | 317 __ ld_ptr(O0, O1, Otos_i); |
326 __ verify_oop(Otos_i); | 318 __ verify_oop(Otos_i); |
327 __ push(atos); | 319 __ push(atos); |
328 __ ba(false, exit); | 320 __ ba_short(exit); |
329 __ delayed()->nop(); | |
330 | 321 |
331 __ bind(notString); | 322 __ bind(notString); |
332 // __ ldf(FloatRegisterImpl::S, O0, O1, Ftos_f); | 323 // __ ldf(FloatRegisterImpl::S, O0, O1, Ftos_f); |
333 __ push(ftos); | 324 __ push(ftos); |
334 | 325 |
363 const Register Rcon_klass = G3_scratch; // same as Rcache | 354 const Register Rcon_klass = G3_scratch; // same as Rcache |
364 const Register Rarray_klass = G4_scratch; // same as Rscratch | 355 const Register Rarray_klass = G4_scratch; // same as Rscratch |
365 __ load_klass(Otos_i, Rcon_klass); | 356 __ load_klass(Otos_i, Rcon_klass); |
366 AddressLiteral array_klass_addr((address)Universe::systemObjArrayKlassObj_addr()); | 357 AddressLiteral array_klass_addr((address)Universe::systemObjArrayKlassObj_addr()); |
367 __ load_contents(array_klass_addr, Rarray_klass); | 358 __ load_contents(array_klass_addr, Rarray_klass); |
368 __ cmp(Rarray_klass, Rcon_klass); | 359 __ cmp_and_brx_short(Rarray_klass, Rcon_klass, Assembler::notEqual, Assembler::pt, L_done); |
369 __ brx(Assembler::notEqual, false, Assembler::pt, L_done); | |
370 __ delayed()->nop(); | |
371 __ ld(Address(Otos_i, arrayOopDesc::length_offset_in_bytes()), Rcon_klass); | 360 __ ld(Address(Otos_i, arrayOopDesc::length_offset_in_bytes()), Rcon_klass); |
372 __ tst(Rcon_klass); | 361 __ tst(Rcon_klass); |
373 __ brx(Assembler::zero, true, Assembler::pt, L_done); | 362 __ brx(Assembler::zero, true, Assembler::pt, L_done); |
374 __ delayed()->clr(Otos_i); // executed only if branch is taken | 363 __ delayed()->clr(Otos_i); // executed only if branch is taken |
375 | 364 |
395 __ ldub(O2, O1, O2); | 384 __ ldub(O2, O1, O2); |
396 | 385 |
397 __ sll(O1, LogBytesPerWord, O1); | 386 __ sll(O1, LogBytesPerWord, O1); |
398 __ add(O0, O1, G3_scratch); | 387 __ add(O0, O1, G3_scratch); |
399 | 388 |
400 __ cmp(O2, JVM_CONSTANT_Double); | 389 __ cmp_and_brx_short(O2, JVM_CONSTANT_Double, Assembler::notEqual, Assembler::pt, Long); |
401 __ brx(Assembler::notEqual, false, Assembler::pt, Long); | |
402 __ delayed()->nop(); | |
403 // A double can be placed at word-aligned locations in the constant pool. | 390 // A double can be placed at word-aligned locations in the constant pool. |
404 // Check out Conversions.java for an example. | 391 // Check out Conversions.java for an example. |
405 // Also constantPoolOopDesc::header_size() is 20, which makes it very difficult | 392 // Also constantPoolOopDesc::header_size() is 20, which makes it very difficult |
406 // to double-align double on the constant pool. SG, 11/7/97 | 393 // to double-align double on the constant pool. SG, 11/7/97 |
407 #ifdef _LP64 | 394 #ifdef _LP64 |
411 __ ldf(FloatRegisterImpl::S, G3_scratch, base_offset, f); | 398 __ ldf(FloatRegisterImpl::S, G3_scratch, base_offset, f); |
412 __ ldf(FloatRegisterImpl::S, G3_scratch, base_offset + sizeof(jdouble)/2, | 399 __ ldf(FloatRegisterImpl::S, G3_scratch, base_offset + sizeof(jdouble)/2, |
413 f->successor()); | 400 f->successor()); |
414 #endif | 401 #endif |
415 __ push(dtos); | 402 __ push(dtos); |
416 __ ba(false, exit); | 403 __ ba_short(exit); |
417 __ delayed()->nop(); | |
418 | 404 |
419 __ bind(Long); | 405 __ bind(Long); |
420 #ifdef _LP64 | 406 #ifdef _LP64 |
421 __ ldx(G3_scratch, base_offset, Otos_l); | 407 __ ldx(G3_scratch, base_offset, Otos_l); |
422 #else | 408 #else |
451 | 437 |
452 // if _iload, wait to rewrite to iload2. We only want to rewrite the | 438 // if _iload, wait to rewrite to iload2. We only want to rewrite the |
453 // last two iloads in a pair. Comparing against fast_iload means that | 439 // last two iloads in a pair. Comparing against fast_iload means that |
454 // the next bytecode is neither an iload or a caload, and therefore | 440 // the next bytecode is neither an iload or a caload, and therefore |
455 // an iload pair. | 441 // an iload pair. |
456 __ cmp(G3_scratch, (int)Bytecodes::_iload); | 442 __ cmp_and_br_short(G3_scratch, (int)Bytecodes::_iload, Assembler::equal, Assembler::pn, done); |
457 __ br(Assembler::equal, false, Assembler::pn, done); | |
458 __ delayed()->nop(); | |
459 | 443 |
460 __ cmp(G3_scratch, (int)Bytecodes::_fast_iload); | 444 __ cmp(G3_scratch, (int)Bytecodes::_fast_iload); |
461 __ br(Assembler::equal, false, Assembler::pn, rewrite); | 445 __ br(Assembler::equal, false, Assembler::pn, rewrite); |
462 __ delayed()->set(Bytecodes::_fast_iload2, G4_scratch); | 446 __ delayed()->set(Bytecodes::_fast_iload2, G4_scratch); |
463 | 447 |
695 | 679 |
696 // do actual aload_0 | 680 // do actual aload_0 |
697 aload(0); | 681 aload(0); |
698 | 682 |
699 // if _getfield then wait with rewrite | 683 // if _getfield then wait with rewrite |
700 __ cmp(G3_scratch, (int)Bytecodes::_getfield); | 684 __ cmp_and_br_short(G3_scratch, (int)Bytecodes::_getfield, Assembler::equal, Assembler::pn, done); |
701 __ br(Assembler::equal, false, Assembler::pn, done); | |
702 __ delayed()->nop(); | |
703 | 685 |
704 // if _igetfield then rewrite to _fast_iaccess_0 | 686 // if _igetfield then rewrite to _fast_iaccess_0 |
705 assert(Bytecodes::java_code(Bytecodes::_fast_iaccess_0) == Bytecodes::_aload_0, "adjust fast bytecode def"); | 687 assert(Bytecodes::java_code(Bytecodes::_fast_iaccess_0) == Bytecodes::_aload_0, "adjust fast bytecode def"); |
706 __ cmp(G3_scratch, (int)Bytecodes::_fast_igetfield); | 688 __ cmp(G3_scratch, (int)Bytecodes::_fast_igetfield); |
707 __ br(Assembler::equal, false, Assembler::pn, rewrite); | 689 __ br(Assembler::equal, false, Assembler::pn, rewrite); |
865 // O3: array | 847 // O3: array |
866 __ verify_oop(Otos_i); | 848 __ verify_oop(Otos_i); |
867 __ index_check_without_pop(O3, O2, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O1); | 849 __ index_check_without_pop(O3, O2, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O1); |
868 | 850 |
869 // do array store check - check for NULL value first | 851 // do array store check - check for NULL value first |
870 __ br_null( Otos_i, false, Assembler::pn, is_null ); | 852 __ br_null_short( Otos_i, Assembler::pn, is_null ); |
871 __ delayed()->nop(); | |
872 | 853 |
873 __ load_klass(O3, O4); // get array klass | 854 __ load_klass(O3, O4); // get array klass |
874 __ load_klass(Otos_i, O5); // get value klass | 855 __ load_klass(Otos_i, O5); // get value klass |
875 | 856 |
876 // do fast instanceof cache test | 857 // do fast instanceof cache test |
897 | 878 |
898 // Store is OK. | 879 // Store is OK. |
899 __ bind(store_ok); | 880 __ bind(store_ok); |
900 do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i, G3_scratch, _bs->kind(), true); | 881 do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i, G3_scratch, _bs->kind(), true); |
901 | 882 |
902 __ ba(false,done); | 883 __ ba(done); |
903 __ delayed()->inc(Lesp, 3* Interpreter::stackElementSize); // adj sp (pops array, index and value) | 884 __ delayed()->inc(Lesp, 3* Interpreter::stackElementSize); // adj sp (pops array, index and value) |
904 | 885 |
905 __ bind(is_null); | 886 __ bind(is_null); |
906 do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), G0, G4_scratch, _bs->kind(), true); | 887 do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), G0, G4_scratch, _bs->kind(), true); |
907 | 888 |
1631 int increment = InvocationCounter::count_increment; | 1612 int increment = InvocationCounter::count_increment; |
1632 int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift; | 1613 int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift; |
1633 if (ProfileInterpreter) { | 1614 if (ProfileInterpreter) { |
1634 // If no method data exists, go to profile_continue. | 1615 // If no method data exists, go to profile_continue. |
1635 __ ld_ptr(Lmethod, methodOopDesc::method_data_offset(), G4_scratch); | 1616 __ ld_ptr(Lmethod, methodOopDesc::method_data_offset(), G4_scratch); |
1636 __ br_null(G4_scratch, false, Assembler::pn, Lno_mdo); | 1617 __ br_null_short(G4_scratch, Assembler::pn, Lno_mdo); |
1637 __ delayed()->nop(); | |
1638 | 1618 |
1639 // Increment backedge counter in the MDO | 1619 // Increment backedge counter in the MDO |
1640 Address mdo_backedge_counter(G4_scratch, in_bytes(methodDataOopDesc::backedge_counter_offset()) + | 1620 Address mdo_backedge_counter(G4_scratch, in_bytes(methodDataOopDesc::backedge_counter_offset()) + |
1641 in_bytes(InvocationCounter::counter_offset())); | 1621 in_bytes(InvocationCounter::counter_offset())); |
1642 __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, G3_scratch, Lscratch, | 1622 __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, G3_scratch, Lscratch, |
1643 Assembler::notZero, &Lforward); | 1623 Assembler::notZero, &Lforward); |
1644 __ ba(false, Loverflow); | 1624 __ ba_short(Loverflow); |
1645 __ delayed()->nop(); | |
1646 } | 1625 } |
1647 | 1626 |
1648 // If there's no MDO, increment counter in methodOop | 1627 // If there's no MDO, increment counter in methodOop |
1649 __ bind(Lno_mdo); | 1628 __ bind(Lno_mdo); |
1650 Address backedge_counter(Lmethod, in_bytes(methodOopDesc::backedge_counter_offset()) + | 1629 Address backedge_counter(Lmethod, in_bytes(methodOopDesc::backedge_counter_offset()) + |
1656 // notify point for loop, pass branch bytecode | 1635 // notify point for loop, pass branch bytecode |
1657 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), O0_cur_bcp); | 1636 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), O0_cur_bcp); |
1658 | 1637 |
1659 // Was an OSR adapter generated? | 1638 // Was an OSR adapter generated? |
1660 // O0 = osr nmethod | 1639 // O0 = osr nmethod |
1661 __ br_null(O0, false, Assembler::pn, Lforward); | 1640 __ br_null_short(O0, Assembler::pn, Lforward); |
1662 __ delayed()->nop(); | |
1663 | 1641 |
1664 // Has the nmethod been invalidated already? | 1642 // Has the nmethod been invalidated already? |
1665 __ ld(O0, nmethod::entry_bci_offset(), O2); | 1643 __ ld(O0, nmethod::entry_bci_offset(), O2); |
1666 __ cmp(O2, InvalidOSREntryBci); | 1644 __ cmp_and_br_short(O2, InvalidOSREntryBci, Assembler::equal, Assembler::pn, Lforward); |
1667 __ br(Assembler::equal, false, Assembler::pn, Lforward); | |
1668 __ delayed()->nop(); | |
1669 | 1645 |
1670 // migrate the interpreter frame off of the stack | 1646 // migrate the interpreter frame off of the stack |
1671 | 1647 |
1672 __ mov(G2_thread, L7); | 1648 __ mov(G2_thread, L7); |
1673 // save nmethod | 1649 // save nmethod |
1828 // lookup dispatch offset | 1804 // lookup dispatch offset |
1829 __ delayed()->sub(Otos_i, O2, O2); | 1805 __ delayed()->sub(Otos_i, O2, O2); |
1830 __ profile_switch_case(O2, O3, G3_scratch, G4_scratch); | 1806 __ profile_switch_case(O2, O3, G3_scratch, G4_scratch); |
1831 __ sll(O2, LogBytesPerInt, O2); | 1807 __ sll(O2, LogBytesPerInt, O2); |
1832 __ add(O2, 3 * BytesPerInt, O2); | 1808 __ add(O2, 3 * BytesPerInt, O2); |
1833 __ ba(false, continue_execution); | 1809 __ ba(continue_execution); |
1834 __ delayed()->ld(O1, O2, O2); | 1810 __ delayed()->ld(O1, O2, O2); |
1835 // handle default | 1811 // handle default |
1836 __ bind(default_case); | 1812 __ bind(default_case); |
1837 __ profile_switch_default(O3); | 1813 __ profile_switch_default(O3); |
1838 __ ld(O1, 0, O2); // get default offset | 1814 __ ld(O1, 0, O2); // get default offset |
1856 __ and3(O1, -BytesPerInt, O1); | 1832 __ and3(O1, -BytesPerInt, O1); |
1857 // set counter | 1833 // set counter |
1858 __ ld(O1, BytesPerInt, O2); | 1834 __ ld(O1, BytesPerInt, O2); |
1859 __ sll(O2, LogBytesPerInt + 1, O2); // in word-pairs | 1835 __ sll(O2, LogBytesPerInt + 1, O2); // in word-pairs |
1860 __ add(O1, 2 * BytesPerInt, O3); // set first pair addr | 1836 __ add(O1, 2 * BytesPerInt, O3); // set first pair addr |
1861 __ ba(false, loop_entry); | 1837 __ ba(loop_entry); |
1862 __ delayed()->add(O3, O2, O2); // counter now points past last pair | 1838 __ delayed()->add(O3, O2, O2); // counter now points past last pair |
1863 | 1839 |
1864 // table search | 1840 // table search |
1865 __ bind(loop); | 1841 __ bind(loop); |
1866 __ cmp(O4, Otos_i); | 1842 __ cmp(O4, Otos_i); |
1875 | 1851 |
1876 // default case | 1852 // default case |
1877 __ ld(O1, 0, O4); // get default offset | 1853 __ ld(O1, 0, O4); // get default offset |
1878 if (ProfileInterpreter) { | 1854 if (ProfileInterpreter) { |
1879 __ profile_switch_default(O3); | 1855 __ profile_switch_default(O3); |
1880 __ ba(false, continue_execution); | 1856 __ ba_short(continue_execution); |
1881 __ delayed()->nop(); | |
1882 } | 1857 } |
1883 | 1858 |
1884 // entry found -> get offset | 1859 // entry found -> get offset |
1885 __ bind(found); | 1860 __ bind(found); |
1886 if (ProfileInterpreter) { | 1861 if (ProfileInterpreter) { |
1942 // initialize i & j (in delay slot) | 1917 // initialize i & j (in delay slot) |
1943 __ clr( Ri ); | 1918 __ clr( Ri ); |
1944 | 1919 |
1945 // and start | 1920 // and start |
1946 Label entry; | 1921 Label entry; |
1947 __ ba(false, entry); | 1922 __ ba(entry); |
1948 __ delayed()->ld( Rarray, -BytesPerInt, Rj); | 1923 __ delayed()->ld( Rarray, -BytesPerInt, Rj); |
1949 // (Rj is already in the native byte-ordering.) | 1924 // (Rj is already in the native byte-ordering.) |
1950 | 1925 |
1951 // binary search loop | 1926 // binary search loop |
1952 { Label loop; | 1927 { Label loop; |
2000 __ profile_switch_case(Rh, Rj, Rscratch, Rkey); | 1975 __ profile_switch_case(Rh, Rj, Rscratch, Rkey); |
2001 __ ld( Rarray, Ri, Rj ); | 1976 __ ld( Rarray, Ri, Rj ); |
2002 // (Rj is already in the native byte-ordering.) | 1977 // (Rj is already in the native byte-ordering.) |
2003 | 1978 |
2004 if (ProfileInterpreter) { | 1979 if (ProfileInterpreter) { |
2005 __ ba(false, continue_execution); | 1980 __ ba_short(continue_execution); |
2006 __ delayed()->nop(); | |
2007 } | 1981 } |
2008 | 1982 |
2009 __ bind(default_case); // fall through (if not profiling) | 1983 __ bind(default_case); // fall through (if not profiling) |
2010 __ profile_switch_default(Ri); | 1984 __ profile_switch_default(Ri); |
2011 | 1985 |
2214 // the time to call into the VM. | 2188 // the time to call into the VM. |
2215 Label Label1; | 2189 Label Label1; |
2216 assert_different_registers(Rcache, index, G1_scratch); | 2190 assert_different_registers(Rcache, index, G1_scratch); |
2217 AddressLiteral get_field_access_count_addr(JvmtiExport::get_field_access_count_addr()); | 2191 AddressLiteral get_field_access_count_addr(JvmtiExport::get_field_access_count_addr()); |
2218 __ load_contents(get_field_access_count_addr, G1_scratch); | 2192 __ load_contents(get_field_access_count_addr, G1_scratch); |
2219 __ tst(G1_scratch); | 2193 __ cmp_and_br_short(G1_scratch, 0, Assembler::equal, Assembler::pt, Label1); |
2220 __ br(Assembler::zero, false, Assembler::pt, Label1); | |
2221 __ delayed()->nop(); | |
2222 | 2194 |
2223 __ add(Rcache, in_bytes(cp_base_offset), Rcache); | 2195 __ add(Rcache, in_bytes(cp_base_offset), Rcache); |
2224 | 2196 |
2225 if (is_static) { | 2197 if (is_static) { |
2226 __ clr(Otos_i); | 2198 __ clr(Otos_i); |
2296 __ verify_oop(Otos_i); | 2268 __ verify_oop(Otos_i); |
2297 __ push(atos); | 2269 __ push(atos); |
2298 if (!is_static) { | 2270 if (!is_static) { |
2299 patch_bytecode(Bytecodes::_fast_agetfield, G3_scratch, G4_scratch); | 2271 patch_bytecode(Bytecodes::_fast_agetfield, G3_scratch, G4_scratch); |
2300 } | 2272 } |
2301 __ ba(false, checkVolatile); | 2273 __ ba(checkVolatile); |
2302 __ delayed()->tst(Lscratch); | 2274 __ delayed()->tst(Lscratch); |
2303 | 2275 |
2304 __ bind(notObj); | 2276 __ bind(notObj); |
2305 | 2277 |
2306 // cmp(Rflags, itos); | 2278 // cmp(Rflags, itos); |
2311 __ ld(Rclass, Roffset, Otos_i); | 2283 __ ld(Rclass, Roffset, Otos_i); |
2312 __ push(itos); | 2284 __ push(itos); |
2313 if (!is_static) { | 2285 if (!is_static) { |
2314 patch_bytecode(Bytecodes::_fast_igetfield, G3_scratch, G4_scratch); | 2286 patch_bytecode(Bytecodes::_fast_igetfield, G3_scratch, G4_scratch); |
2315 } | 2287 } |
2316 __ ba(false, checkVolatile); | 2288 __ ba(checkVolatile); |
2317 __ delayed()->tst(Lscratch); | 2289 __ delayed()->tst(Lscratch); |
2318 | 2290 |
2319 __ bind(notInt); | 2291 __ bind(notInt); |
2320 | 2292 |
2321 // cmp(Rflags, ltos); | 2293 // cmp(Rflags, ltos); |
2327 __ ld_long(Rclass, Roffset, Otos_l); | 2299 __ ld_long(Rclass, Roffset, Otos_l); |
2328 __ push(ltos); | 2300 __ push(ltos); |
2329 if (!is_static) { | 2301 if (!is_static) { |
2330 patch_bytecode(Bytecodes::_fast_lgetfield, G3_scratch, G4_scratch); | 2302 patch_bytecode(Bytecodes::_fast_lgetfield, G3_scratch, G4_scratch); |
2331 } | 2303 } |
2332 __ ba(false, checkVolatile); | 2304 __ ba(checkVolatile); |
2333 __ delayed()->tst(Lscratch); | 2305 __ delayed()->tst(Lscratch); |
2334 | 2306 |
2335 __ bind(notLong); | 2307 __ bind(notLong); |
2336 | 2308 |
2337 // cmp(Rflags, btos); | 2309 // cmp(Rflags, btos); |
2342 __ ldsb(Rclass, Roffset, Otos_i); | 2314 __ ldsb(Rclass, Roffset, Otos_i); |
2343 __ push(itos); | 2315 __ push(itos); |
2344 if (!is_static) { | 2316 if (!is_static) { |
2345 patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch); | 2317 patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch); |
2346 } | 2318 } |
2347 __ ba(false, checkVolatile); | 2319 __ ba(checkVolatile); |
2348 __ delayed()->tst(Lscratch); | 2320 __ delayed()->tst(Lscratch); |
2349 | 2321 |
2350 __ bind(notByte); | 2322 __ bind(notByte); |
2351 | 2323 |
2352 // cmp(Rflags, ctos); | 2324 // cmp(Rflags, ctos); |
2357 __ lduh(Rclass, Roffset, Otos_i); | 2329 __ lduh(Rclass, Roffset, Otos_i); |
2358 __ push(itos); | 2330 __ push(itos); |
2359 if (!is_static) { | 2331 if (!is_static) { |
2360 patch_bytecode(Bytecodes::_fast_cgetfield, G3_scratch, G4_scratch); | 2332 patch_bytecode(Bytecodes::_fast_cgetfield, G3_scratch, G4_scratch); |
2361 } | 2333 } |
2362 __ ba(false, checkVolatile); | 2334 __ ba(checkVolatile); |
2363 __ delayed()->tst(Lscratch); | 2335 __ delayed()->tst(Lscratch); |
2364 | 2336 |
2365 __ bind(notChar); | 2337 __ bind(notChar); |
2366 | 2338 |
2367 // cmp(Rflags, stos); | 2339 // cmp(Rflags, stos); |
2372 __ ldsh(Rclass, Roffset, Otos_i); | 2344 __ ldsh(Rclass, Roffset, Otos_i); |
2373 __ push(itos); | 2345 __ push(itos); |
2374 if (!is_static) { | 2346 if (!is_static) { |
2375 patch_bytecode(Bytecodes::_fast_sgetfield, G3_scratch, G4_scratch); | 2347 patch_bytecode(Bytecodes::_fast_sgetfield, G3_scratch, G4_scratch); |
2376 } | 2348 } |
2377 __ ba(false, checkVolatile); | 2349 __ ba(checkVolatile); |
2378 __ delayed()->tst(Lscratch); | 2350 __ delayed()->tst(Lscratch); |
2379 | 2351 |
2380 __ bind(notShort); | 2352 __ bind(notShort); |
2381 | 2353 |
2382 | 2354 |
2388 __ ldf(FloatRegisterImpl::S, Rclass, Roffset, Ftos_f); | 2360 __ ldf(FloatRegisterImpl::S, Rclass, Roffset, Ftos_f); |
2389 __ push(ftos); | 2361 __ push(ftos); |
2390 if (!is_static) { | 2362 if (!is_static) { |
2391 patch_bytecode(Bytecodes::_fast_fgetfield, G3_scratch, G4_scratch); | 2363 patch_bytecode(Bytecodes::_fast_fgetfield, G3_scratch, G4_scratch); |
2392 } | 2364 } |
2393 __ ba(false, checkVolatile); | 2365 __ ba(checkVolatile); |
2394 __ delayed()->tst(Lscratch); | 2366 __ delayed()->tst(Lscratch); |
2395 | 2367 |
2396 __ bind(notFloat); | 2368 __ bind(notFloat); |
2397 | 2369 |
2398 | 2370 |
2497 // Check to see if a field modification watch has been set before we take | 2469 // Check to see if a field modification watch has been set before we take |
2498 // the time to call into the VM. | 2470 // the time to call into the VM. |
2499 Label done; | 2471 Label done; |
2500 AddressLiteral get_field_modification_count_addr(JvmtiExport::get_field_modification_count_addr()); | 2472 AddressLiteral get_field_modification_count_addr(JvmtiExport::get_field_modification_count_addr()); |
2501 __ load_contents(get_field_modification_count_addr, G4_scratch); | 2473 __ load_contents(get_field_modification_count_addr, G4_scratch); |
2502 __ tst(G4_scratch); | 2474 __ cmp_and_br_short(G4_scratch, 0, Assembler::equal, Assembler::pt, done); |
2503 __ br(Assembler::zero, false, Assembler::pt, done); | |
2504 __ delayed()->nop(); | |
2505 __ pop_ptr(G4_scratch); // copy the object pointer from tos | 2475 __ pop_ptr(G4_scratch); // copy the object pointer from tos |
2506 __ verify_oop(G4_scratch); | 2476 __ verify_oop(G4_scratch); |
2507 __ push_ptr(G4_scratch); // put the object pointer back on tos | 2477 __ push_ptr(G4_scratch); // put the object pointer back on tos |
2508 __ get_cache_entry_pointer_at_bcp(G1_scratch, G3_scratch, 1); | 2478 __ get_cache_entry_pointer_at_bcp(G1_scratch, G3_scratch, 1); |
2509 // Save tos values before call_VM() clobbers them. Since we have | 2479 // Save tos values before call_VM() clobbers them. Since we have |
2550 // the time to call into the VM. | 2520 // the time to call into the VM. |
2551 Label Label1; | 2521 Label Label1; |
2552 assert_different_registers(Rcache, index, G1_scratch); | 2522 assert_different_registers(Rcache, index, G1_scratch); |
2553 AddressLiteral get_field_modification_count_addr(JvmtiExport::get_field_modification_count_addr()); | 2523 AddressLiteral get_field_modification_count_addr(JvmtiExport::get_field_modification_count_addr()); |
2554 __ load_contents(get_field_modification_count_addr, G1_scratch); | 2524 __ load_contents(get_field_modification_count_addr, G1_scratch); |
2555 __ tst(G1_scratch); | 2525 __ cmp_and_br_short(G1_scratch, 0, Assembler::zero, Assembler::pt, Label1); |
2556 __ br(Assembler::zero, false, Assembler::pt, Label1); | |
2557 __ delayed()->nop(); | |
2558 | 2526 |
2559 // The Rcache and index registers have been already set. | 2527 // The Rcache and index registers have been already set. |
2560 // This allows to eliminate this call but the Rcache and index | 2528 // This allows to eliminate this call but the Rcache and index |
2561 // registers must be correspondingly used after this line. | 2529 // registers must be correspondingly used after this line. |
2562 __ get_cache_and_index_at_bcp(G1_scratch, G4_scratch, 1); | 2530 __ get_cache_and_index_at_bcp(G1_scratch, G4_scratch, 1); |
2582 __ br(Assembler::equal, false, Assembler::pt, two_word); | 2550 __ br(Assembler::equal, false, Assembler::pt, two_word); |
2583 __ delayed()->cmp(Rflags, dtos); | 2551 __ delayed()->cmp(Rflags, dtos); |
2584 __ br(Assembler::equal, false, Assembler::pt, two_word); | 2552 __ br(Assembler::equal, false, Assembler::pt, two_word); |
2585 __ delayed()->nop(); | 2553 __ delayed()->nop(); |
2586 __ inc(G4_scratch, Interpreter::expr_offset_in_bytes(1)); | 2554 __ inc(G4_scratch, Interpreter::expr_offset_in_bytes(1)); |
2587 __ br(Assembler::always, false, Assembler::pt, valsizeknown); | 2555 __ ba_short(valsizeknown); |
2588 __ delayed()->nop(); | |
2589 __ bind(two_word); | 2556 __ bind(two_word); |
2590 | 2557 |
2591 __ inc(G4_scratch, Interpreter::expr_offset_in_bytes(2)); | 2558 __ inc(G4_scratch, Interpreter::expr_offset_in_bytes(2)); |
2592 | 2559 |
2593 __ bind(valsizeknown); | 2560 __ bind(valsizeknown); |
2634 if (__ membar_has_effect(read_bits) || __ membar_has_effect(write_bits)) { | 2601 if (__ membar_has_effect(read_bits) || __ membar_has_effect(write_bits)) { |
2635 __ set((1 << ConstantPoolCacheEntry::volatileField), Lscratch); | 2602 __ set((1 << ConstantPoolCacheEntry::volatileField), Lscratch); |
2636 __ and3(Rflags, Lscratch, Lscratch); | 2603 __ and3(Rflags, Lscratch, Lscratch); |
2637 | 2604 |
2638 if (__ membar_has_effect(read_bits)) { | 2605 if (__ membar_has_effect(read_bits)) { |
2639 __ tst(Lscratch); | 2606 __ cmp_and_br_short(Lscratch, 0, Assembler::equal, Assembler::pt, notVolatile); |
2640 __ br(Assembler::zero, false, Assembler::pt, notVolatile); | |
2641 __ delayed()->nop(); | |
2642 volatile_barrier(read_bits); | 2607 volatile_barrier(read_bits); |
2643 __ bind(notVolatile); | 2608 __ bind(notVolatile); |
2644 } | 2609 } |
2645 } | 2610 } |
2646 | 2611 |
2661 __ pop_ptr(); | 2626 __ pop_ptr(); |
2662 __ verify_oop(Otos_i); | 2627 __ verify_oop(Otos_i); |
2663 | 2628 |
2664 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); | 2629 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); |
2665 | 2630 |
2666 __ ba(false, checkVolatile); | 2631 __ ba(checkVolatile); |
2667 __ delayed()->tst(Lscratch); | 2632 __ delayed()->tst(Lscratch); |
2668 | 2633 |
2669 __ bind(notObj); | 2634 __ bind(notObj); |
2670 | 2635 |
2671 // cmp(Rflags, itos ); | 2636 // cmp(Rflags, itos ); |
2673 __ delayed() ->cmp(Rflags, btos ); | 2638 __ delayed() ->cmp(Rflags, btos ); |
2674 | 2639 |
2675 // itos | 2640 // itos |
2676 __ pop_i(); | 2641 __ pop_i(); |
2677 __ st(Otos_i, Rclass, Roffset); | 2642 __ st(Otos_i, Rclass, Roffset); |
2678 __ ba(false, checkVolatile); | 2643 __ ba(checkVolatile); |
2679 __ delayed()->tst(Lscratch); | 2644 __ delayed()->tst(Lscratch); |
2680 | 2645 |
2681 __ bind(notInt); | 2646 __ bind(notInt); |
2682 | 2647 |
2683 } else { | 2648 } else { |
2689 // itos | 2654 // itos |
2690 __ pop_i(); | 2655 __ pop_i(); |
2691 pop_and_check_object(Rclass); | 2656 pop_and_check_object(Rclass); |
2692 __ st(Otos_i, Rclass, Roffset); | 2657 __ st(Otos_i, Rclass, Roffset); |
2693 patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch); | 2658 patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch); |
2694 __ ba(false, checkVolatile); | 2659 __ ba(checkVolatile); |
2695 __ delayed()->tst(Lscratch); | 2660 __ delayed()->tst(Lscratch); |
2696 | 2661 |
2697 __ bind(notInt); | 2662 __ bind(notInt); |
2698 // cmp(Rflags, atos ); | 2663 // cmp(Rflags, atos ); |
2699 __ br(Assembler::notEqual, false, Assembler::pt, notObj); | 2664 __ br(Assembler::notEqual, false, Assembler::pt, notObj); |
2705 __ verify_oop(Otos_i); | 2670 __ verify_oop(Otos_i); |
2706 | 2671 |
2707 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); | 2672 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); |
2708 | 2673 |
2709 patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch); | 2674 patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch); |
2710 __ ba(false, checkVolatile); | 2675 __ ba(checkVolatile); |
2711 __ delayed()->tst(Lscratch); | 2676 __ delayed()->tst(Lscratch); |
2712 | 2677 |
2713 __ bind(notObj); | 2678 __ bind(notObj); |
2714 } | 2679 } |
2715 | 2680 |
2722 if (!is_static) pop_and_check_object(Rclass); | 2687 if (!is_static) pop_and_check_object(Rclass); |
2723 __ stb(Otos_i, Rclass, Roffset); | 2688 __ stb(Otos_i, Rclass, Roffset); |
2724 if (!is_static) { | 2689 if (!is_static) { |
2725 patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch); | 2690 patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch); |
2726 } | 2691 } |
2727 __ ba(false, checkVolatile); | 2692 __ ba(checkVolatile); |
2728 __ delayed()->tst(Lscratch); | 2693 __ delayed()->tst(Lscratch); |
2729 | 2694 |
2730 __ bind(notByte); | 2695 __ bind(notByte); |
2731 | 2696 |
2732 // cmp(Rflags, ltos ); | 2697 // cmp(Rflags, ltos ); |
2738 if (!is_static) pop_and_check_object(Rclass); | 2703 if (!is_static) pop_and_check_object(Rclass); |
2739 __ st_long(Otos_l, Rclass, Roffset); | 2704 __ st_long(Otos_l, Rclass, Roffset); |
2740 if (!is_static) { | 2705 if (!is_static) { |
2741 patch_bytecode(Bytecodes::_fast_lputfield, G3_scratch, G4_scratch); | 2706 patch_bytecode(Bytecodes::_fast_lputfield, G3_scratch, G4_scratch); |
2742 } | 2707 } |
2743 __ ba(false, checkVolatile); | 2708 __ ba(checkVolatile); |
2744 __ delayed()->tst(Lscratch); | 2709 __ delayed()->tst(Lscratch); |
2745 | 2710 |
2746 __ bind(notLong); | 2711 __ bind(notLong); |
2747 | 2712 |
2748 // cmp(Rflags, ctos ); | 2713 // cmp(Rflags, ctos ); |
2754 if (!is_static) pop_and_check_object(Rclass); | 2719 if (!is_static) pop_and_check_object(Rclass); |
2755 __ sth(Otos_i, Rclass, Roffset); | 2720 __ sth(Otos_i, Rclass, Roffset); |
2756 if (!is_static) { | 2721 if (!is_static) { |
2757 patch_bytecode(Bytecodes::_fast_cputfield, G3_scratch, G4_scratch); | 2722 patch_bytecode(Bytecodes::_fast_cputfield, G3_scratch, G4_scratch); |
2758 } | 2723 } |
2759 __ ba(false, checkVolatile); | 2724 __ ba(checkVolatile); |
2760 __ delayed()->tst(Lscratch); | 2725 __ delayed()->tst(Lscratch); |
2761 | 2726 |
2762 __ bind(notChar); | 2727 __ bind(notChar); |
2763 // cmp(Rflags, stos ); | 2728 // cmp(Rflags, stos ); |
2764 __ br(Assembler::notEqual, false, Assembler::pt, notShort); | 2729 __ br(Assembler::notEqual, false, Assembler::pt, notShort); |
2769 if (!is_static) pop_and_check_object(Rclass); | 2734 if (!is_static) pop_and_check_object(Rclass); |
2770 __ sth(Otos_i, Rclass, Roffset); | 2735 __ sth(Otos_i, Rclass, Roffset); |
2771 if (!is_static) { | 2736 if (!is_static) { |
2772 patch_bytecode(Bytecodes::_fast_sputfield, G3_scratch, G4_scratch); | 2737 patch_bytecode(Bytecodes::_fast_sputfield, G3_scratch, G4_scratch); |
2773 } | 2738 } |
2774 __ ba(false, checkVolatile); | 2739 __ ba(checkVolatile); |
2775 __ delayed()->tst(Lscratch); | 2740 __ delayed()->tst(Lscratch); |
2776 | 2741 |
2777 __ bind(notShort); | 2742 __ bind(notShort); |
2778 // cmp(Rflags, ftos ); | 2743 // cmp(Rflags, ftos ); |
2779 __ br(Assembler::notZero, false, Assembler::pt, notFloat); | 2744 __ br(Assembler::notZero, false, Assembler::pt, notFloat); |
2784 if (!is_static) pop_and_check_object(Rclass); | 2749 if (!is_static) pop_and_check_object(Rclass); |
2785 __ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset); | 2750 __ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset); |
2786 if (!is_static) { | 2751 if (!is_static) { |
2787 patch_bytecode(Bytecodes::_fast_fputfield, G3_scratch, G4_scratch); | 2752 patch_bytecode(Bytecodes::_fast_fputfield, G3_scratch, G4_scratch); |
2788 } | 2753 } |
2789 __ ba(false, checkVolatile); | 2754 __ ba(checkVolatile); |
2790 __ delayed()->tst(Lscratch); | 2755 __ delayed()->tst(Lscratch); |
2791 | 2756 |
2792 __ bind(notFloat); | 2757 __ bind(notFloat); |
2793 | 2758 |
2794 // dtos | 2759 // dtos |
2831 if (__ membar_has_effect(read_bits) || __ membar_has_effect(write_bits)) { | 2796 if (__ membar_has_effect(read_bits) || __ membar_has_effect(write_bits)) { |
2832 __ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::flags_offset(), Rflags); | 2797 __ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::flags_offset(), Rflags); |
2833 __ set((1 << ConstantPoolCacheEntry::volatileField), Lscratch); | 2798 __ set((1 << ConstantPoolCacheEntry::volatileField), Lscratch); |
2834 __ and3(Rflags, Lscratch, Lscratch); | 2799 __ and3(Rflags, Lscratch, Lscratch); |
2835 if (__ membar_has_effect(read_bits)) { | 2800 if (__ membar_has_effect(read_bits)) { |
2836 __ tst(Lscratch); | 2801 __ cmp_and_br_short(Lscratch, 0, Assembler::equal, Assembler::pt, notVolatile); |
2837 __ br(Assembler::zero, false, Assembler::pt, notVolatile); | |
2838 __ delayed()->nop(); | |
2839 volatile_barrier(read_bits); | 2802 volatile_barrier(read_bits); |
2840 __ bind(notVolatile); | 2803 __ bind(notVolatile); |
2841 } | 2804 } |
2842 } | 2805 } |
2843 | 2806 |
2862 default: | 2825 default: |
2863 ShouldNotReachHere(); | 2826 ShouldNotReachHere(); |
2864 } | 2827 } |
2865 | 2828 |
2866 if (__ membar_has_effect(write_bits)) { | 2829 if (__ membar_has_effect(write_bits)) { |
2867 __ tst(Lscratch); | 2830 __ cmp_and_br_short(Lscratch, 0, Assembler::equal, Assembler::pt, exit); |
2868 __ br(Assembler::zero, false, Assembler::pt, exit); | |
2869 __ delayed()->nop(); | |
2870 volatile_barrier(Assembler::StoreLoad); | 2831 volatile_barrier(Assembler::StoreLoad); |
2871 __ bind(exit); | 2832 __ bind(exit); |
2872 } | 2833 } |
2873 } | 2834 } |
2874 | 2835 |
3224 // Check that entry is non-null. Null entries are probably a bytecode | 3185 // Check that entry is non-null. Null entries are probably a bytecode |
3225 // problem. If the interface isn't implemented by the receiver class, | 3186 // problem. If the interface isn't implemented by the receiver class, |
3226 // the VM should throw IncompatibleClassChangeError. linkResolver checks | 3187 // the VM should throw IncompatibleClassChangeError. linkResolver checks |
3227 // this too but that's only if the entry isn't already resolved, so we | 3188 // this too but that's only if the entry isn't already resolved, so we |
3228 // need to check again. | 3189 // need to check again. |
3229 __ br_notnull( Rtemp, false, Assembler::pt, ok); | 3190 __ br_notnull_short( Rtemp, Assembler::pt, ok); |
3230 __ delayed()->nop(); | |
3231 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError)); | 3191 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError)); |
3232 __ should_not_reach_here(); | 3192 __ should_not_reach_here(); |
3233 __ bind(ok); | 3193 __ bind(ok); |
3234 __ verify_oop(Rtemp); | 3194 __ verify_oop(Rtemp); |
3235 } | 3195 } |
3249 __ ld_ptr(RklassOop, Rscratch, G5_method); | 3209 __ ld_ptr(RklassOop, Rscratch, G5_method); |
3250 | 3210 |
3251 // Check for abstract method error. | 3211 // Check for abstract method error. |
3252 { | 3212 { |
3253 Label ok; | 3213 Label ok; |
3254 __ tst(G5_method); | 3214 __ br_notnull_short(G5_method, Assembler::pt, ok); |
3255 __ brx(Assembler::notZero, false, Assembler::pt, ok); | |
3256 __ delayed()->nop(); | |
3257 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError)); | 3215 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError)); |
3258 __ should_not_reach_here(); | 3216 __ should_not_reach_here(); |
3259 __ bind(ok); | 3217 __ bind(ok); |
3260 } | 3218 } |
3261 | 3219 |
3406 #ifdef _LP64 | 3364 #ifdef _LP64 |
3407 __ srlx(RfreeValue, LogHeapWordSize, RfreeValue); | 3365 __ srlx(RfreeValue, LogHeapWordSize, RfreeValue); |
3408 #else | 3366 #else |
3409 __ srl(RfreeValue, LogHeapWordSize, RfreeValue); | 3367 __ srl(RfreeValue, LogHeapWordSize, RfreeValue); |
3410 #endif | 3368 #endif |
3411 __ cmp(RtlabWasteLimitValue, RfreeValue); | 3369 __ cmp_and_brx_short(RtlabWasteLimitValue, RfreeValue, Assembler::greaterEqualUnsigned, Assembler::pt, slow_case); // tlab waste is small |
3412 __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, slow_case); // tlab waste is small | |
3413 __ delayed()->nop(); | |
3414 | 3370 |
3415 // increment waste limit to prevent getting stuck on this slow path | 3371 // increment waste limit to prevent getting stuck on this slow path |
3416 __ add(RtlabWasteLimitValue, ThreadLocalAllocBuffer::refill_waste_limit_increment(), RtlabWasteLimitValue); | 3372 __ add(RtlabWasteLimitValue, ThreadLocalAllocBuffer::refill_waste_limit_increment(), RtlabWasteLimitValue); |
3417 __ st_ptr(RtlabWasteLimitValue, G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())); | 3373 __ st_ptr(RtlabWasteLimitValue, G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())); |
3418 } else { | 3374 } else { |
3419 // No allocation in the shared eden. | 3375 // No allocation in the shared eden. |
3420 __ br(Assembler::always, false, Assembler::pt, slow_case); | 3376 __ ba_short(slow_case); |
3421 __ delayed()->nop(); | |
3422 } | 3377 } |
3423 } | 3378 } |
3424 | 3379 |
3425 // Allocation in the shared Eden | 3380 // Allocation in the shared Eden |
3426 if (allow_shared_alloc) { | 3381 if (allow_shared_alloc) { |
3438 __ ld_ptr(RtopAddr, 0, RoldTopValue); | 3393 __ ld_ptr(RtopAddr, 0, RoldTopValue); |
3439 __ add(RoldTopValue, Roffset, RnewTopValue); | 3394 __ add(RoldTopValue, Roffset, RnewTopValue); |
3440 | 3395 |
3441 // RnewTopValue contains the top address after the new object | 3396 // RnewTopValue contains the top address after the new object |
3442 // has been allocated. | 3397 // has been allocated. |
3443 __ cmp(RnewTopValue, RendValue); | 3398 __ cmp_and_brx_short(RnewTopValue, RendValue, Assembler::greaterUnsigned, Assembler::pn, slow_case); |
3444 __ brx(Assembler::greaterUnsigned, false, Assembler::pn, slow_case); | |
3445 __ delayed()->nop(); | |
3446 | 3399 |
3447 __ casx_under_lock(RtopAddr, RoldTopValue, RnewTopValue, | 3400 __ casx_under_lock(RtopAddr, RoldTopValue, RnewTopValue, |
3448 VM_Version::v9_instructions_work() ? NULL : | 3401 VM_Version::v9_instructions_work() ? NULL : |
3449 (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr()); | 3402 (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr()); |
3450 | 3403 |
3451 // if someone beat us on the allocation, try again, otherwise continue | 3404 // if someone beat us on the allocation, try again, otherwise continue |
3452 __ cmp(RoldTopValue, RnewTopValue); | 3405 __ cmp_and_brx_short(RoldTopValue, RnewTopValue, Assembler::notEqual, Assembler::pn, retry); |
3453 __ brx(Assembler::notEqual, false, Assembler::pn, retry); | |
3454 __ delayed()->nop(); | |
3455 | 3406 |
3456 // bump total bytes allocated by this thread | 3407 // bump total bytes allocated by this thread |
3457 // RoldTopValue and RtopAddr are dead, so can use G1 and G3 | 3408 // RoldTopValue and RtopAddr are dead, so can use G1 and G3 |
3458 __ incr_allocated_bytes(Roffset, G1_scratch, G3_scratch); | 3409 __ incr_allocated_bytes(Roffset, G1_scratch, G3_scratch); |
3459 } | 3410 } |
3472 //__ subcc(Roffset, wordSize, Roffset); // executed above loop or in delay slot | 3423 //__ subcc(Roffset, wordSize, Roffset); // executed above loop or in delay slot |
3473 __ st_ptr(G0, G3_scratch, Roffset); | 3424 __ st_ptr(G0, G3_scratch, Roffset); |
3474 __ br(Assembler::notEqual, false, Assembler::pt, loop); | 3425 __ br(Assembler::notEqual, false, Assembler::pt, loop); |
3475 __ delayed()->subcc(Roffset, wordSize, Roffset); | 3426 __ delayed()->subcc(Roffset, wordSize, Roffset); |
3476 } | 3427 } |
3477 __ br(Assembler::always, false, Assembler::pt, initialize_header); | 3428 __ ba_short(initialize_header); |
3478 __ delayed()->nop(); | |
3479 } | 3429 } |
3480 | 3430 |
3481 // slow case | 3431 // slow case |
3482 __ bind(slow_case); | 3432 __ bind(slow_case); |
3483 __ get_2_byte_integer_at_bcp(1, G3_scratch, O2, InterpreterMacroAssembler::Unsigned); | 3433 __ get_2_byte_integer_at_bcp(1, G3_scratch, O2, InterpreterMacroAssembler::Unsigned); |
3484 __ get_constant_pool(O1); | 3434 __ get_constant_pool(O1); |
3485 | 3435 |
3486 call_VM(Otos_i, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), O1, O2); | 3436 call_VM(Otos_i, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), O1, O2); |
3487 | 3437 |
3488 __ ba(false, done); | 3438 __ ba_short(done); |
3489 __ delayed()->nop(); | |
3490 | 3439 |
3491 // Initialize the header: mark, klass | 3440 // Initialize the header: mark, klass |
3492 __ bind(initialize_header); | 3441 __ bind(initialize_header); |
3493 | 3442 |
3494 if (UseBiasedLocking) { | 3443 if (UseBiasedLocking) { |
3548 Register Roffset = G1_scratch; | 3497 Register Roffset = G1_scratch; |
3549 Register RobjKlass = O5; | 3498 Register RobjKlass = O5; |
3550 Register RspecifiedKlass = O4; | 3499 Register RspecifiedKlass = O4; |
3551 | 3500 |
3552 // Check for casting a NULL | 3501 // Check for casting a NULL |
3553 __ br_null(Otos_i, false, Assembler::pn, is_null); | 3502 __ br_null_short(Otos_i, Assembler::pn, is_null); |
3554 __ delayed()->nop(); | |
3555 | 3503 |
3556 // Get value klass in RobjKlass | 3504 // Get value klass in RobjKlass |
3557 __ load_klass(Otos_i, RobjKlass); // get value klass | 3505 __ load_klass(Otos_i, RobjKlass); // get value klass |
3558 | 3506 |
3559 // Get constant pool tag | 3507 // Get constant pool tag |
3569 | 3517 |
3570 __ push_ptr(); // save receiver for result, and for GC | 3518 __ push_ptr(); // save receiver for result, and for GC |
3571 call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); | 3519 call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); |
3572 __ pop_ptr(Otos_i, G3_scratch); // restore receiver | 3520 __ pop_ptr(Otos_i, G3_scratch); // restore receiver |
3573 | 3521 |
3574 __ br(Assembler::always, false, Assembler::pt, resolved); | 3522 __ ba_short(resolved); |
3575 __ delayed()->nop(); | |
3576 | 3523 |
3577 // Extract target class from constant pool | 3524 // Extract target class from constant pool |
3578 __ bind(quicked); | 3525 __ bind(quicked); |
3579 __ add(Roffset, sizeof(constantPoolOopDesc), Roffset); | 3526 __ add(Roffset, sizeof(constantPoolOopDesc), Roffset); |
3580 __ ld_ptr(Lscratch, Roffset, RspecifiedKlass); | 3527 __ ld_ptr(Lscratch, Roffset, RspecifiedKlass); |
3589 __ throw_if_not_x( Assembler::never, Interpreter::_throw_ClassCastException_entry, G3_scratch ); | 3536 __ throw_if_not_x( Assembler::never, Interpreter::_throw_ClassCastException_entry, G3_scratch ); |
3590 | 3537 |
3591 __ bind(cast_ok); | 3538 __ bind(cast_ok); |
3592 | 3539 |
3593 if (ProfileInterpreter) { | 3540 if (ProfileInterpreter) { |
3594 __ ba(false, done); | 3541 __ ba_short(done); |
3595 __ delayed()->nop(); | |
3596 } | 3542 } |
3597 __ bind(is_null); | 3543 __ bind(is_null); |
3598 __ profile_null_seen(G3_scratch); | 3544 __ profile_null_seen(G3_scratch); |
3599 __ bind(done); | 3545 __ bind(done); |
3600 } | 3546 } |
3606 Register Roffset = G1_scratch; | 3552 Register Roffset = G1_scratch; |
3607 Register RobjKlass = O5; | 3553 Register RobjKlass = O5; |
3608 Register RspecifiedKlass = O4; | 3554 Register RspecifiedKlass = O4; |
3609 | 3555 |
3610 // Check for casting a NULL | 3556 // Check for casting a NULL |
3611 __ br_null(Otos_i, false, Assembler::pt, is_null); | 3557 __ br_null_short(Otos_i, Assembler::pt, is_null); |
3612 __ delayed()->nop(); | |
3613 | 3558 |
3614 // Get value klass in RobjKlass | 3559 // Get value klass in RobjKlass |
3615 __ load_klass(Otos_i, RobjKlass); // get value klass | 3560 __ load_klass(Otos_i, RobjKlass); // get value klass |
3616 | 3561 |
3617 // Get constant pool tag | 3562 // Get constant pool tag |
3627 | 3572 |
3628 __ push_ptr(); // save receiver for result, and for GC | 3573 __ push_ptr(); // save receiver for result, and for GC |
3629 call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); | 3574 call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); |
3630 __ pop_ptr(Otos_i, G3_scratch); // restore receiver | 3575 __ pop_ptr(Otos_i, G3_scratch); // restore receiver |
3631 | 3576 |
3632 __ br(Assembler::always, false, Assembler::pt, resolved); | 3577 __ ba_short(resolved); |
3633 __ delayed()->nop(); | |
3634 | |
3635 | 3578 |
3636 // Extract target class from constant pool | 3579 // Extract target class from constant pool |
3637 __ bind(quicked); | 3580 __ bind(quicked); |
3638 __ add(Roffset, sizeof(constantPoolOopDesc), Roffset); | 3581 __ add(Roffset, sizeof(constantPoolOopDesc), Roffset); |
3639 __ get_constant_pool(Lscratch); | 3582 __ get_constant_pool(Lscratch); |
3647 __ gen_subtype_check( RobjKlass, RspecifiedKlass, G3_scratch, G4_scratch, G1_scratch, done ); | 3590 __ gen_subtype_check( RobjKlass, RspecifiedKlass, G3_scratch, G4_scratch, G1_scratch, done ); |
3648 // Not a subtype; return 0; | 3591 // Not a subtype; return 0; |
3649 __ clr( Otos_i ); | 3592 __ clr( Otos_i ); |
3650 | 3593 |
3651 if (ProfileInterpreter) { | 3594 if (ProfileInterpreter) { |
3652 __ ba(false, done); | 3595 __ ba_short(done); |
3653 __ delayed()->nop(); | |
3654 } | 3596 } |
3655 __ bind(is_null); | 3597 __ bind(is_null); |
3656 __ profile_null_seen(G3_scratch); | 3598 __ profile_null_seen(G3_scratch); |
3657 __ bind(done); | 3599 __ bind(done); |
3658 } | 3600 } |
3722 __ clr(O1); // points to free slot or NULL | 3664 __ clr(O1); // points to free slot or NULL |
3723 | 3665 |
3724 { | 3666 { |
3725 Label entry, loop, exit; | 3667 Label entry, loop, exit; |
3726 __ add( __ top_most_monitor(), O2 ); // last one to check | 3668 __ add( __ top_most_monitor(), O2 ); // last one to check |
3727 __ ba( false, entry ); | 3669 __ ba( entry ); |
3728 __ delayed()->mov( Lmonitors, O3 ); // first one to check | 3670 __ delayed()->mov( Lmonitors, O3 ); // first one to check |
3729 | 3671 |
3730 | 3672 |
3731 __ bind( loop ); | 3673 __ bind( loop ); |
3732 | 3674 |
3755 } | 3697 } |
3756 | 3698 |
3757 { Label allocated; | 3699 { Label allocated; |
3758 | 3700 |
3759 // found free slot? | 3701 // found free slot? |
3760 __ br_notnull(O1, false, Assembler::pn, allocated); | 3702 __ br_notnull_short(O1, Assembler::pn, allocated); |
3761 __ delayed()->nop(); | |
3762 | 3703 |
3763 __ add_monitor_to_stack( false, O2, O3 ); | 3704 __ add_monitor_to_stack( false, O2, O3 ); |
3764 __ mov(Lmonitors, O1); | 3705 __ mov(Lmonitors, O1); |
3765 | 3706 |
3766 __ bind(allocated); | 3707 __ bind(allocated); |
3789 | 3730 |
3790 assert(O0 == Otos_i, "just checking"); | 3731 assert(O0 == Otos_i, "just checking"); |
3791 | 3732 |
3792 { Label entry, loop, found; | 3733 { Label entry, loop, found; |
3793 __ add( __ top_most_monitor(), O2 ); // last one to check | 3734 __ add( __ top_most_monitor(), O2 ); // last one to check |
3794 __ ba(false, entry ); | 3735 __ ba(entry); |
3795 // use Lscratch to hold monitor elem to check, start with most recent monitor, | 3736 // use Lscratch to hold monitor elem to check, start with most recent monitor, |
3796 // By using a local it survives the call to the C routine. | 3737 // By using a local it survives the call to the C routine. |
3797 __ delayed()->mov( Lmonitors, Lscratch ); | 3738 __ delayed()->mov( Lmonitors, Lscratch ); |
3798 | 3739 |
3799 __ bind( loop ); | 3740 __ bind( loop ); |