Mercurial > hg > graal-jvmci-8
comparison src/cpu/sparc/vm/templateTable_sparc.cpp @ 113:ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv
Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author | coleenp |
---|---|
date | Sun, 13 Apr 2008 17:43:42 -0400 |
parents | a61af66fc99e |
children | feeb96a45707 37f87013dfd8 |
comparison
equal
deleted
inserted
replaced
110:a49a647afe9a | 113:ba764ed4b6f2 |
---|---|
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 ); |