460 |
460 |
461 void TemplateTable::aaload() { |
461 void TemplateTable::aaload() { |
462 transition(itos, atos); |
462 transition(itos, atos); |
463 // Otos_i: index |
463 // Otos_i: index |
464 // tos: array |
464 // tos: array |
465 __ index_check(O2, Otos_i, LogBytesPerWord, G3_scratch, O3); |
465 __ index_check(O2, Otos_i, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O3); |
466 __ ld_ptr(O3, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i); |
466 __ load_heap_oop(O3, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i); |
467 __ verify_oop(Otos_i); |
467 __ verify_oop(Otos_i); |
468 } |
468 } |
469 |
469 |
470 |
470 |
471 void TemplateTable::baload() { |
471 void TemplateTable::baload() { |
734 __ ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(2), O3); // get array |
734 __ ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(2), O3); // get array |
735 // Otos_i: val |
735 // Otos_i: val |
736 // O2: index |
736 // O2: index |
737 // O3: array |
737 // O3: array |
738 __ verify_oop(Otos_i); |
738 __ verify_oop(Otos_i); |
739 __ index_check_without_pop(O3, O2, LogBytesPerWord, G3_scratch, O1); |
739 __ index_check_without_pop(O3, O2, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O1); |
740 |
740 |
741 // do array store check - check for NULL value first |
741 // do array store check - check for NULL value first |
742 __ br_null( Otos_i, false, Assembler::pn, is_null ); |
742 __ br_null( Otos_i, false, Assembler::pn, is_null ); |
743 __ delayed()-> |
743 __ delayed()->nop(); |
744 ld_ptr(O3, oopDesc::klass_offset_in_bytes(), O4); // get array klass |
744 |
|
745 __ load_klass(O3, O4); // get array klass |
|
746 __ load_klass(Otos_i, O5); // get value klass |
745 |
747 |
746 // do fast instanceof cache test |
748 // do fast instanceof cache test |
747 __ ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), O5); // get value klass |
|
748 |
749 |
749 __ ld_ptr(O4, sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes(), O4); |
750 __ ld_ptr(O4, sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes(), O4); |
750 |
751 |
751 assert(Otos_i == O0, "just checking"); |
752 assert(Otos_i == O0, "just checking"); |
752 |
753 |
764 // Not a subtype; so must throw exception |
765 // Not a subtype; so must throw exception |
765 __ throw_if_not_x( Assembler::never, Interpreter::_throw_ArrayStoreException_entry, G3_scratch ); |
766 __ throw_if_not_x( Assembler::never, Interpreter::_throw_ArrayStoreException_entry, G3_scratch ); |
766 |
767 |
767 // Store is OK. |
768 // Store is OK. |
768 __ bind(store_ok); |
769 __ bind(store_ok); |
769 __ st_ptr(Otos_i, O1, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
770 __ store_heap_oop(Otos_i, O1, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
770 // Quote from rememberedSet.hpp: For objArrays, the precise card |
771 // Quote from rememberedSet.hpp: For objArrays, the precise card |
771 // corresponding to the pointer store is dirtied so we don't need to |
772 // corresponding to the pointer store is dirtied so we don't need to |
772 // scavenge the entire array. |
773 // scavenge the entire array. |
773 Address element(O1, 0, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
774 Address element(O1, 0, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
774 __ add(element, O1); // address the element precisely |
775 __ add(element, O1); // address the element precisely |
775 __ store_check(G3_scratch, O1); |
776 __ store_check(G3_scratch, O1); |
776 __ ba(false,done); |
777 __ ba(false,done); |
777 __ delayed()->inc(Lesp, 3* Interpreter::stackElementSize()); // adj sp (pops array, index and value) |
778 __ delayed()->inc(Lesp, 3* Interpreter::stackElementSize()); // adj sp (pops array, index and value) |
778 |
779 |
779 __ bind(is_null); |
780 __ bind(is_null); |
780 __ st_ptr(Otos_i, element); |
781 __ store_heap_oop(Otos_i, element); |
781 __ profile_null_seen(G3_scratch); |
782 __ profile_null_seen(G3_scratch); |
782 __ inc(Lesp, 3* Interpreter::stackElementSize()); // adj sp (pops array, index and value) |
783 __ inc(Lesp, 3* Interpreter::stackElementSize()); // adj sp (pops array, index and value) |
783 __ bind(done); |
784 __ bind(done); |
784 } |
785 } |
785 |
786 |
1831 |
1832 |
1832 if (_desc->bytecode() == Bytecodes::_return_register_finalizer) { |
1833 if (_desc->bytecode() == Bytecodes::_return_register_finalizer) { |
1833 assert(state == vtos, "only valid state"); |
1834 assert(state == vtos, "only valid state"); |
1834 __ mov(G0, G3_scratch); |
1835 __ mov(G0, G3_scratch); |
1835 __ access_local_ptr(G3_scratch, Otos_i); |
1836 __ access_local_ptr(G3_scratch, Otos_i); |
1836 __ ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), O2); |
1837 __ load_klass(Otos_i, O2); |
1837 __ set(JVM_ACC_HAS_FINALIZER, G3); |
1838 __ set(JVM_ACC_HAS_FINALIZER, G3); |
1838 __ ld(O2, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc), O2); |
1839 __ ld(O2, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc), O2); |
1839 __ andcc(G3, O2, G0); |
1840 __ andcc(G3, O2, G0); |
1840 Label skip_register_finalizer; |
1841 Label skip_register_finalizer; |
1841 __ br(Assembler::zero, false, Assembler::pn, skip_register_finalizer); |
1842 __ br(Assembler::zero, false, Assembler::pn, skip_register_finalizer); |
2076 __ cmp(Rflags, atos); |
2077 __ cmp(Rflags, atos); |
2077 __ br(Assembler::notEqual, false, Assembler::pt, notObj); |
2078 __ br(Assembler::notEqual, false, Assembler::pt, notObj); |
2078 __ delayed() ->cmp(Rflags, itos); |
2079 __ delayed() ->cmp(Rflags, itos); |
2079 |
2080 |
2080 // atos |
2081 // atos |
2081 __ ld_ptr(Rclass, Roffset, Otos_i); |
2082 __ load_heap_oop(Rclass, Roffset, Otos_i); |
2082 __ verify_oop(Otos_i); |
2083 __ verify_oop(Otos_i); |
2083 __ push(atos); |
2084 __ push(atos); |
2084 if (!is_static) { |
2085 if (!is_static) { |
2085 patch_bytecode(Bytecodes::_fast_agetfield, G3_scratch, G4_scratch); |
2086 patch_bytecode(Bytecodes::_fast_agetfield, G3_scratch, G4_scratch); |
2086 } |
2087 } |
2257 break; |
2258 break; |
2258 case Bytecodes::_fast_dgetfield: |
2259 case Bytecodes::_fast_dgetfield: |
2259 __ ldf(FloatRegisterImpl::D, Otos_i, Roffset, Ftos_d); |
2260 __ ldf(FloatRegisterImpl::D, Otos_i, Roffset, Ftos_d); |
2260 break; |
2261 break; |
2261 case Bytecodes::_fast_agetfield: |
2262 case Bytecodes::_fast_agetfield: |
2262 __ ld_ptr(Otos_i, Roffset, Otos_i); |
2263 __ load_heap_oop(Otos_i, Roffset, Otos_i); |
2263 break; |
2264 break; |
2264 default: |
2265 default: |
2265 ShouldNotReachHere(); |
2266 ShouldNotReachHere(); |
2266 } |
2267 } |
2267 |
2268 |
2446 __ delayed() ->cmp(Rflags, itos ); |
2447 __ delayed() ->cmp(Rflags, itos ); |
2447 |
2448 |
2448 // atos |
2449 // atos |
2449 __ pop_ptr(); |
2450 __ pop_ptr(); |
2450 __ verify_oop(Otos_i); |
2451 __ verify_oop(Otos_i); |
2451 __ st_ptr(Otos_i, Rclass, Roffset); |
2452 __ store_heap_oop(Otos_i, Rclass, Roffset); |
2452 __ store_check(G1_scratch, Rclass, Roffset); |
2453 __ store_check(G1_scratch, Rclass, Roffset); |
2453 __ ba(false, checkVolatile); |
2454 __ ba(false, checkVolatile); |
2454 __ delayed()->tst(Lscratch); |
2455 __ delayed()->tst(Lscratch); |
2455 |
2456 |
2456 __ bind(notObj); |
2457 __ bind(notObj); |
2488 |
2489 |
2489 // atos |
2490 // atos |
2490 __ pop_ptr(); |
2491 __ pop_ptr(); |
2491 pop_and_check_object(Rclass); |
2492 pop_and_check_object(Rclass); |
2492 __ verify_oop(Otos_i); |
2493 __ verify_oop(Otos_i); |
2493 __ st_ptr(Otos_i, Rclass, Roffset); |
2494 __ store_heap_oop(Otos_i, Rclass, Roffset); |
2494 __ store_check(G1_scratch, Rclass, Roffset); |
2495 __ store_check(G1_scratch, Rclass, Roffset); |
2495 patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch); |
2496 patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch); |
2496 __ ba(false, checkVolatile); |
2497 __ ba(false, checkVolatile); |
2497 __ delayed()->tst(Lscratch); |
2498 __ delayed()->tst(Lscratch); |
2498 |
2499 |
2643 break; |
2644 break; |
2644 case Bytecodes::_fast_dputfield: |
2645 case Bytecodes::_fast_dputfield: |
2645 __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset); |
2646 __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset); |
2646 break; |
2647 break; |
2647 case Bytecodes::_fast_aputfield: |
2648 case Bytecodes::_fast_aputfield: |
2648 __ st_ptr(Otos_i, Rclass, Roffset); |
2649 __ store_heap_oop(Otos_i, Rclass, Roffset); |
2649 __ store_check(G1_scratch, Rclass, Roffset); |
2650 __ store_check(G1_scratch, Rclass, Roffset); |
2650 break; |
2651 break; |
2651 default: |
2652 default: |
2652 ShouldNotReachHere(); |
2653 ShouldNotReachHere(); |
2653 } |
2654 } |
2686 __ add(Lbcp, 1, Lbcp); // needed to report exception at the correct bcp |
2687 __ add(Lbcp, 1, Lbcp); // needed to report exception at the correct bcp |
2687 |
2688 |
2688 __ verify_oop(Rreceiver); |
2689 __ verify_oop(Rreceiver); |
2689 __ null_check(Rreceiver); |
2690 __ null_check(Rreceiver); |
2690 if (state == atos) { |
2691 if (state == atos) { |
2691 __ ld_ptr(Rreceiver, Roffset, Otos_i); |
2692 __ load_heap_oop(Rreceiver, Roffset, Otos_i); |
2692 } else if (state == itos) { |
2693 } else if (state == itos) { |
2693 __ ld (Rreceiver, Roffset, Otos_i) ; |
2694 __ ld (Rreceiver, Roffset, Otos_i) ; |
2694 } else if (state == ftos) { |
2695 } else if (state == ftos) { |
2695 __ ldf(FloatRegisterImpl::S, Rreceiver, Roffset, Ftos_f); |
2696 __ ldf(FloatRegisterImpl::S, Rreceiver, Roffset, Ftos_f); |
2696 } else { |
2697 } else { |
2788 __ sll(Rret, LogBytesPerWord, Rret); |
2789 __ sll(Rret, LogBytesPerWord, Rret); |
2789 __ ld_ptr(Rtemp, Rret, Rret); // get return address |
2790 __ ld_ptr(Rtemp, Rret, Rret); // get return address |
2790 |
2791 |
2791 // get receiver klass |
2792 // get receiver klass |
2792 __ null_check(O0, oopDesc::klass_offset_in_bytes()); |
2793 __ null_check(O0, oopDesc::klass_offset_in_bytes()); |
2793 __ ld_ptr(Address(O0, 0, oopDesc::klass_offset_in_bytes()), Rrecv); |
2794 __ load_klass(O0, Rrecv); |
2794 __ verify_oop(Rrecv); |
2795 __ verify_oop(Rrecv); |
2795 |
2796 |
2796 __ profile_virtual_call(Rrecv, O4); |
2797 __ profile_virtual_call(Rrecv, O4); |
2797 |
2798 |
2798 generate_vtable_call(Rrecv, Rscratch, Rret); |
2799 generate_vtable_call(Rrecv, Rscratch, Rret); |
2956 __ sll(Rret, LogBytesPerWord, Rret); |
2957 __ sll(Rret, LogBytesPerWord, Rret); |
2957 __ ld_ptr(Rscratch, Rret, Rret); // get return address |
2958 __ ld_ptr(Rscratch, Rret, Rret); // get return address |
2958 |
2959 |
2959 // get receiver klass |
2960 // get receiver klass |
2960 __ null_check(O0, oopDesc::klass_offset_in_bytes()); |
2961 __ null_check(O0, oopDesc::klass_offset_in_bytes()); |
2961 __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), RklassOop); |
2962 __ load_klass(O0, RklassOop); |
2962 __ verify_oop(RklassOop); |
2963 __ verify_oop(RklassOop); |
2963 |
2964 |
2964 // Special case of invokeinterface called for virtual method of |
2965 // Special case of invokeinterface called for virtual method of |
2965 // java.lang.Object. See cpCacheOop.cpp for details. |
2966 // java.lang.Object. See cpCacheOop.cpp for details. |
2966 // This code isn't produced by javac, but could be produced by |
2967 // This code isn't produced by javac, but could be produced by |
3219 __ ld_ptr(RinstanceKlass, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), G4_scratch); |
3220 __ ld_ptr(RinstanceKlass, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), G4_scratch); |
3220 } else { |
3221 } else { |
3221 __ set((intptr_t)markOopDesc::prototype(), G4_scratch); |
3222 __ set((intptr_t)markOopDesc::prototype(), G4_scratch); |
3222 } |
3223 } |
3223 __ st_ptr(G4_scratch, RallocatedObject, oopDesc::mark_offset_in_bytes()); // mark |
3224 __ st_ptr(G4_scratch, RallocatedObject, oopDesc::mark_offset_in_bytes()); // mark |
3224 __ st_ptr(RinstanceKlass, RallocatedObject, oopDesc::klass_offset_in_bytes()); // klass |
3225 __ store_klass(RinstanceKlass, RallocatedObject); // klass |
3225 |
3226 |
3226 { |
3227 { |
3227 SkipIfEqual skip_if( |
3228 SkipIfEqual skip_if( |
3228 _masm, G4_scratch, &DTraceAllocProbes, Assembler::zero); |
3229 _masm, G4_scratch, &DTraceAllocProbes, Assembler::zero); |
3229 // Trigger dtrace event |
3230 // Trigger dtrace event |
3275 // Check for casting a NULL |
3276 // Check for casting a NULL |
3276 __ br_null(Otos_i, false, Assembler::pn, is_null); |
3277 __ br_null(Otos_i, false, Assembler::pn, is_null); |
3277 __ delayed()->nop(); |
3278 __ delayed()->nop(); |
3278 |
3279 |
3279 // Get value klass in RobjKlass |
3280 // Get value klass in RobjKlass |
3280 __ ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), RobjKlass); // get value klass |
3281 __ load_klass(Otos_i, RobjKlass); // get value klass |
3281 |
3282 |
3282 // Get constant pool tag |
3283 // Get constant pool tag |
3283 __ get_2_byte_integer_at_bcp(1, Lscratch, Roffset, InterpreterMacroAssembler::Unsigned); |
3284 __ get_2_byte_integer_at_bcp(1, Lscratch, Roffset, InterpreterMacroAssembler::Unsigned); |
3284 |
3285 |
3285 // See if the checkcast has been quickened |
3286 // See if the checkcast has been quickened |
3293 __ push_ptr(); // save receiver for result, and for GC |
3294 __ push_ptr(); // save receiver for result, and for GC |
3294 call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); |
3295 call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); |
3295 __ pop_ptr(Otos_i, G3_scratch); // restore receiver |
3296 __ pop_ptr(Otos_i, G3_scratch); // restore receiver |
3296 |
3297 |
3297 __ br(Assembler::always, false, Assembler::pt, resolved); |
3298 __ br(Assembler::always, false, Assembler::pt, resolved); |
3298 __ delayed()->ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), RobjKlass); // get value klass |
3299 __ delayed()->nop(); |
3299 |
3300 |
3300 // Extract target class from constant pool |
3301 // Extract target class from constant pool |
3301 __ bind(quicked); |
3302 __ bind(quicked); |
3302 __ add(Roffset, sizeof(constantPoolOopDesc), Roffset); |
3303 __ add(Roffset, sizeof(constantPoolOopDesc), Roffset); |
3303 __ ld_ptr(Lscratch, Roffset, RspecifiedKlass); |
3304 __ ld_ptr(Lscratch, Roffset, RspecifiedKlass); |
3304 __ bind(resolved); |
3305 __ bind(resolved); |
|
3306 __ load_klass(Otos_i, RobjKlass); // get value klass |
3305 |
3307 |
3306 // Generate a fast subtype check. Branch to cast_ok if no |
3308 // Generate a fast subtype check. Branch to cast_ok if no |
3307 // failure. Throw exception if failure. |
3309 // failure. Throw exception if failure. |
3308 __ gen_subtype_check( RobjKlass, RspecifiedKlass, G3_scratch, G4_scratch, G1_scratch, cast_ok ); |
3310 __ gen_subtype_check( RobjKlass, RspecifiedKlass, G3_scratch, G4_scratch, G1_scratch, cast_ok ); |
3309 |
3311 |
3332 // Check for casting a NULL |
3334 // Check for casting a NULL |
3333 __ br_null(Otos_i, false, Assembler::pt, is_null); |
3335 __ br_null(Otos_i, false, Assembler::pt, is_null); |
3334 __ delayed()->nop(); |
3336 __ delayed()->nop(); |
3335 |
3337 |
3336 // Get value klass in RobjKlass |
3338 // Get value klass in RobjKlass |
3337 __ ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), RobjKlass); // get value klass |
3339 __ load_klass(Otos_i, RobjKlass); // get value klass |
3338 |
3340 |
3339 // Get constant pool tag |
3341 // Get constant pool tag |
3340 __ get_2_byte_integer_at_bcp(1, Lscratch, Roffset, InterpreterMacroAssembler::Unsigned); |
3342 __ get_2_byte_integer_at_bcp(1, Lscratch, Roffset, InterpreterMacroAssembler::Unsigned); |
3341 |
3343 |
3342 // See if the checkcast has been quickened |
3344 // See if the checkcast has been quickened |
3350 __ push_ptr(); // save receiver for result, and for GC |
3352 __ push_ptr(); // save receiver for result, and for GC |
3351 call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); |
3353 call_VM(RspecifiedKlass, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); |
3352 __ pop_ptr(Otos_i, G3_scratch); // restore receiver |
3354 __ pop_ptr(Otos_i, G3_scratch); // restore receiver |
3353 |
3355 |
3354 __ br(Assembler::always, false, Assembler::pt, resolved); |
3356 __ br(Assembler::always, false, Assembler::pt, resolved); |
3355 __ delayed()->ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), RobjKlass); // get value klass |
3357 __ delayed()->nop(); |
3356 |
3358 |
3357 |
3359 |
3358 // Extract target class from constant pool |
3360 // Extract target class from constant pool |
3359 __ bind(quicked); |
3361 __ bind(quicked); |
3360 __ add(Roffset, sizeof(constantPoolOopDesc), Roffset); |
3362 __ add(Roffset, sizeof(constantPoolOopDesc), Roffset); |
3361 __ get_constant_pool(Lscratch); |
3363 __ get_constant_pool(Lscratch); |
3362 __ ld_ptr(Lscratch, Roffset, RspecifiedKlass); |
3364 __ ld_ptr(Lscratch, Roffset, RspecifiedKlass); |
3363 __ bind(resolved); |
3365 __ bind(resolved); |
|
3366 __ load_klass(Otos_i, RobjKlass); // get value klass |
3364 |
3367 |
3365 // Generate a fast subtype check. Branch to cast_ok if no |
3368 // Generate a fast subtype check. Branch to cast_ok if no |
3366 // failure. Return 0 if failure. |
3369 // failure. Return 0 if failure. |
3367 __ or3(G0, 1, Otos_i); // set result assuming quick tests succeed |
3370 __ or3(G0, 1, Otos_i); // set result assuming quick tests succeed |
3368 __ gen_subtype_check( RobjKlass, RspecifiedKlass, G3_scratch, G4_scratch, G1_scratch, done ); |
3371 __ gen_subtype_check( RobjKlass, RspecifiedKlass, G3_scratch, G4_scratch, G1_scratch, done ); |