src/cpu/x86/vm/interp_masm_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/interp_masm_x86_32.cpp

Print this page
rev 423 : imported patch indy.patch


 172     // same-named entrypoint in the generated interpreter code.
 173     get_thread(java_thread);
 174     movptr(tmp, Address(java_thread, JavaThread::jvmti_thread_state_offset()));
 175     pushl(Address(tmp, JvmtiThreadState::earlyret_tos_offset()));
 176     call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), 1);
 177     jmp(rax);
 178     bind(L);
 179     get_thread(java_thread);
 180   }
 181 }
 182 
 183 
 184 void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset) {
 185   assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
 186   movl(reg, Address(rsi, bcp_offset));
 187   bswapl(reg);
 188   shrl(reg, 16);
 189 }
 190 
 191 
 192 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset) {
 193   assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");













 194   assert(cache != index, "must use different registers");
 195   load_unsigned_word(index, Address(rsi, bcp_offset));
 196   movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
 197   assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below");
 198   shlptr(index, 2); // convert from field index to ConstantPoolCacheEntry index
 199 }
 200 
 201 
 202 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset) {
 203   assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
 204   assert(cache != tmp, "must use different register");
 205   load_unsigned_word(tmp, Address(rsi, bcp_offset));
 206   assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below");
 207                                // convert from field index to ConstantPoolCacheEntry index
 208                                // and from word offset to byte offset
 209   shll(tmp, 2 + LogBytesPerWord);
 210   movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
 211                                // skip past the header
 212   addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset()));
 213   addptr(cache, tmp);            // construct pointer to cache entry
 214 }
 215 
 216 
 217   // Generate a subtype check: branch to ok_is_subtype if sub_klass is
 218   // a subtype of super_klass.  EAX holds the super_klass.  Blows ECX.
 219   // Resets EDI to locals.  Register sub_klass cannot be any of the above.
 220 void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &ok_is_subtype ) {
 221   assert( Rsub_klass != rax, "rax, holds superklass" );
 222   assert( Rsub_klass != rcx, "rcx holds 2ndary super array length" );
 223   assert( Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr" );
 224   Label not_subtype, loop;
 225 


1228 }
1229 
1230 
1231 void InterpreterMacroAssembler::profile_final_call(Register mdp) {
1232   if (ProfileInterpreter) {
1233     Label profile_continue;
1234 
1235     // If no method data exists, go to profile_continue.
1236     test_method_data_pointer(mdp, profile_continue);
1237 
1238     // We are making a call.  Increment the count.
1239     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1240 
1241     // The method data pointer needs to be updated to reflect the new target.
1242     update_mdp_by_constant(mdp, in_bytes(VirtualCallData::virtual_call_data_size()));
1243     bind (profile_continue);
1244   }
1245 }
1246 
1247 
1248 void InterpreterMacroAssembler::profile_virtual_call(Register receiver, Register mdp, Register reg2) {


1249   if (ProfileInterpreter) {
1250     Label profile_continue;
1251 
1252     // If no method data exists, go to profile_continue.
1253     test_method_data_pointer(mdp, profile_continue);
1254 
1255     // We are making a call.  Increment the count.
1256     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1257 






1258     // Record the receiver type.
1259     record_klass_in_profile(receiver, mdp, reg2);

1260 
1261     // The method data pointer needs to be updated to reflect the new target.
1262     update_mdp_by_constant(mdp,
1263                            in_bytes(VirtualCallData::
1264                                     virtual_call_data_size()));
1265     bind(profile_continue);
1266   }
1267 }
1268 
1269 
1270 void InterpreterMacroAssembler::record_klass_in_profile_helper(
1271                                         Register receiver, Register mdp,
1272                                         Register reg2,
1273                                         int start_row, Label& done) {
1274   int last_row = VirtualCallData::row_limit() - 1;
1275   assert(start_row <= last_row, "must be work left to do");
1276   // Test this row for both the receiver and for null.
1277   // Take any of three different outcomes:
1278   //   1. found receiver => increment count and goto done
1279   //   2. found null => keep looking for case 1, maybe allocate this cell




 172     // same-named entrypoint in the generated interpreter code.
 173     get_thread(java_thread);
 174     movptr(tmp, Address(java_thread, JavaThread::jvmti_thread_state_offset()));
 175     pushl(Address(tmp, JvmtiThreadState::earlyret_tos_offset()));
 176     call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), 1);
 177     jmp(rax);
 178     bind(L);
 179     get_thread(java_thread);
 180   }
 181 }
 182 
 183 
 184 void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset) {
 185   assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
 186   movl(reg, Address(rsi, bcp_offset));
 187   bswapl(reg);
 188   shrl(reg, 16);
 189 }
 190 
 191 
 192 void InterpreterMacroAssembler::get_cache_index_at_bcp(Register reg, int bcp_offset, bool giant_index) {
 193   assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
 194   if (!giant_index) {
 195     load_unsigned_word(reg, Address(rsi, bcp_offset));
 196   } else {
 197     assert(InvokeDynamic, "giant index used only for InvokeDynamic");
 198     movl(reg, Address(rsi, bcp_offset));
 199     assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
 200     notl(reg);  // convert to plain index
 201   }
 202 }
 203 
 204 
 205 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Register index,
 206                                                            int bcp_offset, bool giant_index) {
 207   assert(cache != index, "must use different registers");
 208   get_cache_index_at_bcp(index, bcp_offset, giant_index);
 209   movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
 210   assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below");
 211   shlptr(index, 2); // convert from field index to ConstantPoolCacheEntry index
 212 }
 213 
 214 
 215 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp,
 216                                                                int bcp_offset, bool giant_index) {
 217   assert(cache != tmp, "must use different register");
 218   get_cache_index_at_bcp(tmp, bcp_offset, giant_index);
 219   assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below");
 220                                // convert from field index to ConstantPoolCacheEntry index
 221                                // and from word offset to byte offset
 222   shll(tmp, 2 + LogBytesPerWord);
 223   movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
 224                                // skip past the header
 225   addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset()));
 226   addptr(cache, tmp);            // construct pointer to cache entry
 227 }
 228 
 229 
 230   // Generate a subtype check: branch to ok_is_subtype if sub_klass is
 231   // a subtype of super_klass.  EAX holds the super_klass.  Blows ECX.
 232   // Resets EDI to locals.  Register sub_klass cannot be any of the above.
 233 void InterpreterMacroAssembler::gen_subtype_check( Register Rsub_klass, Label &ok_is_subtype ) {
 234   assert( Rsub_klass != rax, "rax, holds superklass" );
 235   assert( Rsub_klass != rcx, "rcx holds 2ndary super array length" );
 236   assert( Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr" );
 237   Label not_subtype, loop;
 238 


1241 }
1242 
1243 
1244 void InterpreterMacroAssembler::profile_final_call(Register mdp) {
1245   if (ProfileInterpreter) {
1246     Label profile_continue;
1247 
1248     // If no method data exists, go to profile_continue.
1249     test_method_data_pointer(mdp, profile_continue);
1250 
1251     // We are making a call.  Increment the count.
1252     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1253 
1254     // The method data pointer needs to be updated to reflect the new target.
1255     update_mdp_by_constant(mdp, in_bytes(VirtualCallData::virtual_call_data_size()));
1256     bind (profile_continue);
1257   }
1258 }
1259 
1260 
1261 void InterpreterMacroAssembler::profile_virtual_call(Register receiver, Register mdp,
1262                                                      Register reg2,
1263                                                      bool receiver_can_be_null) {
1264   if (ProfileInterpreter) {
1265     Label profile_continue;
1266 
1267     // If no method data exists, go to profile_continue.
1268     test_method_data_pointer(mdp, profile_continue);
1269 
1270     // We are making a call.  Increment the count.
1271     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1272 
1273     Label skip_receiver_profile;
1274     if (receiver_can_be_null) {
1275       testptr(receiver, receiver);
1276       jcc(Assembler::zero, skip_receiver_profile);
1277     }
1278 
1279     // Record the receiver type.
1280     record_klass_in_profile(receiver, mdp, reg2);
1281     bind(skip_receiver_profile);
1282 
1283     // The method data pointer needs to be updated to reflect the new target.
1284     update_mdp_by_constant(mdp,
1285                            in_bytes(VirtualCallData::
1286                                     virtual_call_data_size()));
1287     bind(profile_continue);
1288   }
1289 }
1290 
1291 
1292 void InterpreterMacroAssembler::record_klass_in_profile_helper(
1293                                         Register receiver, Register mdp,
1294                                         Register reg2,
1295                                         int start_row, Label& done) {
1296   int last_row = VirtualCallData::row_limit() - 1;
1297   assert(start_row <= last_row, "must be work left to do");
1298   // Test this row for both the receiver and for null.
1299   // Take any of three different outcomes:
1300   //   1. found receiver => increment count and goto done
1301   //   2. found null => keep looking for case 1, maybe allocate this cell


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