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 );