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

src/cpu/x86/vm/interp_masm_x86_64.cpp

Print this page
rev 5468 : 8026251: New type profiling points: parameters to methods
Summary: x86 interpreter and c1 type profiling for parameters on method entries
Reviewed-by:
rev 5469 : [mq]: parameters-review


   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "interp_masm_x86_64.hpp"
  27 #include "interpreter/interpreter.hpp"
  28 #include "interpreter/interpreterRuntime.hpp"
  29 #include "oops/arrayOop.hpp"
  30 #include "oops/markOop.hpp"
  31 #include "oops/methodData.hpp"
  32 #include "oops/method.hpp"
  33 #include "prims/jvmtiExport.hpp"
  34 #include "prims/jvmtiRedefineClassesTrace.hpp"
  35 #include "prims/jvmtiThreadState.hpp"
  36 #include "runtime/basicLock.hpp"
  37 #include "runtime/biasedLocking.hpp"
  38 #include "runtime/sharedRuntime.hpp"
  39 #include "runtime/thread.inline.hpp"
  40 
  41 
  42 // Implementation of InterpreterMacroAssembler
  43 
  44 #ifdef CC_INTERP
  45 void InterpreterMacroAssembler::get_method(Register reg) {
  46   movptr(reg, Address(rbp, -((int)sizeof(BytecodeInterpreter) + 2 * wordSize)));


1046     // The method data pointer needs to be updated to reflect the new target.
1047     update_mdp_by_offset(mdp, in_bytes(JumpData::displacement_offset()));
1048     bind(profile_continue);
1049   }
1050 }
1051 
1052 
1053 void InterpreterMacroAssembler::profile_not_taken_branch(Register mdp) {
1054   if (ProfileInterpreter) {
1055     Label profile_continue;
1056 
1057     // If no method data exists, go to profile_continue.
1058     test_method_data_pointer(mdp, profile_continue);
1059 
1060     // We are taking a branch.  Increment the not taken count.
1061     increment_mdp_data_at(mdp, in_bytes(BranchData::not_taken_offset()));
1062 
1063     // The method data pointer needs to be updated to correspond to
1064     // the next bytecode
1065     update_mdp_by_constant(mdp, in_bytes(BranchData::branch_data_size()));
1066     bind(profile_continue);
1067   }
1068 }
1069 
1070 void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
1071   Label update, next, none;
1072 
1073   verify_oop(obj);
1074 
1075   testptr(obj, obj);
1076   jccb(Assembler::notZero, update);
1077   orptr(mdo_addr, TypeEntries::null_seen);
1078   jmpb(next);
1079 
1080   bind(update);
1081   load_klass(obj, obj);
1082 
1083   xorptr(obj, mdo_addr);
1084   testptr(obj, TypeEntries::type_klass_mask);
1085   jccb(Assembler::zero, next); // klass seen before, nothing to
1086                                // do. The unknown bit may have been
1087                                // set already but no need to check.
1088 
1089   testptr(obj, TypeEntries::type_unknown);
1090   jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
1091 
1092   // There is a chance that by the time we do these checks (re-reading
1093   // profiling data from memory) another thread has set the profling
1094   // to this obj's klass and we set the profiling as unknow
1095   // erroneously
1096   cmpptr(mdo_addr, 0);
1097   jccb(Assembler::equal, none);
1098   cmpptr(mdo_addr, TypeEntries::null_seen);
1099   jccb(Assembler::equal, none);
1100   // There is a chance that the checks above (re-reading profiling
1101   // data from memory) fail if another thread has just set the
1102   // profiling to this obj's klass
1103   xorptr(obj, mdo_addr);
1104   testptr(obj, TypeEntries::type_klass_mask);
1105   jccb(Assembler::zero, next);
1106 
1107   // different than before. Cannot keep accurate profile.
1108   orptr(mdo_addr, TypeEntries::type_unknown);
1109   jmpb(next);
1110 
1111   bind(none);
1112   // first time here. Set profile type.
1113   movptr(mdo_addr, obj);
1114 
1115   bind(next);
1116 }
1117 
1118 void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) {
1119   if (!ProfileInterpreter) {
1120     return;
1121   }
1122 
1123   if (MethodData::profile_arguments() || MethodData::profile_return()) {
1124     Label profile_continue;
1125 
1126     test_method_data_pointer(mdp, profile_continue);
1127 
1128     int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());
1129 
1130     cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag);
1131     jcc(Assembler::notEqual, profile_continue);
1132 
1133     if (MethodData::profile_arguments()) {
1134       Label done;
1135       int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset());
1136       addptr(mdp, off_to_args);
1137 
1138       for (int i = 0; i < TypeProfileArgsLimit; i++) {
1139         if (i > 0 || MethodData::profile_return()) {
1140           // If return value type is profiled we may have no argument to profile
1141           movq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
1142           subl(tmp, i*TypeStackSlotEntries::per_arg_count());
1143           cmpl(tmp, TypeStackSlotEntries::per_arg_count());
1144           jcc(Assembler::less, done);
1145         }
1146         movptr(tmp, Address(callee, Method::const_offset()));
1147         load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset()));
1148         subq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args));
1149         subl(tmp, 1);
1150         Address arg_addr = argument_address(tmp);
1151         movptr(tmp, arg_addr);
1152 
1153         Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args);
1154         profile_obj_type(tmp, mdo_arg_addr);
1155 
1156         int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
1157         addptr(mdp, to_add);
1158         off_to_args += to_add;
1159       }
1160 
1161       if (MethodData::profile_return()) {
1162         movq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
1163         subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
1164       }
1165 
1166       bind(done);
1167 
1168       if (MethodData::profile_return()) {
1169         // We're right after the type profile for the last
1170         // argument. tmp is the number of cell left in the
1171         // CallTypeData/VirtualCallTypeData to reach its end. Non null
1172         // if there's a return to profile.
1173         assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type");
1174         shll(tmp, exact_log2(DataLayout::cell_size));
1175         addptr(mdp, tmp);
1176       }
1177       movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp);
1178     } else {
1179       assert(MethodData::profile_return(), "either profile call args or call ret");
1180       update_mdp_by_constant(mdp, in_bytes(ReturnTypeEntry::size()));
1181     }
1182 
1183     // mdp points right after the end of the
1184     // CallTypeData/VirtualCallTypeData, right after the cells for the
1185     // return value type if there's one
1186 
1187     bind(profile_continue);
1188   }
1189 }
1190 
1191 void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) {
1192   assert_different_registers(mdp, ret, tmp, r13);
1193   if (ProfileInterpreter && MethodData::profile_return()) {
1194     Label profile_continue, done;
1195 
1196     test_method_data_pointer(mdp, profile_continue);
1197 
1198     if (MethodData::profile_return_jsr292_only()) {
1199       // If we don't profile all invoke bytecodes we must make sure
1200       // it's a bytecode we indeed profile. We can't go back to the
1201       // begining of the ProfileData we intend to update to check its
1202       // type because we're right after it and we don't known its
1203       // length
1204       Label do_profile;
1205       cmpb(Address(r13, 0), Bytecodes::_invokedynamic);
1206       jcc(Assembler::equal, do_profile);
1207       cmpb(Address(r13, 0), Bytecodes::_invokehandle);
1208       jcc(Assembler::equal, do_profile);
1209       get_method(tmp);
1210       cmpb(Address(tmp, Method::intrinsic_id_offset_in_bytes()), vmIntrinsics::_compiledLambdaForm);
1211       jcc(Assembler::notEqual, profile_continue);
1212 
1213       bind(do_profile);
1214     }
1215 
1216     Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size()));
1217     mov(tmp, ret);
1218     profile_obj_type(tmp, mdo_ret_addr);
1219 
1220     bind(profile_continue);
1221   }
1222 }
1223 
1224 void InterpreterMacroAssembler::profile_call(Register mdp) {
1225   if (ProfileInterpreter) {
1226     Label profile_continue;
1227 
1228     // If no method data exists, go to profile_continue.
1229     test_method_data_pointer(mdp, profile_continue);
1230 
1231     // We are making a call.  Increment the count.
1232     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1233 
1234     // The method data pointer needs to be updated to reflect the new target.
1235     update_mdp_by_constant(mdp, in_bytes(CounterData::counter_data_size()));
1236     bind(profile_continue);
1237   }
1238 }
1239 




   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "interp_masm_x86.hpp"
  27 #include "interpreter/interpreter.hpp"
  28 #include "interpreter/interpreterRuntime.hpp"
  29 #include "oops/arrayOop.hpp"
  30 #include "oops/markOop.hpp"
  31 #include "oops/methodData.hpp"
  32 #include "oops/method.hpp"
  33 #include "prims/jvmtiExport.hpp"
  34 #include "prims/jvmtiRedefineClassesTrace.hpp"
  35 #include "prims/jvmtiThreadState.hpp"
  36 #include "runtime/basicLock.hpp"
  37 #include "runtime/biasedLocking.hpp"
  38 #include "runtime/sharedRuntime.hpp"
  39 #include "runtime/thread.inline.hpp"
  40 
  41 
  42 // Implementation of InterpreterMacroAssembler
  43 
  44 #ifdef CC_INTERP
  45 void InterpreterMacroAssembler::get_method(Register reg) {
  46   movptr(reg, Address(rbp, -((int)sizeof(BytecodeInterpreter) + 2 * wordSize)));


1046     // The method data pointer needs to be updated to reflect the new target.
1047     update_mdp_by_offset(mdp, in_bytes(JumpData::displacement_offset()));
1048     bind(profile_continue);
1049   }
1050 }
1051 
1052 
1053 void InterpreterMacroAssembler::profile_not_taken_branch(Register mdp) {
1054   if (ProfileInterpreter) {
1055     Label profile_continue;
1056 
1057     // If no method data exists, go to profile_continue.
1058     test_method_data_pointer(mdp, profile_continue);
1059 
1060     // We are taking a branch.  Increment the not taken count.
1061     increment_mdp_data_at(mdp, in_bytes(BranchData::not_taken_offset()));
1062 
1063     // The method data pointer needs to be updated to correspond to
1064     // the next bytecode
1065     update_mdp_by_constant(mdp, in_bytes(BranchData::branch_data_size()));


























































































































































1066     bind(profile_continue);
1067   }
1068 }
1069 
1070 void InterpreterMacroAssembler::profile_call(Register mdp) {
1071   if (ProfileInterpreter) {
1072     Label profile_continue;
1073 
1074     // If no method data exists, go to profile_continue.
1075     test_method_data_pointer(mdp, profile_continue);
1076 
1077     // We are making a call.  Increment the count.
1078     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1079 
1080     // The method data pointer needs to be updated to reflect the new target.
1081     update_mdp_by_constant(mdp, in_bytes(CounterData::counter_data_size()));
1082     bind(profile_continue);
1083   }
1084 }
1085 


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