comparison src/cpu/x86/vm/templateTable_x86_64.cpp @ 628:7bb995fbd3c0

Merge
author trims
date Thu, 12 Mar 2009 18:16:36 -0700
parents 9adddb8c0fc8
children be93aad57795
comparison
equal deleted inserted replaced
580:ce2272390558 628:7bb995fbd3c0
305 __ load_signed_byte(rax, at_bcp(1)); 305 __ load_signed_byte(rax, at_bcp(1));
306 } 306 }
307 307
308 void TemplateTable::sipush() { 308 void TemplateTable::sipush() {
309 transition(vtos, itos); 309 transition(vtos, itos);
310 __ load_unsigned_word(rax, at_bcp(1)); 310 __ load_unsigned_short(rax, at_bcp(1));
311 __ bswapl(rax); 311 __ bswapl(rax);
312 __ sarl(rax, 16); 312 __ sarl(rax, 16);
313 } 313 }
314 314
315 void TemplateTable::ldc(bool wide) { 315 void TemplateTable::ldc(bool wide) {
643 transition(itos, itos); 643 transition(itos, itos);
644 __ pop_ptr(rdx); 644 __ pop_ptr(rdx);
645 // eax: index 645 // eax: index
646 // rdx: array 646 // rdx: array
647 index_check(rdx, rax); // kills rbx 647 index_check(rdx, rax); // kills rbx
648 __ load_unsigned_word(rax, 648 __ load_unsigned_short(rax,
649 Address(rdx, rax, 649 Address(rdx, rax,
650 Address::times_2, 650 Address::times_2,
651 arrayOopDesc::base_offset_in_bytes(T_CHAR))); 651 arrayOopDesc::base_offset_in_bytes(T_CHAR)));
652 } 652 }
653 653
654 // iload followed by caload frequent pair 654 // iload followed by caload frequent pair
655 void TemplateTable::fast_icaload() { 655 void TemplateTable::fast_icaload() {
656 transition(vtos, itos); 656 transition(vtos, itos);
661 661
662 // eax: index 662 // eax: index
663 // rdx: array 663 // rdx: array
664 __ pop_ptr(rdx); 664 __ pop_ptr(rdx);
665 index_check(rdx, rax); // kills rbx 665 index_check(rdx, rax); // kills rbx
666 __ load_unsigned_word(rax, 666 __ load_unsigned_short(rax,
667 Address(rdx, rax, 667 Address(rdx, rax,
668 Address::times_2, 668 Address::times_2,
669 arrayOopDesc::base_offset_in_bytes(T_CHAR))); 669 arrayOopDesc::base_offset_in_bytes(T_CHAR)));
670 } 670 }
671 671
672 void TemplateTable::saload() { 672 void TemplateTable::saload() {
673 transition(itos, itos); 673 transition(itos, itos);
674 __ pop_ptr(rdx); 674 __ pop_ptr(rdx);
675 // eax: index 675 // eax: index
676 // rdx: array 676 // rdx: array
677 index_check(rdx, rax); // kills rbx 677 index_check(rdx, rax); // kills rbx
678 __ load_signed_word(rax, 678 __ load_signed_short(rax,
679 Address(rdx, rax, 679 Address(rdx, rax,
680 Address::times_2, 680 Address::times_2,
681 arrayOopDesc::base_offset_in_bytes(T_SHORT))); 681 arrayOopDesc::base_offset_in_bytes(T_SHORT)));
682 } 682 }
683 683
684 void TemplateTable::iload(int n) { 684 void TemplateTable::iload(int n) {
685 transition(vtos, itos); 685 transition(vtos, itos);
686 __ movl(rax, iaddress(n)); 686 __ movl(rax, iaddress(n));
1557 } 1557 }
1558 __ movl2ptr(rdx, rdx); 1558 __ movl2ptr(rdx, rdx);
1559 1559
1560 // Handle all the JSR stuff here, then exit. 1560 // Handle all the JSR stuff here, then exit.
1561 // It's much shorter and cleaner than intermingling with the non-JSR 1561 // It's much shorter and cleaner than intermingling with the non-JSR
1562 // normal-branch stuff occuring below. 1562 // normal-branch stuff occurring below.
1563 if (is_jsr) { 1563 if (is_jsr) {
1564 // Pre-load the next target bytecode into rbx 1564 // Pre-load the next target bytecode into rbx
1565 __ load_unsigned_byte(rbx, Address(r13, rdx, Address::times_1, 0)); 1565 __ load_unsigned_byte(rbx, Address(r13, rdx, Address::times_1, 0));
1566 1566
1567 // compute return address as bci in rax 1567 // compute return address as bci in rax
2274 2274
2275 __ bind(notInt); 2275 __ bind(notInt);
2276 __ cmpl(flags, ctos); 2276 __ cmpl(flags, ctos);
2277 __ jcc(Assembler::notEqual, notChar); 2277 __ jcc(Assembler::notEqual, notChar);
2278 // ctos 2278 // ctos
2279 __ load_unsigned_word(rax, field); 2279 __ load_unsigned_short(rax, field);
2280 __ push(ctos); 2280 __ push(ctos);
2281 // Rewrite bytecode to be faster 2281 // Rewrite bytecode to be faster
2282 if (!is_static) { 2282 if (!is_static) {
2283 patch_bytecode(Bytecodes::_fast_cgetfield, bc, rbx); 2283 patch_bytecode(Bytecodes::_fast_cgetfield, bc, rbx);
2284 } 2284 }
2286 2286
2287 __ bind(notChar); 2287 __ bind(notChar);
2288 __ cmpl(flags, stos); 2288 __ cmpl(flags, stos);
2289 __ jcc(Assembler::notEqual, notShort); 2289 __ jcc(Assembler::notEqual, notShort);
2290 // stos 2290 // stos
2291 __ load_signed_word(rax, field); 2291 __ load_signed_short(rax, field);
2292 __ push(stos); 2292 __ push(stos);
2293 // Rewrite bytecode to be faster 2293 // Rewrite bytecode to be faster
2294 if (!is_static) { 2294 if (!is_static) {
2295 patch_bytecode(Bytecodes::_fast_sgetfield, bc, rbx); 2295 patch_bytecode(Bytecodes::_fast_sgetfield, bc, rbx);
2296 } 2296 }
2749 break; 2749 break;
2750 case Bytecodes::_fast_bgetfield: 2750 case Bytecodes::_fast_bgetfield:
2751 __ movsbl(rax, field); 2751 __ movsbl(rax, field);
2752 break; 2752 break;
2753 case Bytecodes::_fast_sgetfield: 2753 case Bytecodes::_fast_sgetfield:
2754 __ load_signed_word(rax, field); 2754 __ load_signed_short(rax, field);
2755 break; 2755 break;
2756 case Bytecodes::_fast_cgetfield: 2756 case Bytecodes::_fast_cgetfield:
2757 __ load_unsigned_word(rax, field); 2757 __ load_unsigned_short(rax, field);
2758 break; 2758 break;
2759 case Bytecodes::_fast_fgetfield: 2759 case Bytecodes::_fast_fgetfield:
2760 __ movflt(xmm0, field); 2760 __ movflt(xmm0, field);
2761 break; 2761 break;
2762 case Bytecodes::_fast_dgetfield: 2762 case Bytecodes::_fast_dgetfield:
3008 __ verify_oop(rdx); 3008 __ verify_oop(rdx);
3009 3009
3010 // profile this call 3010 // profile this call
3011 __ profile_virtual_call(rdx, r13, r14); 3011 __ profile_virtual_call(rdx, r13, r14);
3012 3012
3013 __ mov(r14, rdx); // Save klassOop in r14 3013 Label no_such_interface, no_such_method;
3014 3014
3015 // Compute start of first itableOffsetEntry (which is at the end of 3015 __ lookup_interface_method(// inputs: rec. class, interface, itable index
3016 // the vtable) 3016 rdx, rax, rbx,
3017 const int base = instanceKlass::vtable_start_offset() * wordSize; 3017 // outputs: method, scan temp. reg
3018 // Get length of vtable 3018 rbx, r13,
3019 assert(vtableEntry::size() * wordSize == 8, 3019 no_such_interface);
3020 "adjust the scaling in the code below"); 3020
3021 __ movl(r13, Address(rdx, 3021 // rbx,: methodOop to call
3022 instanceKlass::vtable_length_offset() * wordSize)); 3022 // rcx: receiver
3023 __ lea(rdx, Address(rdx, r13, Address::times_8, base)); 3023 // Check for abstract method error
3024 3024 // Note: This should be done more efficiently via a throw_abstract_method_error
3025 if (HeapWordsPerLong > 1) { 3025 // interpreter entry point and a conditional jump to it in case of a null
3026 // Round up to align_object_offset boundary 3026 // method.
3027 __ round_to(rdx, BytesPerLong); 3027 __ testptr(rbx, rbx);
3028 } 3028 __ jcc(Assembler::zero, no_such_method);
3029 3029
3030 Label entry, search, interface_ok; 3030 // do the call
3031 3031 // rcx: receiver
3032 __ jmpb(entry); 3032 // rbx,: methodOop
3033 __ bind(search); 3033 __ jump_from_interpreted(rbx, rdx);
3034 __ addptr(rdx, itableOffsetEntry::size() * wordSize); 3034 __ should_not_reach_here();
3035 3035
3036 __ bind(entry); 3036 // exception handling code follows...
3037 3037 // note: must restore interpreter registers to canonical
3038 // Check that the entry is non-null. A null entry means that the 3038 // state for exception handling to work correctly!
3039 // receiver class doesn't implement the interface, and wasn't the 3039
3040 // same as the receiver class checked when the interface was 3040 __ bind(no_such_method);
3041 // resolved.
3042 __ push(rdx);
3043 __ movptr(rdx, Address(rdx, itableOffsetEntry::interface_offset_in_bytes()));
3044 __ testptr(rdx, rdx);
3045 __ jcc(Assembler::notZero, interface_ok);
3046 // throw exception 3041 // throw exception
3047 __ pop(rdx); // pop saved register first. 3042 __ pop(rbx); // pop return address (pushed by prepare_invoke)
3048 __ pop(rbx); // pop return address (pushed by prepare_invoke) 3043 __ restore_bcp(); // r13 must be correct for exception handler (was destroyed)
3049 __ restore_bcp(); // r13 must be correct for exception handler (was 3044 __ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
3050 // destroyed) 3045 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
3051 __ restore_locals(); // make sure locals pointer is correct as well 3046 // the call_VM checks for exception, so we should never return here.
3052 // (was destroyed) 3047 __ should_not_reach_here();
3048
3049 __ bind(no_such_interface);
3050 // throw exception
3051 __ pop(rbx); // pop return address (pushed by prepare_invoke)
3052 __ restore_bcp(); // r13 must be correct for exception handler (was destroyed)
3053 __ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
3053 __ call_VM(noreg, CAST_FROM_FN_PTR(address, 3054 __ call_VM(noreg, CAST_FROM_FN_PTR(address,
3054 InterpreterRuntime::throw_IncompatibleClassChangeError)); 3055 InterpreterRuntime::throw_IncompatibleClassChangeError));
3055 // the call_VM checks for exception, so we should never return here. 3056 // the call_VM checks for exception, so we should never return here.
3056 __ should_not_reach_here(); 3057 __ should_not_reach_here();
3057 __ bind(interface_ok); 3058 return;
3058 3059 }
3059 __ pop(rdx); 3060
3060
3061 __ cmpptr(rax, Address(rdx, itableOffsetEntry::interface_offset_in_bytes()));
3062 __ jcc(Assembler::notEqual, search);
3063
3064 __ movl(rdx, Address(rdx, itableOffsetEntry::offset_offset_in_bytes()));
3065
3066 __ addptr(rdx, r14); // Add offset to klassOop
3067 assert(itableMethodEntry::size() * wordSize == 8,
3068 "adjust the scaling in the code below");
3069 __ movptr(rbx, Address(rdx, rbx, Address::times_8));
3070 // rbx: methodOop to call
3071 // rcx: receiver
3072 // Check for abstract method error
3073 // Note: This should be done more efficiently via a
3074 // throw_abstract_method_error interpreter entry point and a
3075 // conditional jump to it in case of a null method.
3076 {
3077 Label L;
3078 __ testptr(rbx, rbx);
3079 __ jcc(Assembler::notZero, L);
3080 // throw exception
3081 // note: must restore interpreter registers to canonical
3082 // state for exception handling to work correctly!
3083 __ pop(rbx); // pop return address (pushed by prepare_invoke)
3084 __ restore_bcp(); // r13 must be correct for exception handler
3085 // (was destroyed)
3086 __ restore_locals(); // make sure locals pointer is correct as
3087 // well (was destroyed)
3088 __ call_VM(noreg,
3089 CAST_FROM_FN_PTR(address,
3090 InterpreterRuntime::throw_AbstractMethodError));
3091 // the call_VM checks for exception, so we should never return here.
3092 __ should_not_reach_here();
3093 __ bind(L);
3094 }
3095
3096 __ movptr(rcx, Address(rbx, methodOopDesc::interpreter_entry_offset()));
3097
3098 // do the call
3099 // rcx: receiver
3100 // rbx: methodOop
3101 __ jump_from_interpreted(rbx, rdx);
3102 }
3103 3061
3104 //----------------------------------------------------------------------------- 3062 //-----------------------------------------------------------------------------
3105 // Allocation 3063 // Allocation
3106 3064
3107 void TemplateTable::_new() { 3065 void TemplateTable::_new() {