src/cpu/x86/vm/templateTable_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot-dvm Sdiff src/cpu/x86/vm

src/cpu/x86/vm/templateTable_x86_32.cpp

Print this page
rev 423 : imported patch indy.patch


 189                                    Register scratch,
 190                                    bool load_bc_into_scratch/*=true*/) {
 191 
 192   if (!RewriteBytecodes) return;
 193   // the pair bytecodes have already done the load.
 194   if (load_bc_into_scratch) {
 195     __ movl(bc, bytecode);
 196   }
 197   Label patch_done;
 198   if (JvmtiExport::can_post_breakpoint()) {
 199     Label fast_patch;
 200     // if a breakpoint is present we can't rewrite the stream directly
 201     __ movzbl(scratch, at_bcp(0));
 202     __ cmpl(scratch, Bytecodes::_breakpoint);
 203     __ jcc(Assembler::notEqual, fast_patch);
 204     __ get_method(scratch);
 205     // Let breakpoint table handling rewrite to quicker bytecode
 206     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, rsi, bc);
 207 #ifndef ASSERT
 208     __ jmpb(patch_done);
 209     __ bind(fast_patch);
 210   }
 211 #else
 212     __ jmp(patch_done);

 213     __ bind(fast_patch);
 214   }

 215   Label okay;
 216   __ load_unsigned_byte(scratch, at_bcp(0));
 217   __ cmpl(scratch, (int)Bytecodes::java_code(bytecode));
 218   __ jccb(Assembler::equal, okay);
 219   __ cmpl(scratch, bc);
 220   __ jcc(Assembler::equal, okay);
 221   __ stop("patching the wrong bytecode");
 222   __ bind(okay);
 223 #endif
 224   // patch bytecode
 225   __ movb(at_bcp(0), bc);
 226   __ bind(patch_done);
 227 }
 228 
 229 //----------------------------------------------------------------------------------------------------
 230 // Individual instructions
 231 
 232 void TemplateTable::nop() {
 233   transition(vtos, vtos);
 234   // nothing to do


2088 // (3) Similar a volatile write cannot let unrelated NON-volatile memory refs
2089 // that happen BEFORE the write float down to after the write.  It's OK for
2090 // non-volatile memory refs that happen after the volatile write to float up
2091 // before it.
2092 //
2093 // We only put in barriers around volatile refs (they are expensive), not
2094 // _between_ memory refs (that would require us to track the flavor of the
2095 // previous memory refs).  Requirements (2) and (3) require some barriers
2096 // before volatile stores and after volatile loads.  These nearly cover
2097 // requirement (1) but miss the volatile-store-volatile-load case.  This final
2098 // case is placed after volatile-stores although it could just as well go
2099 // before volatile-loads.
2100 void TemplateTable::volatile_barrier(Assembler::Membar_mask_bits order_constraint ) {
2101   // Helper function to insert a is-volatile test and memory barrier
2102   if( !os::is_MP() ) return;    // Not needed on single CPU
2103   __ membar(order_constraint);
2104 }
2105 
2106 void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) {
2107   assert(byte_no == 1 || byte_no == 2, "byte_no out of range");

2108 
2109   Register temp = rbx;
2110 
2111   assert_different_registers(Rcache, index, temp);
2112 
2113   const int shift_count = (1 + byte_no)*BitsPerByte;
2114   Label resolved;
2115   __ get_cache_and_index_at_bcp(Rcache, index, 1);





2116   __ movl(temp, Address(Rcache, index, Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
2117   __ shrl(temp, shift_count);
2118   // have we resolved this bytecode?
2119   __ andl(temp, 0xFF);
2120   __ cmpl(temp, (int)bytecode());
2121   __ jcc(Assembler::equal, resolved);

2122 
2123   // resolve first time through
2124   address entry;
2125   switch (bytecode()) {
2126     case Bytecodes::_getstatic      : // fall through
2127     case Bytecodes::_putstatic      : // fall through
2128     case Bytecodes::_getfield       : // fall through
2129     case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
2130     case Bytecodes::_invokevirtual  : // fall through
2131     case Bytecodes::_invokespecial  : // fall through
2132     case Bytecodes::_invokestatic   : // fall through
2133     case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);  break;

2134     default                         : ShouldNotReachHere();                                 break;
2135   }
2136   __ movl(temp, (int)bytecode());
2137   __ call_VM(noreg, entry, temp);
2138   // Update registers with resolved info
2139   __ get_cache_and_index_at_bcp(Rcache, index, 1);
2140   __ bind(resolved);
2141 }
2142 
2143 
2144 // The cache and index registers must be set before call
2145 void TemplateTable::load_field_cp_cache_entry(Register obj,
2146                                               Register cache,
2147                                               Register index,
2148                                               Register off,
2149                                               Register flags,
2150                                               bool is_static = false) {
2151   assert_different_registers(cache, index, flags, off);
2152 
2153   ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset();
2154   // Field offset
2155   __ movptr(off, Address(cache, index, Address::times_ptr,
2156                          in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset())));
2157   // Flags
2158   __ movl(flags, Address(cache, index, Address::times_ptr,
2159            in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset())));


2864     __ verify_oop(rax);
2865   } else if (state == ftos) {
2866     __ fld_s(lo);
2867   } else {
2868     ShouldNotReachHere();
2869   }
2870   __ decrement(rsi);
2871 }
2872 
2873 
2874 
2875 //----------------------------------------------------------------------------------------------------
2876 // Calls
2877 
2878 void TemplateTable::count_calls(Register method, Register temp) {
2879   // implemented elsewhere
2880   ShouldNotReachHere();
2881 }
2882 
2883 
2884 void TemplateTable::prepare_invoke(Register method, Register index, int byte_no, Bytecodes::Code code) {



2885   // determine flags

2886   const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;

2887   const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
2888   const bool is_invokespecial    = code == Bytecodes::_invokespecial;
2889   const bool load_receiver       = code != Bytecodes::_invokestatic;
2890   const bool receiver_null_check = is_invokespecial;
2891   const bool save_flags = is_invokeinterface || is_invokevirtual;
2892   // setup registers & access constant pool cache
2893   const Register recv   = rcx;
2894   const Register flags  = rdx;
2895   assert_different_registers(method, index, recv, flags);
2896 



2897   // save 'interpreter return address'
2898   __ save_bcp();
2899 
2900   load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual);
2901 
2902   // load receiver if needed (note: no return address pushed yet)
2903   if (load_receiver) {
2904     __ movl(recv, flags);
2905     __ andl(recv, 0xFF);
2906     // recv count is 0 based?
2907     __ movl(recv, Address(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1)));




2908     __ verify_oop(recv);
2909   }

2910 
2911   // do null check if needed
2912   if (receiver_null_check) {
2913     __ null_check(recv);
2914   }
2915 
2916   if (save_flags) {
2917     __ mov(rsi, flags);
2918   }
2919 
2920   // compute return type
2921   __ shrl(flags, ConstantPoolCacheEntry::tosBits);
2922   // Make sure we don't need to mask flags for tosBits after the above shift
2923   ConstantPoolCacheEntry::verify_tosBits();
2924   // load return address
2925   { const int table =
2926       is_invokeinterface
2927       ? (int)Interpreter::return_5_addrs_by_index_table()
2928       : (int)Interpreter::return_3_addrs_by_index_table();
2929     __ movl(flags, Address(noreg, flags, Address::times_4, table));




2930   }
2931 
2932   // push return address
2933   __ push(flags);
2934 
2935   // Restore flag value from the constant pool cache, and restore rsi
2936   // for later null checks.  rsi is the bytecode pointer
2937   if (save_flags) {
2938     __ mov(flags, rsi);
2939     __ restore_bcp();
2940   }
2941 }
2942 
2943 
2944 void TemplateTable::invokevirtual_helper(Register index, Register recv,
2945                         Register flags) {
2946 
2947   // Uses temporary registers rax, rdx
2948   assert_different_registers(index, recv, rax, rdx);
2949 


2971 
2972   // get receiver klass
2973   __ null_check(recv, oopDesc::klass_offset_in_bytes());
2974   // Keep recv in rcx for callee expects it there
2975   __ movptr(rax, Address(recv, oopDesc::klass_offset_in_bytes()));
2976   __ verify_oop(rax);
2977 
2978   // profile this call
2979   __ profile_virtual_call(rax, rdi, rdx);
2980 
2981   // get target methodOop & entry point
2982   const int base = instanceKlass::vtable_start_offset() * wordSize;
2983   assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below");
2984   __ movptr(method, Address(rax, index, Address::times_ptr, base + vtableEntry::method_offset_in_bytes()));
2985   __ jump_from_interpreted(method, rdx);
2986 }
2987 
2988 
2989 void TemplateTable::invokevirtual(int byte_no) {
2990   transition(vtos, vtos);
2991   prepare_invoke(rbx, noreg, byte_no, bytecode());
2992 
2993   // rbx,: index
2994   // rcx: receiver
2995   // rdx: flags
2996 
2997   invokevirtual_helper(rbx, rcx, rdx);
2998 }
2999 
3000 
3001 void TemplateTable::invokespecial(int byte_no) {
3002   transition(vtos, vtos);
3003   prepare_invoke(rbx, noreg, byte_no, bytecode());
3004   // do the call
3005   __ verify_oop(rbx);
3006   __ profile_call(rax);
3007   __ jump_from_interpreted(rbx, rax);
3008 }
3009 
3010 
3011 void TemplateTable::invokestatic(int byte_no) {
3012   transition(vtos, vtos);
3013   prepare_invoke(rbx, noreg, byte_no, bytecode());
3014   // do the call
3015   __ verify_oop(rbx);
3016   __ profile_call(rax);
3017   __ jump_from_interpreted(rbx, rax);
3018 }
3019 
3020 
3021 void TemplateTable::fast_invokevfinal(int byte_no) {
3022   transition(vtos, vtos);
3023   __ stop("fast_invokevfinal not used on x86");
3024 }
3025 
3026 
3027 void TemplateTable::invokeinterface(int byte_no) {
3028   transition(vtos, vtos);
3029   prepare_invoke(rax, rbx, byte_no, bytecode());
3030 
3031   // rax,: Interface
3032   // rbx,: index
3033   // rcx: receiver
3034   // rdx: flags
3035 
3036   // Special case of invokeinterface called for virtual method of
3037   // java.lang.Object.  See cpCacheOop.cpp for details.
3038   // This code isn't produced by javac, but could be produced by
3039   // another compliant java compiler.
3040   Label notMethod;
3041   __ movl(rdi, rdx);
3042   __ andl(rdi, (1 << ConstantPoolCacheEntry::methodInterface));
3043   __ jcc(Assembler::zero, notMethod);
3044 
3045   invokevirtual_helper(rbx, rcx, rdx);
3046   __ bind(notMethod);
3047 
3048   // Get receiver klass into rdx - also a null check
3049   __ restore_locals();  // restore rdi


3161       __ testptr(rbx, rbx);
3162       __ jcc(Assembler::notZero, L);
3163       // throw exception
3164           // note: must restore interpreter registers to canonical
3165           //       state for exception handling to work correctly!
3166           __ pop(rbx);           // pop return address (pushed by prepare_invoke)
3167           __ restore_bcp();      // rsi must be correct for exception handler   (was destroyed)
3168           __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
3169       __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
3170       // the call_VM checks for exception, so we should never return here.
3171       __ should_not_reach_here();
3172       __ bind(L);
3173     }
3174 
3175   // do the call
3176   // rcx: receiver
3177   // rbx,: methodOop
3178   __ jump_from_interpreted(rbx, rdx);
3179 }
3180 









































































3181 //----------------------------------------------------------------------------------------------------
3182 // Allocation
3183 
3184 void TemplateTable::_new() {
3185   transition(vtos, atos);
3186   __ get_unsigned_2_byte_index_at_bcp(rdx, 1);
3187   Label slow_case;
3188   Label done;
3189   Label initialize_header;
3190   Label initialize_object;  // including clearing the fields
3191   Label allocate_shared;
3192 
3193   __ get_cpool_and_tags(rcx, rax);
3194   // get instanceKlass
3195   __ movptr(rcx, Address(rcx, rdx, Address::times_ptr, sizeof(constantPoolOopDesc)));
3196   __ push(rcx);  // save the contexts of klass for initializing the header
3197 
3198   // make sure the class we're about to instantiate has been resolved.
3199   // Note: slow_case does a pop of stack, which is why we loaded class/pushed above
3200   const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize;




 189                                    Register scratch,
 190                                    bool load_bc_into_scratch/*=true*/) {
 191 
 192   if (!RewriteBytecodes) return;
 193   // the pair bytecodes have already done the load.
 194   if (load_bc_into_scratch) {
 195     __ movl(bc, bytecode);
 196   }
 197   Label patch_done;
 198   if (JvmtiExport::can_post_breakpoint()) {
 199     Label fast_patch;
 200     // if a breakpoint is present we can't rewrite the stream directly
 201     __ movzbl(scratch, at_bcp(0));
 202     __ cmpl(scratch, Bytecodes::_breakpoint);
 203     __ jcc(Assembler::notEqual, fast_patch);
 204     __ get_method(scratch);
 205     // Let breakpoint table handling rewrite to quicker bytecode
 206     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, rsi, bc);
 207 #ifndef ASSERT
 208     __ jmpb(patch_done);


 209 #else
 210     __ jmp(patch_done);
 211 #endif
 212     __ bind(fast_patch);
 213   }
 214 #ifdef ASSERT
 215   Label okay;
 216   __ load_unsigned_byte(scratch, at_bcp(0));
 217   __ cmpl(scratch, (int)Bytecodes::java_code(bytecode));
 218   __ jccb(Assembler::equal, okay);
 219   __ cmpl(scratch, bc);
 220   __ jcc(Assembler::equal, okay);
 221   __ stop("patching the wrong bytecode");
 222   __ bind(okay);
 223 #endif
 224   // patch bytecode
 225   __ movb(at_bcp(0), bc);
 226   __ bind(patch_done);
 227 }
 228 
 229 //----------------------------------------------------------------------------------------------------
 230 // Individual instructions
 231 
 232 void TemplateTable::nop() {
 233   transition(vtos, vtos);
 234   // nothing to do


2088 // (3) Similar a volatile write cannot let unrelated NON-volatile memory refs
2089 // that happen BEFORE the write float down to after the write.  It's OK for
2090 // non-volatile memory refs that happen after the volatile write to float up
2091 // before it.
2092 //
2093 // We only put in barriers around volatile refs (they are expensive), not
2094 // _between_ memory refs (that would require us to track the flavor of the
2095 // previous memory refs).  Requirements (2) and (3) require some barriers
2096 // before volatile stores and after volatile loads.  These nearly cover
2097 // requirement (1) but miss the volatile-store-volatile-load case.  This final
2098 // case is placed after volatile-stores although it could just as well go
2099 // before volatile-loads.
2100 void TemplateTable::volatile_barrier(Assembler::Membar_mask_bits order_constraint ) {
2101   // Helper function to insert a is-volatile test and memory barrier
2102   if( !os::is_MP() ) return;    // Not needed on single CPU
2103   __ membar(order_constraint);
2104 }
2105 
2106 void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) {
2107   assert(byte_no == 1 || byte_no == 2, "byte_no out of range");
2108   bool is_invokedynamic = (bytecode() == Bytecodes::_invokedynamic);
2109 
2110   Register temp = rbx;
2111 
2112   assert_different_registers(Rcache, index, temp);
2113 
2114   const int shift_count = (1 + byte_no)*BitsPerByte;
2115   Label resolved;
2116   __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
2117   if (is_invokedynamic) {
2118     // we are resolved if the f1 field contains a non-null CallSite object
2119     __ cmpptr(Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()), (int32_t) NULL_WORD);
2120     __ jcc(Assembler::notEqual, resolved);
2121   } else {
2122     __ movl(temp, Address(Rcache, index, Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
2123     __ shrl(temp, shift_count);
2124     // have we resolved this bytecode?
2125     __ andl(temp, 0xFF);
2126     __ cmpl(temp, (int)bytecode());
2127     __ jcc(Assembler::equal, resolved);
2128   }
2129 
2130   // resolve first time through
2131   address entry;
2132   switch (bytecode()) {
2133     case Bytecodes::_getstatic      : // fall through
2134     case Bytecodes::_putstatic      : // fall through
2135     case Bytecodes::_getfield       : // fall through
2136     case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
2137     case Bytecodes::_invokevirtual  : // fall through
2138     case Bytecodes::_invokespecial  : // fall through
2139     case Bytecodes::_invokestatic   : // fall through
2140     case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);  break;
2141     case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
2142     default                         : ShouldNotReachHere();                                 break;
2143   }
2144   __ movl(temp, (int)bytecode());
2145   __ call_VM(noreg, entry, temp);
2146   // Update registers with resolved info
2147   __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
2148   __ bind(resolved);
2149 }
2150 
2151 
2152 // The cache and index registers must be set before call
2153 void TemplateTable::load_field_cp_cache_entry(Register obj,
2154                                               Register cache,
2155                                               Register index,
2156                                               Register off,
2157                                               Register flags,
2158                                               bool is_static = false) {
2159   assert_different_registers(cache, index, flags, off);
2160 
2161   ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset();
2162   // Field offset
2163   __ movptr(off, Address(cache, index, Address::times_ptr,
2164                          in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset())));
2165   // Flags
2166   __ movl(flags, Address(cache, index, Address::times_ptr,
2167            in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset())));


2872     __ verify_oop(rax);
2873   } else if (state == ftos) {
2874     __ fld_s(lo);
2875   } else {
2876     ShouldNotReachHere();
2877   }
2878   __ decrement(rsi);
2879 }
2880 
2881 
2882 
2883 //----------------------------------------------------------------------------------------------------
2884 // Calls
2885 
2886 void TemplateTable::count_calls(Register method, Register temp) {
2887   // implemented elsewhere
2888   ShouldNotReachHere();
2889 }
2890 
2891 
2892 void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
2893   bool neg_byte_no = (byte_no < 0);
2894   if (neg_byte_no)  byte_no = -byte_no;
2895 
2896   // determine flags
2897   Bytecodes::Code code = bytecode();
2898   const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
2899   const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
2900   const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
2901   const bool is_invokespecial    = code == Bytecodes::_invokespecial;
2902   const bool load_receiver       = code != Bytecodes::_invokestatic;
2903   const bool receiver_null_check = is_invokespecial;
2904   const bool save_flags = is_invokeinterface || is_invokevirtual;
2905   // setup registers & access constant pool cache
2906   const Register recv   = rcx;
2907   const Register flags  = rdx;
2908   assert_different_registers(method, index, recv, flags);
2909 
2910   assert(!neg_byte_no || is_invokedynamic, "byte_no<0 hack only for invdyn");
2911   const bool is_invdyn_bootstrap = neg_byte_no;
2912 
2913   // save 'interpreter return address'
2914   __ save_bcp();
2915 
2916   load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual);
2917 
2918   // load receiver if needed (note: no return address pushed yet)
2919   if (load_receiver) {
2920     __ movl(recv, flags);
2921     __ andl(recv, 0xFF);
2922     // recv count is 0 based?
2923     Address recv_addr(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1));
2924     if (is_invokedynamic) {
2925       __ lea(recv, recv_addr);
2926     } else {
2927       __ movptr(recv, recv_addr);
2928       __ verify_oop(recv);
2929     }
2930   }
2931 
2932   // do null check if needed
2933   if (receiver_null_check) {
2934     __ null_check(recv);
2935   }
2936 
2937   if (save_flags) {
2938     __ mov(rsi, flags);
2939   }
2940 
2941   // compute return type
2942   __ shrl(flags, ConstantPoolCacheEntry::tosBits);
2943   // Make sure we don't need to mask flags for tosBits after the above shift
2944   ConstantPoolCacheEntry::verify_tosBits();
2945   // load return address
2946   {
2947     address table_addr =
2948       (is_invdyn_bootstrap)
2949       ? (address)Interpreter::return_5_unbox_addrs_by_index_table()
2950       : (is_invokeinterface || is_invokedynamic)
2951       ? (address)Interpreter::return_5_addrs_by_index_table()
2952       : (address)Interpreter::return_3_addrs_by_index_table();
2953     ExternalAddress table(table_addr);
2954     __ movptr(flags, ArrayAddress(table, Address(noreg, flags, Address::times_ptr)));
2955   }
2956 
2957   // push return address
2958   __ push(flags);
2959 
2960   // Restore flag value from the constant pool cache, and restore rsi
2961   // for later null checks.  rsi is the bytecode pointer
2962   if (save_flags) {
2963     __ mov(flags, rsi);
2964     __ restore_bcp();
2965   }
2966 }
2967 
2968 
2969 void TemplateTable::invokevirtual_helper(Register index, Register recv,
2970                         Register flags) {
2971 
2972   // Uses temporary registers rax, rdx
2973   assert_different_registers(index, recv, rax, rdx);
2974 


2996 
2997   // get receiver klass
2998   __ null_check(recv, oopDesc::klass_offset_in_bytes());
2999   // Keep recv in rcx for callee expects it there
3000   __ movptr(rax, Address(recv, oopDesc::klass_offset_in_bytes()));
3001   __ verify_oop(rax);
3002 
3003   // profile this call
3004   __ profile_virtual_call(rax, rdi, rdx);
3005 
3006   // get target methodOop & entry point
3007   const int base = instanceKlass::vtable_start_offset() * wordSize;
3008   assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below");
3009   __ movptr(method, Address(rax, index, Address::times_ptr, base + vtableEntry::method_offset_in_bytes()));
3010   __ jump_from_interpreted(method, rdx);
3011 }
3012 
3013 
3014 void TemplateTable::invokevirtual(int byte_no) {
3015   transition(vtos, vtos);
3016   prepare_invoke(rbx, noreg, byte_no);
3017 
3018   // rbx,: index
3019   // rcx: receiver
3020   // rdx: flags
3021 
3022   invokevirtual_helper(rbx, rcx, rdx);
3023 }
3024 
3025 
3026 void TemplateTable::invokespecial(int byte_no) {
3027   transition(vtos, vtos);
3028   prepare_invoke(rbx, noreg, byte_no);
3029   // do the call
3030   __ verify_oop(rbx);
3031   __ profile_call(rax);
3032   __ jump_from_interpreted(rbx, rax);
3033 }
3034 
3035 
3036 void TemplateTable::invokestatic(int byte_no) {
3037   transition(vtos, vtos);
3038   prepare_invoke(rbx, noreg, byte_no);
3039   // do the call
3040   __ verify_oop(rbx);
3041   __ profile_call(rax);
3042   __ jump_from_interpreted(rbx, rax);
3043 }
3044 
3045 
3046 void TemplateTable::fast_invokevfinal(int byte_no) {
3047   transition(vtos, vtos);
3048   __ stop("fast_invokevfinal not used on x86");
3049 }
3050 
3051 
3052 void TemplateTable::invokeinterface(int byte_no) {
3053   transition(vtos, vtos);
3054   prepare_invoke(rax, rbx, byte_no);
3055 
3056   // rax,: Interface
3057   // rbx,: index
3058   // rcx: receiver
3059   // rdx: flags
3060 
3061   // Special case of invokeinterface called for virtual method of
3062   // java.lang.Object.  See cpCacheOop.cpp for details.
3063   // This code isn't produced by javac, but could be produced by
3064   // another compliant java compiler.
3065   Label notMethod;
3066   __ movl(rdi, rdx);
3067   __ andl(rdi, (1 << ConstantPoolCacheEntry::methodInterface));
3068   __ jcc(Assembler::zero, notMethod);
3069 
3070   invokevirtual_helper(rbx, rcx, rdx);
3071   __ bind(notMethod);
3072 
3073   // Get receiver klass into rdx - also a null check
3074   __ restore_locals();  // restore rdi


3186       __ testptr(rbx, rbx);
3187       __ jcc(Assembler::notZero, L);
3188       // throw exception
3189           // note: must restore interpreter registers to canonical
3190           //       state for exception handling to work correctly!
3191           __ pop(rbx);           // pop return address (pushed by prepare_invoke)
3192           __ restore_bcp();      // rsi must be correct for exception handler   (was destroyed)
3193           __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
3194       __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
3195       // the call_VM checks for exception, so we should never return here.
3196       __ should_not_reach_here();
3197       __ bind(L);
3198     }
3199 
3200   // do the call
3201   // rcx: receiver
3202   // rbx,: methodOop
3203   __ jump_from_interpreted(rbx, rdx);
3204 }
3205 
3206 void TemplateTable::invokedynamic(int byte_no) {
3207   transition(vtos, vtos);
3208 
3209   if (!InvokeDynamic) {
3210     // We do not encounter this bytecode if !InvokeDynamic.
3211     // See Rewriter::rewrite_invokedynamic.
3212     __ stop("invokedynamic not enabled");
3213     return;
3214   }
3215 
3216   prepare_invoke(rax, rbx, byte_no);
3217 
3218   // rax: CallSite object (f1)
3219   // rbx: unused (f2)
3220   // rcx: receiver address
3221   // rdx: flags (unused)
3222 
3223   if (ProfileInterpreter) {
3224     Label L;
3225     __ movl(rdx, Address(rcx, 0));
3226     __ testl(rdx, rdx);
3227     __ jcc(Assembler::zero, L);
3228 
3229     // Get receiver klass into rdx
3230     __ movl(rdx, Address(rdx, oopDesc::klass_offset_in_bytes()));
3231     __ verify_oop(rdx);
3232     __ bind(L);
3233 
3234     // profile this call
3235     __ profile_virtual_call(rdx, rsi, rdi, true);
3236   }
3237 
3238   Label handle_unlinked_site;
3239   __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_impl_DynCallSite::target_offset_in_bytes, rcx)));
3240   __ testptr(rcx, rcx);
3241   __ jcc(Assembler::zero, handle_unlinked_site);
3242 
3243   __ prepare_to_jump_from_interpreted();
3244   __ jump_to_method_handle_entry(rcx, rdx);
3245 
3246   // Initial calls come here...
3247   __ bind(handle_unlinked_site);
3248   __ pop(rcx);                 // remove return address pushed by prepare_invoke
3249 
3250   address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::bootstrap_invokedynamic);
3251   // squish stacked arguments together on stack, preceded by call site
3252   // return bootstrap method as a handle in rcx
3253   __ restore_bcp();      // rsi must be correct for call_VM
3254   __ call_VM(rax, entry, rax);
3255   __ movl(rdi, rax);            // protect MH from prepare_invoke
3256 
3257   // recompute return address
3258   __ restore_bcp();      // rsi must be correct for prepare_invoke
3259   prepare_invoke(rax, rbx, -byte_no);
3260   // rax: CallSite object (f1)
3261   // rbx: unused (f2)
3262   // rcx: receiver address (now holds arglist)
3263   // rdx: flags
3264 
3265   // save SP now, before we add the bootstrap call to the stack 
3266   __ prepare_to_jump_from_interpreted();
3267 
3268   // let's play adapter
3269   __ pop(rbx);                  // return value
3270   __ push(rdi);                 // boot MH
3271   __ push(rax);                 // call site
3272   __ movptr(rcx, Address(rcx, 0));
3273   __ push(rcx);                 // arglist
3274   __ push(rbx);                 // return value
3275   __ mov(rcx, rdi);
3276   __ jump_to_method_handle_entry(rcx, rdx);
3277 }
3278 
3279 //----------------------------------------------------------------------------------------------------
3280 // Allocation
3281 
3282 void TemplateTable::_new() {
3283   transition(vtos, atos);
3284   __ get_unsigned_2_byte_index_at_bcp(rdx, 1);
3285   Label slow_case;
3286   Label done;
3287   Label initialize_header;
3288   Label initialize_object;  // including clearing the fields
3289   Label allocate_shared;
3290 
3291   __ get_cpool_and_tags(rcx, rax);
3292   // get instanceKlass
3293   __ movptr(rcx, Address(rcx, rdx, Address::times_ptr, sizeof(constantPoolOopDesc)));
3294   __ push(rcx);  // save the contexts of klass for initializing the header
3295 
3296   // make sure the class we're about to instantiate has been resolved.
3297   // Note: slow_case does a pop of stack, which is why we loaded class/pushed above
3298   const int tags_offset = typeArrayOopDesc::header_size(T_BYTE) * wordSize;


src/cpu/x86/vm/templateTable_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File