src/cpu/x86/vm/interp_masm_x86_64.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_64.cpp

Print this page
rev 423 : imported patch indy.patch


 168     // same-named entrypoint in the generated interpreter code.
 169     movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset()));
 170     movl(c_rarg0, Address(c_rarg0, JvmtiThreadState::earlyret_tos_offset()));
 171     call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), c_rarg0);
 172     jmp(rax);
 173     bind(L);
 174   }
 175 }
 176 
 177 
 178 void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(
 179   Register reg,
 180   int bcp_offset) {
 181   assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
 182   movl(reg, Address(r13, bcp_offset));
 183   bswapl(reg);
 184   shrl(reg, 16);
 185 }
 186 
 187 















 188 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
 189                                                            Register index,
 190                                                            int bcp_offset) {
 191   assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
 192   assert(cache != index, "must use different registers");
 193   load_unsigned_word(index, Address(r13, bcp_offset));
 194   movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
 195   assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
 196   // convert from field index to ConstantPoolCacheEntry index
 197   shll(index, 2);
 198 }
 199 
 200 
 201 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
 202                                                                Register tmp,
 203                                                                int bcp_offset) {
 204   assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
 205   assert(cache != tmp, "must use different register");
 206   load_unsigned_word(tmp, Address(r13, bcp_offset));
 207   assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
 208   // convert from field index to ConstantPoolCacheEntry index
 209   // and from word offset to byte offset
 210   shll(tmp, 2 + LogBytesPerWord);
 211   movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
 212   // skip past the header
 213   addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset()));
 214   addptr(cache, tmp);  // construct pointer to cache entry
 215 }
 216 
 217 
 218 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a
 219 // subtype of super_klass.
 220 //
 221 // Args:
 222 //      rax: superklass
 223 //      Rsub_klass: subklass
 224 //
 225 // Kills:
 226 //      rcx, rdi


1271   if (ProfileInterpreter) {
1272     Label profile_continue;
1273 
1274     // If no method data exists, go to profile_continue.
1275     test_method_data_pointer(mdp, profile_continue);
1276 
1277     // We are making a call.  Increment the count.
1278     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1279 
1280     // The method data pointer needs to be updated to reflect the new target.
1281     update_mdp_by_constant(mdp,
1282                            in_bytes(VirtualCallData::
1283                                     virtual_call_data_size()));
1284     bind(profile_continue);
1285   }
1286 }
1287 
1288 
1289 void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
1290                                                      Register mdp,
1291                                                      Register reg2) {

1292   if (ProfileInterpreter) {
1293     Label profile_continue;
1294 
1295     // If no method data exists, go to profile_continue.
1296     test_method_data_pointer(mdp, profile_continue);
1297 
1298     // We are making a call.  Increment the count.
1299     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1300 






1301     // Record the receiver type.
1302     record_klass_in_profile(receiver, mdp, reg2);

1303 
1304     // The method data pointer needs to be updated to reflect the new target.
1305     update_mdp_by_constant(mdp,
1306                            in_bytes(VirtualCallData::
1307                                     virtual_call_data_size()));
1308     bind(profile_continue);
1309   }
1310 }
1311 
1312 // This routine creates a state machine for updating the multi-row
1313 // type profile at a virtual call site (or other type-sensitive bytecode).
1314 // The machine visits each row (of receiver/count) until the receiver type
1315 // is found, or until it runs out of rows.  At the same time, it remembers
1316 // the location of the first empty row.  (An empty row records null for its
1317 // receiver, and can be allocated for a newly-observed receiver type.)
1318 // Because there are two degrees of freedom in the state, a simple linear
1319 // search will not work; it must be a decision tree.  Hence this helper
1320 // function is recursive, to generate the required tree structured code.
1321 // It's the interpreter, so we are trading off code space for speed.
1322 // See below for example code.




 168     // same-named entrypoint in the generated interpreter code.
 169     movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset()));
 170     movl(c_rarg0, Address(c_rarg0, JvmtiThreadState::earlyret_tos_offset()));
 171     call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), c_rarg0);
 172     jmp(rax);
 173     bind(L);
 174   }
 175 }
 176 
 177 
 178 void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(
 179   Register reg,
 180   int bcp_offset) {
 181   assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
 182   movl(reg, Address(r13, bcp_offset));
 183   bswapl(reg);
 184   shrl(reg, 16);
 185 }
 186 
 187 
 188 void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
 189                                                        int bcp_offset,
 190                                                        bool giant_index) {
 191   assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
 192   if (!giant_index) {
 193     load_unsigned_word(index, Address(r13, bcp_offset));
 194   } else {
 195     assert(InvokeDynamic, "giant index used only for InvokeDynamic");
 196     movl(index, Address(r13, bcp_offset));
 197     assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
 198     notl(index);  // convert to plain index
 199   }
 200 }
 201 
 202 
 203 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
 204                                                            Register index,
 205                                                            int bcp_offset,
 206                                                            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   // convert from field index to ConstantPoolCacheEntry index
 212   shll(index, 2);
 213 }
 214 
 215 
 216 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
 217                                                                Register tmp,
 218                                                                int bcp_offset,
 219                                                                bool giant_index) {
 220   assert(cache != tmp, "must use different register");
 221   get_cache_index_at_bcp(tmp, bcp_offset, giant_index);
 222   assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
 223   // convert from field index to ConstantPoolCacheEntry index
 224   // and from word offset to byte offset
 225   shll(tmp, 2 + LogBytesPerWord);
 226   movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
 227   // skip past the header
 228   addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset()));
 229   addptr(cache, tmp);  // construct pointer to cache entry
 230 }
 231 
 232 
 233 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a
 234 // subtype of super_klass.
 235 //
 236 // Args:
 237 //      rax: superklass
 238 //      Rsub_klass: subklass
 239 //
 240 // Kills:
 241 //      rcx, rdi


1286   if (ProfileInterpreter) {
1287     Label profile_continue;
1288 
1289     // If no method data exists, go to profile_continue.
1290     test_method_data_pointer(mdp, profile_continue);
1291 
1292     // We are making a call.  Increment the count.
1293     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1294 
1295     // The method data pointer needs to be updated to reflect the new target.
1296     update_mdp_by_constant(mdp,
1297                            in_bytes(VirtualCallData::
1298                                     virtual_call_data_size()));
1299     bind(profile_continue);
1300   }
1301 }
1302 
1303 
1304 void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
1305                                                      Register mdp,
1306                                                      Register reg2,
1307                                                      bool receiver_can_be_null) {
1308   if (ProfileInterpreter) {
1309     Label profile_continue;
1310 
1311     // If no method data exists, go to profile_continue.
1312     test_method_data_pointer(mdp, profile_continue);
1313 
1314     // We are making a call.  Increment the count.
1315     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1316 
1317     Label skip_receiver_profile;
1318     if (receiver_can_be_null) {
1319       testptr(receiver, receiver);
1320       jcc(Assembler::zero, skip_receiver_profile);
1321     }
1322 
1323     // Record the receiver type.
1324     record_klass_in_profile(receiver, mdp, reg2);
1325     bind(skip_receiver_profile);
1326 
1327     // The method data pointer needs to be updated to reflect the new target.
1328     update_mdp_by_constant(mdp,
1329                            in_bytes(VirtualCallData::
1330                                     virtual_call_data_size()));
1331     bind(profile_continue);
1332   }
1333 }
1334 
1335 // This routine creates a state machine for updating the multi-row
1336 // type profile at a virtual call site (or other type-sensitive bytecode).
1337 // The machine visits each row (of receiver/count) until the receiver type
1338 // is found, or until it runs out of rows.  At the same time, it remembers
1339 // the location of the first empty row.  (An empty row records null for its
1340 // receiver, and can be allocated for a newly-observed receiver type.)
1341 // Because there are two degrees of freedom in the state, a simple linear
1342 // search will not work; it must be a decision tree.  Hence this helper
1343 // function is recursive, to generate the required tree structured code.
1344 // It's the interpreter, so we are trading off code space for speed.
1345 // See below for example code.


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