< prev index next >

src/hotspot/cpu/x86/interp_masm_x86.cpp

Print this page




  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 "logging/log.hpp"
  30 #include "oops/arrayOop.hpp"
  31 #include "oops/markOop.hpp"
  32 #include "oops/methodData.hpp"
  33 #include "oops/method.hpp"

  34 #include "prims/jvmtiExport.hpp"
  35 #include "prims/jvmtiThreadState.hpp"
  36 #include "runtime/basicLock.hpp"
  37 #include "runtime/biasedLocking.hpp"
  38 #include "runtime/frame.inline.hpp"
  39 #include "runtime/safepointMechanism.hpp"
  40 #include "runtime/sharedRuntime.hpp"
  41 #include "runtime/thread.inline.hpp"
  42 
  43 // Implementation of InterpreterMacroAssembler
  44 
  45 void InterpreterMacroAssembler::jump_to_entry(address entry) {
  46   assert(entry, "Entry must have been generated by now");
  47   jump(RuntimeAddress(entry));
  48 }
  49 
  50 void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
  51   Label update, next, none;
  52 
  53   verify_oop(obj);


1080     bind(loop);
1081     // check if current entry is used
1082     cmpptr(Address(rmon, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL);
1083     jcc(Assembler::notEqual, exception);
1084 
1085     addptr(rmon, entry_size); // otherwise advance to next entry
1086     bind(entry);
1087     cmpptr(rmon, rbx); // check if bottom reached
1088     jcc(Assembler::notEqual, loop); // if not at bottom then check this entry
1089   }
1090 
1091   bind(no_unlock);
1092 
1093   // jvmti support
1094   if (notify_jvmdi) {
1095     notify_method_exit(state, NotifyJVMTI);    // preserve TOSCA
1096   } else {
1097     notify_method_exit(state, SkipNotifyJVMTI); // preserve TOSCA
1098   }
1099 
1100   // remove activation
1101   // get sender sp
1102   movptr(rbx,
1103          Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize));
1104   if (StackReservedPages > 0) {
1105     // testing if reserved zone needs to be re-enabled
1106     Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
1107     Label no_reserved_zone_enabling;
1108 
1109     NOT_LP64(get_thread(rthread);)
1110 
1111     cmpl(Address(rthread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_enabled);
1112     jcc(Assembler::equal, no_reserved_zone_enabling);
1113 
1114     cmpptr(rbx, Address(rthread, JavaThread::reserved_stack_activation_offset()));
1115     jcc(Assembler::lessEqual, no_reserved_zone_enabling);
1116 
1117     call_VM_leaf(
1118       CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), rthread);
1119     call_VM(noreg, CAST_FROM_FN_PTR(address,
1120                    InterpreterRuntime::throw_delayed_StackOverflowError));
1121     should_not_reach_here();
1122 
1123     bind(no_reserved_zone_enabling);
1124   }

































1125   leave();                           // remove frame anchor
1126   pop(ret_addr);                     // get return address
1127   mov(rsp, rbx);                     // set sp to sender sp
1128 }
1129 
1130 void InterpreterMacroAssembler::get_method_counters(Register method,
1131                                                     Register mcs, Label& skip) {
1132   Label has_counters;
1133   movptr(mcs, Address(method, Method::method_counters_offset()));
1134   testptr(mcs, mcs);
1135   jcc(Assembler::notZero, has_counters);
1136   call_VM(noreg, CAST_FROM_FN_PTR(address,
1137           InterpreterRuntime::build_method_counters), method);
1138   movptr(mcs, Address(method,Method::method_counters_offset()));
1139   testptr(mcs, mcs);
1140   jcc(Assembler::zero, skip); // No MethodCounters allocated, OutOfMemory
1141   bind(has_counters);
1142 }
1143 
1144 


1167 
1168     const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
1169     const int lock_offset = BasicObjectLock::lock_offset_in_bytes ();
1170     const int mark_offset = lock_offset +
1171                             BasicLock::displaced_header_offset_in_bytes();
1172 
1173     Label slow_case;
1174 
1175     // Load object pointer into obj_reg
1176     movptr(obj_reg, Address(lock_reg, obj_offset));
1177 
1178     if (UseBiasedLocking) {
1179       biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp_reg, false, done, &slow_case);
1180     }
1181 
1182     // Load immediate 1 into swap_reg %rax
1183     movl(swap_reg, (int32_t)1);
1184 
1185     // Load (object->mark() | 1) into swap_reg %rax
1186     orptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));




1187 
1188     // Save (object->mark() | 1) into BasicLock's displaced header
1189     movptr(Address(lock_reg, mark_offset), swap_reg);
1190 
1191     assert(lock_offset == 0,
1192            "displaced header must be first word in BasicObjectLock");
1193 
1194     lock();
1195     cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1196     if (PrintBiasedLockingStatistics) {
1197       cond_inc32(Assembler::zero,
1198                  ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr()));
1199     }
1200     jcc(Assembler::zero, done);
1201 
1202     const int zero_bits = LP64_ONLY(7) NOT_LP64(3);
1203 
1204     // Test if the oopMark is an obvious stack pointer, i.e.,
1205     //  1) (mark & zero_bits) == 0, and
1206     //  2) rsp <= mark < mark + os::pagesize()




  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 "logging/log.hpp"
  30 #include "oops/arrayOop.hpp"
  31 #include "oops/markOop.hpp"
  32 #include "oops/methodData.hpp"
  33 #include "oops/method.hpp"
  34 #include "oops/valueKlass.hpp"
  35 #include "prims/jvmtiExport.hpp"
  36 #include "prims/jvmtiThreadState.hpp"
  37 #include "runtime/basicLock.hpp"
  38 #include "runtime/biasedLocking.hpp"
  39 #include "runtime/frame.inline.hpp"
  40 #include "runtime/safepointMechanism.hpp"
  41 #include "runtime/sharedRuntime.hpp"
  42 #include "runtime/thread.inline.hpp"
  43 
  44 // Implementation of InterpreterMacroAssembler
  45 
  46 void InterpreterMacroAssembler::jump_to_entry(address entry) {
  47   assert(entry, "Entry must have been generated by now");
  48   jump(RuntimeAddress(entry));
  49 }
  50 
  51 void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
  52   Label update, next, none;
  53 
  54   verify_oop(obj);


1081     bind(loop);
1082     // check if current entry is used
1083     cmpptr(Address(rmon, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL);
1084     jcc(Assembler::notEqual, exception);
1085 
1086     addptr(rmon, entry_size); // otherwise advance to next entry
1087     bind(entry);
1088     cmpptr(rmon, rbx); // check if bottom reached
1089     jcc(Assembler::notEqual, loop); // if not at bottom then check this entry
1090   }
1091 
1092   bind(no_unlock);
1093 
1094   // jvmti support
1095   if (notify_jvmdi) {
1096     notify_method_exit(state, NotifyJVMTI);    // preserve TOSCA
1097   } else {
1098     notify_method_exit(state, SkipNotifyJVMTI); // preserve TOSCA
1099   }
1100 
1101   if (StackReservedPages > 0) {

1102     movptr(rbx,
1103                Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize));

1104     // testing if reserved zone needs to be re-enabled
1105     Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
1106     Label no_reserved_zone_enabling;
1107 
1108     NOT_LP64(get_thread(rthread);)
1109 
1110     cmpl(Address(rthread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_enabled);
1111     jcc(Assembler::equal, no_reserved_zone_enabling);
1112 
1113     cmpptr(rbx, Address(rthread, JavaThread::reserved_stack_activation_offset()));
1114     jcc(Assembler::lessEqual, no_reserved_zone_enabling);
1115 
1116     call_VM_leaf(
1117       CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), rthread);
1118     call_VM(noreg, CAST_FROM_FN_PTR(address,
1119                    InterpreterRuntime::throw_delayed_StackOverflowError));
1120     should_not_reach_here();
1121 
1122     bind(no_reserved_zone_enabling);
1123   }
1124 
1125   // remove activation
1126   // get sender sp
1127   movptr(rbx,
1128          Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize));
1129 
1130   if (state == atos && ValueTypeReturnedAsFields) {
1131     Label skip;
1132     // Test if the return type is a value type
1133     movptr(rdi, Address(rbp, frame::interpreter_frame_method_offset * wordSize));
1134     movptr(rdi, Address(rdi, Method::const_offset()));
1135     load_unsigned_byte(rdi, Address(rdi, ConstMethod::result_type_offset()));
1136     cmpl(rdi, T_VALUETYPE);
1137     jcc(Assembler::notEqual, skip);
1138 
1139     // We are returning a value type, load its fields into registers
1140 #ifndef _LP64
1141     super_call_VM_leaf(StubRoutines::load_value_type_fields_in_regs());
1142 #else
1143     // Load fields from a buffered value with a value class specific handler
1144     load_klass(rdi, rax);
1145     movptr(rdi, Address(rdi, InstanceKlass::adr_valueklass_fixed_block_offset()));
1146     movptr(rdi, Address(rdi, ValueKlass::unpack_handler_offset()));
1147 
1148     testptr(rdi, rdi);
1149     jcc(Assembler::equal, skip);
1150 
1151     call(rdi);
1152 #endif
1153     // call above kills the value in rbx. Reload it.
1154     movptr(rbx, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize));
1155     bind(skip);
1156   }
1157   leave();                           // remove frame anchor
1158   pop(ret_addr);                     // get return address
1159   mov(rsp, rbx);                     // set sp to sender sp
1160 }
1161 
1162 void InterpreterMacroAssembler::get_method_counters(Register method,
1163                                                     Register mcs, Label& skip) {
1164   Label has_counters;
1165   movptr(mcs, Address(method, Method::method_counters_offset()));
1166   testptr(mcs, mcs);
1167   jcc(Assembler::notZero, has_counters);
1168   call_VM(noreg, CAST_FROM_FN_PTR(address,
1169           InterpreterRuntime::build_method_counters), method);
1170   movptr(mcs, Address(method,Method::method_counters_offset()));
1171   testptr(mcs, mcs);
1172   jcc(Assembler::zero, skip); // No MethodCounters allocated, OutOfMemory
1173   bind(has_counters);
1174 }
1175 
1176 


1199 
1200     const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
1201     const int lock_offset = BasicObjectLock::lock_offset_in_bytes ();
1202     const int mark_offset = lock_offset +
1203                             BasicLock::displaced_header_offset_in_bytes();
1204 
1205     Label slow_case;
1206 
1207     // Load object pointer into obj_reg
1208     movptr(obj_reg, Address(lock_reg, obj_offset));
1209 
1210     if (UseBiasedLocking) {
1211       biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp_reg, false, done, &slow_case);
1212     }
1213 
1214     // Load immediate 1 into swap_reg %rax
1215     movl(swap_reg, (int32_t)1);
1216 
1217     // Load (object->mark() | 1) into swap_reg %rax
1218     orptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1219     if (EnableValhalla && !UseBiasedLocking) {
1220       // For slow path is_always_locked, using biased, which is never natural for !UseBiasLocking
1221       andptr(swap_reg, ~markOopDesc::biased_lock_bit_in_place);
1222     }
1223 
1224     // Save (object->mark() | 1) into BasicLock's displaced header
1225     movptr(Address(lock_reg, mark_offset), swap_reg);
1226 
1227     assert(lock_offset == 0,
1228            "displaced header must be first word in BasicObjectLock");
1229 
1230     lock();
1231     cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1232     if (PrintBiasedLockingStatistics) {
1233       cond_inc32(Assembler::zero,
1234                  ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr()));
1235     }
1236     jcc(Assembler::zero, done);
1237 
1238     const int zero_bits = LP64_ONLY(7) NOT_LP64(3);
1239 
1240     // Test if the oopMark is an obvious stack pointer, i.e.,
1241     //  1) (mark & zero_bits) == 0, and
1242     //  2) rsp <= mark < mark + os::pagesize()


< prev index next >