comparison src/cpu/x86/vm/templateTable_x86_64.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
555 transition(itos, atos); 555 transition(itos, atos);
556 __ pop_ptr(rdx); 556 __ pop_ptr(rdx);
557 // eax: index 557 // eax: index
558 // rdx: array 558 // rdx: array
559 index_check(rdx, rax); // kills rbx 559 index_check(rdx, rax); // kills rbx
560 __ movq(rax, Address(rdx, rax, 560 __ load_heap_oop(rax, Address(rdx, rax,
561 Address::times_8, 561 UseCompressedOops ? Address::times_4 : Address::times_8,
562 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); 562 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
563 } 563 }
564 564
565 void TemplateTable::baload() { 565 void TemplateTable::baload() {
566 transition(itos, itos); 566 transition(itos, itos);
868 // do array store check - check for NULL value first 868 // do array store check - check for NULL value first
869 __ testq(rax, rax); 869 __ testq(rax, rax);
870 __ jcc(Assembler::zero, is_null); 870 __ jcc(Assembler::zero, is_null);
871 871
872 // Move subklass into rbx 872 // Move subklass into rbx
873 __ movq(rbx, Address(rax, oopDesc::klass_offset_in_bytes())); 873 __ load_klass(rbx, rax);
874 // Move superklass into rax 874 // Move superklass into rax
875 __ movq(rax, Address(rdx, oopDesc::klass_offset_in_bytes())); 875 __ load_klass(rax, rdx);
876 __ movq(rax, Address(rax, 876 __ movq(rax, Address(rax,
877 sizeof(oopDesc) + 877 sizeof(oopDesc) +
878 objArrayKlass::element_klass_offset_in_bytes())); 878 objArrayKlass::element_klass_offset_in_bytes()));
879 // Compress array + index*8 + 12 into a single register. Frees rcx. 879 // Compress array + index*oopSize + 12 into a single register. Frees rcx.
880 __ leaq(rdx, Address(rdx, rcx, 880 __ leaq(rdx, Address(rdx, rcx,
881 Address::times_8, 881 UseCompressedOops ? Address::times_4 : Address::times_8,
882 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); 882 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
883 883
884 // Generate subtype check. Blows rcx, rdi 884 // Generate subtype check. Blows rcx, rdi
885 // Superklass in rax. Subklass in rbx. 885 // Superklass in rax. Subklass in rbx.
886 __ gen_subtype_check(rbx, ok_is_subtype); 886 __ gen_subtype_check(rbx, ok_is_subtype);
890 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry)); 890 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry));
891 891
892 // Come here on success 892 // Come here on success
893 __ bind(ok_is_subtype); 893 __ bind(ok_is_subtype);
894 __ movq(rax, at_tos()); // Value 894 __ movq(rax, at_tos()); // Value
895 __ movq(Address(rdx, 0), rax); 895 __ store_heap_oop(Address(rdx, 0), rax);
896 __ store_check(rdx); 896 __ store_check(rdx);
897 __ jmp(done); 897 __ jmp(done);
898 898
899 // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx] 899 // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx]
900 __ bind(is_null); 900 __ bind(is_null);
901 __ profile_null_seen(rbx); 901 __ profile_null_seen(rbx);
902 __ movq(Address(rdx, rcx, 902 __ store_heap_oop(Address(rdx, rcx,
903 Address::times_8, 903 UseCompressedOops ? Address::times_4 : Address::times_8,
904 arrayOopDesc::base_offset_in_bytes(T_OBJECT)), 904 arrayOopDesc::base_offset_in_bytes(T_OBJECT)),
905 rax); 905 rax);
906 906
907 // Pop stack arguments 907 // Pop stack arguments
908 __ bind(done); 908 __ bind(done);
909 __ addq(rsp, 3 * Interpreter::stackElementSize()); 909 __ addq(rsp, 3 * Interpreter::stackElementSize());
910 } 910 }
1932 "inconsistent calls_vm information"); // call in remove_activation 1932 "inconsistent calls_vm information"); // call in remove_activation
1933 1933
1934 if (_desc->bytecode() == Bytecodes::_return_register_finalizer) { 1934 if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
1935 assert(state == vtos, "only valid state"); 1935 assert(state == vtos, "only valid state");
1936 __ movq(c_rarg1, aaddress(0)); 1936 __ movq(c_rarg1, aaddress(0));
1937 __ movq(rdi, Address(c_rarg1, oopDesc::klass_offset_in_bytes())); 1937 __ load_klass(rdi, c_rarg1);
1938 __ movl(rdi, Address(rdi, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc))); 1938 __ movl(rdi, Address(rdi, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc)));
1939 __ testl(rdi, JVM_ACC_HAS_FINALIZER); 1939 __ testl(rdi, JVM_ACC_HAS_FINALIZER);
1940 Label skip_register_finalizer; 1940 Label skip_register_finalizer;
1941 __ jcc(Assembler::zero, skip_register_finalizer); 1941 __ jcc(Assembler::zero, skip_register_finalizer);
1942 1942
2182 2182
2183 __ bind(notByte); 2183 __ bind(notByte);
2184 __ cmpl(flags, atos); 2184 __ cmpl(flags, atos);
2185 __ jcc(Assembler::notEqual, notObj); 2185 __ jcc(Assembler::notEqual, notObj);
2186 // atos 2186 // atos
2187 __ movq(rax, field); 2187 __ load_heap_oop(rax, field);
2188 __ push(atos); 2188 __ push(atos);
2189 if (!is_static) { 2189 if (!is_static) {
2190 patch_bytecode(Bytecodes::_fast_agetfield, bc, rbx); 2190 patch_bytecode(Bytecodes::_fast_agetfield, bc, rbx);
2191 } 2191 }
2192 __ jmp(Done); 2192 __ jmp(Done);
2392 __ cmpl(flags, atos); 2392 __ cmpl(flags, atos);
2393 __ jcc(Assembler::notEqual, notObj); 2393 __ jcc(Assembler::notEqual, notObj);
2394 // atos 2394 // atos
2395 __ pop(atos); 2395 __ pop(atos);
2396 if (!is_static) pop_and_check_object(obj); 2396 if (!is_static) pop_and_check_object(obj);
2397 __ movq(field, rax); 2397 __ store_heap_oop(field, rax);
2398 __ store_check(obj, field); // Need to mark card 2398 __ store_check(obj, field); // Need to mark card
2399 if (!is_static) { 2399 if (!is_static) {
2400 patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx); 2400 patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx);
2401 } 2401 }
2402 __ jmp(Done); 2402 __ jmp(Done);
2513 __ subq(rsp, sizeof(jvalue)); // add space for a jvalue object 2513 __ subq(rsp, sizeof(jvalue)); // add space for a jvalue object
2514 __ movq(c_rarg3, rsp); 2514 __ movq(c_rarg3, rsp);
2515 const Address field(c_rarg3, 0); 2515 const Address field(c_rarg3, 0);
2516 2516
2517 switch (bytecode()) { // load values into the jvalue object 2517 switch (bytecode()) { // load values into the jvalue object
2518 case Bytecodes::_fast_aputfield: // fall through 2518 case Bytecodes::_fast_aputfield: __ movq(field, rax); break;
2519 case Bytecodes::_fast_lputfield: __ movq(field, rax); break; 2519 case Bytecodes::_fast_lputfield: __ movq(field, rax); break;
2520 case Bytecodes::_fast_iputfield: __ movl(field, rax); break; 2520 case Bytecodes::_fast_iputfield: __ movl(field, rax); break;
2521 case Bytecodes::_fast_bputfield: __ movb(field, rax); break; 2521 case Bytecodes::_fast_bputfield: __ movb(field, rax); break;
2522 case Bytecodes::_fast_sputfield: // fall through 2522 case Bytecodes::_fast_sputfield: // fall through
2523 case Bytecodes::_fast_cputfield: __ movw(field, rax); break; 2523 case Bytecodes::_fast_cputfield: __ movw(field, rax); break;
2580 const Address field(rcx, rbx, Address::times_1); 2580 const Address field(rcx, rbx, Address::times_1);
2581 2581
2582 // access field 2582 // access field
2583 switch (bytecode()) { 2583 switch (bytecode()) {
2584 case Bytecodes::_fast_aputfield: 2584 case Bytecodes::_fast_aputfield:
2585 __ movq(field, rax); 2585 __ store_heap_oop(field, rax);
2586 __ store_check(rcx, field); 2586 __ store_check(rcx, field);
2587 break; 2587 break;
2588 case Bytecodes::_fast_lputfield: 2588 case Bytecodes::_fast_lputfield:
2589 __ movq(field, rax); 2589 __ movq(field, rax);
2590 break; 2590 break;
2629 __ mov32(rcx, ExternalAddress((address) JvmtiExport::get_field_access_count_addr())); 2629 __ mov32(rcx, ExternalAddress((address) JvmtiExport::get_field_access_count_addr()));
2630 __ testl(rcx, rcx); 2630 __ testl(rcx, rcx);
2631 __ jcc(Assembler::zero, L1); 2631 __ jcc(Assembler::zero, L1);
2632 // access constant pool cache entry 2632 // access constant pool cache entry
2633 __ get_cache_entry_pointer_at_bcp(c_rarg2, rcx, 1); 2633 __ get_cache_entry_pointer_at_bcp(c_rarg2, rcx, 1);
2634 __ verify_oop(rax);
2634 __ movq(r12, rax); // save object pointer before call_VM() clobbers it 2635 __ movq(r12, rax); // save object pointer before call_VM() clobbers it
2635 __ verify_oop(rax);
2636 __ movq(c_rarg1, rax); 2636 __ movq(c_rarg1, rax);
2637 // c_rarg1: object pointer copied above 2637 // c_rarg1: object pointer copied above
2638 // c_rarg2: cache entry pointer 2638 // c_rarg2: cache entry pointer
2639 __ call_VM(noreg, 2639 __ call_VM(noreg,
2640 CAST_FROM_FN_PTR(address, 2640 CAST_FROM_FN_PTR(address,
2641 InterpreterRuntime::post_field_access), 2641 InterpreterRuntime::post_field_access),
2642 c_rarg1, c_rarg2); 2642 c_rarg1, c_rarg2);
2643 __ movq(rax, r12); // restore object pointer 2643 __ movq(rax, r12); // restore object pointer
2644 __ reinit_heapbase();
2644 __ bind(L1); 2645 __ bind(L1);
2645 } 2646 }
2646 2647
2647 // access constant pool cache 2648 // access constant pool cache
2648 __ get_cache_and_index_at_bcp(rcx, rbx, 1); 2649 __ get_cache_and_index_at_bcp(rcx, rbx, 1);
2665 Address field(rax, rbx, Address::times_1); 2666 Address field(rax, rbx, Address::times_1);
2666 2667
2667 // access field 2668 // access field
2668 switch (bytecode()) { 2669 switch (bytecode()) {
2669 case Bytecodes::_fast_agetfield: 2670 case Bytecodes::_fast_agetfield:
2670 __ movq(rax, field); 2671 __ load_heap_oop(rax, field);
2671 __ verify_oop(rax); 2672 __ verify_oop(rax);
2672 break; 2673 break;
2673 case Bytecodes::_fast_lgetfield: 2674 case Bytecodes::_fast_lgetfield:
2674 __ movq(rax, field); 2675 __ movq(rax, field);
2675 break; 2676 break;
2723 switch (state) { 2724 switch (state) {
2724 case itos: 2725 case itos:
2725 __ movl(rax, Address(rax, rbx, Address::times_1)); 2726 __ movl(rax, Address(rax, rbx, Address::times_1));
2726 break; 2727 break;
2727 case atos: 2728 case atos:
2728 __ movq(rax, Address(rax, rbx, Address::times_1)); 2729 __ load_heap_oop(rax, Address(rax, rbx, Address::times_1));
2729 __ verify_oop(rax); 2730 __ verify_oop(rax);
2730 break; 2731 break;
2731 case ftos: 2732 case ftos:
2732 __ movflt(xmm0, Address(rax, rbx, Address::times_1)); 2733 __ movflt(xmm0, Address(rax, rbx, Address::times_1));
2733 break; 2734 break;
2785 // load receiver if needed (note: no return address pushed yet) 2786 // load receiver if needed (note: no return address pushed yet)
2786 if (load_receiver) { 2787 if (load_receiver) {
2787 __ movl(recv, flags); 2788 __ movl(recv, flags);
2788 __ andl(recv, 0xFF); 2789 __ andl(recv, 0xFF);
2789 if (TaggedStackInterpreter) __ shll(recv, 1); // index*2 2790 if (TaggedStackInterpreter) __ shll(recv, 1); // index*2
2790 __ movq(recv, Address(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1))); 2791 __ movq(recv, Address(rsp, recv, Address::times_8,
2792 -Interpreter::expr_offset_in_bytes(1)));
2791 __ verify_oop(recv); 2793 __ verify_oop(recv);
2792 } 2794 }
2793 2795
2794 // do null check if needed 2796 // do null check if needed
2795 if (receiver_null_check) { 2797 if (receiver_null_check) {
2852 2854
2853 __ bind(notFinal); 2855 __ bind(notFinal);
2854 2856
2855 // get receiver klass 2857 // get receiver klass
2856 __ null_check(recv, oopDesc::klass_offset_in_bytes()); 2858 __ null_check(recv, oopDesc::klass_offset_in_bytes());
2857 __ movq(rax, Address(recv, oopDesc::klass_offset_in_bytes())); 2859 __ load_klass(rax, recv);
2858 2860
2859 __ verify_oop(rax); 2861 __ verify_oop(rax);
2860 2862
2861 // profile this call 2863 // profile this call
2862 __ profile_virtual_call(rax, r14, rdx); 2864 __ profile_virtual_call(rax, r14, rdx);
2864 // get target methodOop & entry point 2866 // get target methodOop & entry point
2865 const int base = instanceKlass::vtable_start_offset() * wordSize; 2867 const int base = instanceKlass::vtable_start_offset() * wordSize;
2866 assert(vtableEntry::size() * wordSize == 8, 2868 assert(vtableEntry::size() * wordSize == 8,
2867 "adjust the scaling in the code below"); 2869 "adjust the scaling in the code below");
2868 __ movq(method, Address(rax, index, 2870 __ movq(method, Address(rax, index,
2869 Address::times_8, 2871 Address::times_8,
2870 base + vtableEntry::method_offset_in_bytes())); 2872 base + vtableEntry::method_offset_in_bytes()));
2871 __ movq(rdx, Address(method, methodOopDesc::interpreter_entry_offset())); 2873 __ movq(rdx, Address(method, methodOopDesc::interpreter_entry_offset()));
2872 __ jump_from_interpreted(method, rdx); 2874 __ jump_from_interpreted(method, rdx);
2873 } 2875 }
2874 2876
2875 2877
2930 invokevirtual_helper(rbx, rcx, rdx); 2932 invokevirtual_helper(rbx, rcx, rdx);
2931 __ bind(notMethod); 2933 __ bind(notMethod);
2932 2934
2933 // Get receiver klass into rdx - also a null check 2935 // Get receiver klass into rdx - also a null check
2934 __ restore_locals(); // restore r14 2936 __ restore_locals(); // restore r14
2935 __ movq(rdx, Address(rcx, oopDesc::klass_offset_in_bytes())); 2937 __ load_klass(rdx, rcx);
2936 __ verify_oop(rdx); 2938 __ verify_oop(rdx);
2937 2939
2938 // profile this call 2940 // profile this call
2939 __ profile_virtual_call(rdx, r13, r14); 2941 __ profile_virtual_call(rdx, r13, r14);
2940 2942
3159 __ movq(Address(rax, oopDesc::mark_offset_in_bytes()), rscratch1); 3161 __ movq(Address(rax, oopDesc::mark_offset_in_bytes()), rscratch1);
3160 } else { 3162 } else {
3161 __ movptr(Address(rax, oopDesc::mark_offset_in_bytes()), 3163 __ movptr(Address(rax, oopDesc::mark_offset_in_bytes()),
3162 (intptr_t) markOopDesc::prototype()); // header (address 0x1) 3164 (intptr_t) markOopDesc::prototype()); // header (address 0x1)
3163 } 3165 }
3164 __ movq(Address(rax, oopDesc::klass_offset_in_bytes()), rsi); // klass 3166 __ store_klass(rax, rsi); // klass
3165 __ jmp(done); 3167 __ jmp(done);
3166 } 3168 }
3167 3169
3168 { 3170 {
3169 SkipIfEqual skip(_masm, &DTraceAllocProbes, false); 3171 SkipIfEqual skip(_masm, &DTraceAllocProbes, false);
3221 __ cmpb(Address(rdx, rbx, 3223 __ cmpb(Address(rdx, rbx,
3222 Address::times_1, 3224 Address::times_1,
3223 typeArrayOopDesc::header_size(T_BYTE) * wordSize), 3225 typeArrayOopDesc::header_size(T_BYTE) * wordSize),
3224 JVM_CONSTANT_Class); 3226 JVM_CONSTANT_Class);
3225 __ jcc(Assembler::equal, quicked); 3227 __ jcc(Assembler::equal, quicked);
3226 3228 __ push(atos); // save receiver for result, and for GC
3227 __ movq(r12, rcx); // save rcx XXX 3229 __ movq(r12, rcx); // save rcx XXX
3228 __ push(atos); // save receiver for result, and for GC
3229 call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc)); 3230 call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
3231 __ movq(rcx, r12); // restore rcx XXX
3232 __ reinit_heapbase();
3230 __ pop_ptr(rdx); // restore receiver 3233 __ pop_ptr(rdx); // restore receiver
3231 __ movq(rcx, r12); // restore rcx XXX
3232 __ jmpb(resolved); 3234 __ jmpb(resolved);
3233 3235
3234 // Get superklass in rax and subklass in rbx 3236 // Get superklass in rax and subklass in rbx
3235 __ bind(quicked); 3237 __ bind(quicked);
3236 __ movq(rdx, rax); // Save object in rdx; rax needed for subtype check 3238 __ movq(rdx, rax); // Save object in rdx; rax needed for subtype check
3237 __ movq(rax, Address(rcx, rbx, 3239 __ movq(rax, Address(rcx, rbx,
3238 Address::times_8, sizeof(constantPoolOopDesc))); 3240 Address::times_8, sizeof(constantPoolOopDesc)));
3239 3241
3240 __ bind(resolved); 3242 __ bind(resolved);
3241 __ movq(rbx, Address(rdx, oopDesc::klass_offset_in_bytes())); 3243 __ load_klass(rbx, rdx);
3242 3244
3243 // Generate subtype check. Blows rcx, rdi. Object in rdx. 3245 // Generate subtype check. Blows rcx, rdi. Object in rdx.
3244 // Superklass in rax. Subklass in rbx. 3246 // Superklass in rax. Subklass in rbx.
3245 __ gen_subtype_check(rbx, ok_is_subtype); 3247 __ gen_subtype_check(rbx, ok_is_subtype);
3246 3248
3278 Address::times_1, 3280 Address::times_1,
3279 typeArrayOopDesc::header_size(T_BYTE) * wordSize), 3281 typeArrayOopDesc::header_size(T_BYTE) * wordSize),
3280 JVM_CONSTANT_Class); 3282 JVM_CONSTANT_Class);
3281 __ jcc(Assembler::equal, quicked); 3283 __ jcc(Assembler::equal, quicked);
3282 3284
3285 __ push(atos); // save receiver for result, and for GC
3283 __ movq(r12, rcx); // save rcx 3286 __ movq(r12, rcx); // save rcx
3284 __ push(atos); // save receiver for result, and for GC
3285 call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc)); 3287 call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
3288 __ movq(rcx, r12); // restore rcx
3289 __ reinit_heapbase();
3286 __ pop_ptr(rdx); // restore receiver 3290 __ pop_ptr(rdx); // restore receiver
3287 __ movq(rdx, Address(rdx, oopDesc::klass_offset_in_bytes())); 3291 __ load_klass(rdx, rdx);
3288 __ movq(rcx, r12); // restore rcx
3289 __ jmpb(resolved); 3292 __ jmpb(resolved);
3290 3293
3291 // Get superklass in rax and subklass in rdx 3294 // Get superklass in rax and subklass in rdx
3292 __ bind(quicked); 3295 __ bind(quicked);
3293 __ movq(rdx, Address(rax, oopDesc::klass_offset_in_bytes())); 3296 __ load_klass(rdx, rax);
3294 __ movq(rax, Address(rcx, rbx, 3297 __ movq(rax, Address(rcx, rbx,
3295 Address::times_8, sizeof(constantPoolOopDesc))); 3298 Address::times_8, sizeof(constantPoolOopDesc)));
3296 3299
3297 __ bind(resolved); 3300 __ bind(resolved);
3298 3301
3299 // Generate subtype check. Blows rcx, rdi 3302 // Generate subtype check. Blows rcx, rdi
3300 // Superklass in rax. Subklass in rdx. 3303 // Superklass in rax. Subklass in rdx.