26 #include "asm/macroAssembler.hpp" |
26 #include "asm/macroAssembler.hpp" |
27 #include "asm/macroAssembler.inline.hpp" |
27 #include "asm/macroAssembler.inline.hpp" |
28 #include "ci/ciUtilities.hpp" |
28 #include "ci/ciUtilities.hpp" |
29 #include "gc/shared/barrierSet.hpp" |
29 #include "gc/shared/barrierSet.hpp" |
30 #include "gc/shared/barrierSetAssembler.hpp" |
30 #include "gc/shared/barrierSetAssembler.hpp" |
|
31 #include "gc/shared/barrierSetNMethod.hpp" |
31 #include "interpreter/interpreter.hpp" |
32 #include "interpreter/interpreter.hpp" |
32 #include "nativeInst_x86.hpp" |
33 #include "nativeInst_x86.hpp" |
33 #include "oops/instanceOop.hpp" |
34 #include "oops/instanceOop.hpp" |
34 #include "oops/method.hpp" |
35 #include "oops/method.hpp" |
35 #include "oops/objArrayKlass.hpp" |
36 #include "oops/objArrayKlass.hpp" |
5192 __ ret(0); |
5193 __ ret(0); |
5193 |
5194 |
5194 return start; |
5195 return start; |
5195 } |
5196 } |
5196 |
5197 |
|
5198 address generate_method_entry_barrier() { |
|
5199 __ align(CodeEntryAlignment); |
|
5200 StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier"); |
|
5201 |
|
5202 Label deoptimize_label; |
|
5203 |
|
5204 address start = __ pc(); |
|
5205 |
|
5206 __ push(-1); // cookie, this is used for writing the new rsp when deoptimizing |
|
5207 |
|
5208 BLOCK_COMMENT("Entry:"); |
|
5209 __ enter(); // save rbp |
|
5210 |
|
5211 // save c_rarg0, because we want to use that value. |
|
5212 // We could do without it but then we depend on the number of slots used by pusha |
|
5213 __ push(c_rarg0); |
|
5214 |
|
5215 __ lea(c_rarg0, Address(rsp, wordSize * 3)); // 1 for cookie, 1 for rbp, 1 for c_rarg0 - this should be the return address |
|
5216 |
|
5217 __ pusha(); |
|
5218 |
|
5219 // The method may have floats as arguments, and we must spill them before calling |
|
5220 // the VM runtime. |
|
5221 assert(Argument::n_float_register_parameters_j == 8, "Assumption"); |
|
5222 const int xmm_size = wordSize * 2; |
|
5223 const int xmm_spill_size = xmm_size * Argument::n_float_register_parameters_j; |
|
5224 __ subptr(rsp, xmm_spill_size); |
|
5225 __ movdqu(Address(rsp, xmm_size * 7), xmm7); |
|
5226 __ movdqu(Address(rsp, xmm_size * 6), xmm6); |
|
5227 __ movdqu(Address(rsp, xmm_size * 5), xmm5); |
|
5228 __ movdqu(Address(rsp, xmm_size * 4), xmm4); |
|
5229 __ movdqu(Address(rsp, xmm_size * 3), xmm3); |
|
5230 __ movdqu(Address(rsp, xmm_size * 2), xmm2); |
|
5231 __ movdqu(Address(rsp, xmm_size * 1), xmm1); |
|
5232 __ movdqu(Address(rsp, xmm_size * 0), xmm0); |
|
5233 |
|
5234 __ call_VM_leaf(CAST_FROM_FN_PTR(address, static_cast<int (*)(address*)>(BarrierSetNMethod::nmethod_stub_entry_barrier)), 1); |
|
5235 |
|
5236 __ movdqu(xmm0, Address(rsp, xmm_size * 0)); |
|
5237 __ movdqu(xmm1, Address(rsp, xmm_size * 1)); |
|
5238 __ movdqu(xmm2, Address(rsp, xmm_size * 2)); |
|
5239 __ movdqu(xmm3, Address(rsp, xmm_size * 3)); |
|
5240 __ movdqu(xmm4, Address(rsp, xmm_size * 4)); |
|
5241 __ movdqu(xmm5, Address(rsp, xmm_size * 5)); |
|
5242 __ movdqu(xmm6, Address(rsp, xmm_size * 6)); |
|
5243 __ movdqu(xmm7, Address(rsp, xmm_size * 7)); |
|
5244 __ addptr(rsp, xmm_spill_size); |
|
5245 |
|
5246 __ cmpl(rax, 1); // 1 means deoptimize |
|
5247 __ jcc(Assembler::equal, deoptimize_label); |
|
5248 |
|
5249 __ popa(); |
|
5250 __ pop(c_rarg0); |
|
5251 |
|
5252 __ leave(); |
|
5253 |
|
5254 __ addptr(rsp, 1 * wordSize); // cookie |
|
5255 __ ret(0); |
|
5256 |
|
5257 |
|
5258 __ BIND(deoptimize_label); |
|
5259 |
|
5260 __ popa(); |
|
5261 __ pop(c_rarg0); |
|
5262 |
|
5263 __ leave(); |
|
5264 |
|
5265 // this can be taken out, but is good for verification purposes. getting a SIGSEGV |
|
5266 // here while still having a correct stack is valuable |
|
5267 __ testptr(rsp, Address(rsp, 0)); |
|
5268 |
|
5269 __ movptr(rsp, Address(rsp, 0)); // new rsp was written in the barrier |
|
5270 __ jmp(Address(rsp, -1 * wordSize)); // jmp target should be callers verified_entry_point |
|
5271 |
|
5272 return start; |
|
5273 } |
|
5274 |
5197 /** |
5275 /** |
5198 * Arguments: |
5276 * Arguments: |
5199 * |
5277 * |
5200 * Input: |
5278 * Input: |
5201 * c_rarg0 - out address |
5279 * c_rarg0 - out address |
5829 &StubRoutines::_safefetch32_fault_pc, |
5907 &StubRoutines::_safefetch32_fault_pc, |
5830 &StubRoutines::_safefetch32_continuation_pc); |
5908 &StubRoutines::_safefetch32_continuation_pc); |
5831 generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, |
5909 generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, |
5832 &StubRoutines::_safefetchN_fault_pc, |
5910 &StubRoutines::_safefetchN_fault_pc, |
5833 &StubRoutines::_safefetchN_continuation_pc); |
5911 &StubRoutines::_safefetchN_continuation_pc); |
|
5912 |
|
5913 BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); |
|
5914 if (bs_nm != NULL) { |
|
5915 StubRoutines::x86::_method_entry_barrier = generate_method_entry_barrier(); |
|
5916 } |
5834 #ifdef COMPILER2 |
5917 #ifdef COMPILER2 |
5835 if (UseMultiplyToLenIntrinsic) { |
5918 if (UseMultiplyToLenIntrinsic) { |
5836 StubRoutines::_multiplyToLen = generate_multiplyToLen(); |
5919 StubRoutines::_multiplyToLen = generate_multiplyToLen(); |
5837 } |
5920 } |
5838 if (UseSquareToLenIntrinsic) { |
5921 if (UseSquareToLenIntrinsic) { |