< prev index next >

src/cpu/x86/vm/sharedRuntime_x86_32.cpp

Print this page


   1 /*
   2  * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   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  *


  97   // Offsets into the register save area
  98   // Used by deoptimization when it is managing result register
  99   // values on its own
 100 
 101   static int raxOffset(void) { return rax_off; }
 102   static int rdxOffset(void) { return rdx_off; }
 103   static int rbxOffset(void) { return rbx_off; }
 104   static int xmm0Offset(void) { return xmm0_off; }
 105   // This really returns a slot in the fp save area, which one is not important
 106   static int fpResultOffset(void) { return st0_off; }
 107 
 108   // During deoptimization only the result register need to be restored
 109   // all the other values have already been extracted.
 110 
 111   static void restore_result_registers(MacroAssembler* masm);
 112 
 113 };
 114 
 115 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words,
 116                                            int* total_frame_words, bool verify_fpu, bool save_vectors) {
 117   int vect_words = 0;
 118   int num_xmm_regs = XMMRegisterImpl::number_of_registers;


 119 #ifdef COMPILER2
 120   if (save_vectors) {
 121     assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
 122     assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
 123     // Save upper half of ZMM/YMM registers :
 124     vect_words = 8 * 16 / wordSize;
 125     additional_frame_words += vect_words;




 126   }
 127 #else
 128   assert(!save_vectors, "vectors are generated only by C2");
 129 #endif
 130   int frame_size_in_bytes = (reg_save_size + additional_frame_words) * wordSize;
 131   int frame_words = frame_size_in_bytes / wordSize;
 132   *total_frame_words = frame_words;
 133 
 134   assert(FPUStateSizeInWords == 27, "update stack layout");
 135 
 136   // save registers, fpu state, and flags
 137   // We assume caller has already has return address slot on the stack
 138   // We push epb twice in this sequence because we want the real rbp,
 139   // to be under the return like a normal enter and we want to use pusha
 140   // We push by hand instead of pusing push
 141   __ enter();
 142   __ pusha();
 143   __ pushf();
 144   __ subptr(rsp,FPU_regs_live*wordSize); // Push FPU registers space
 145   __ push_FPU_state();          // Save FPU state & init


 168   }
 169 
 170   __ frstor(Address(rsp, 0));
 171   if (!verify_fpu) {
 172     // Set the control word so that exceptions are masked for the
 173     // following code.
 174     __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
 175   }
 176 
 177   int off = st0_off;
 178   int delta = st1_off - off;
 179 
 180   // Save the FPU registers in de-opt-able form
 181   for (int n = 0; n < FloatRegisterImpl::number_of_registers; n++) {
 182     __ fstp_d(Address(rsp, off*wordSize));
 183     off += delta;
 184   }
 185 
 186   off = xmm0_off;
 187   delta = xmm1_off - off;
 188   if(UseSSE == 1) {           // Save the XMM state

 189     for (int n = 0; n < num_xmm_regs; n++) {
 190       __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n));
 191       off += delta;
 192     }
 193   } else if(UseSSE >= 2) {
 194     // Save whole 128bit (16 bytes) XMM regiters
 195     for (int n = 0; n < num_xmm_regs; n++) {
 196       __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n));
 197       off += delta;
 198     }
 199   }
 200 
 201   if (save_vectors) {
 202     assert(vect_words*wordSize == 128, "");
 203     __ subptr(rsp, 128); // Save upper half of YMM registes
 204     for (int n = 0; n < num_xmm_regs; n++) {
 205       __ vextractf128h(Address(rsp, n*16), as_XMMRegister(n));
 206     }
 207     if (UseAVX > 2) {
 208       __ subptr(rsp, 256); // Save upper half of ZMM registes

 209       for (int n = 0; n < num_xmm_regs; n++) {
 210         __ vextractf64x4h(Address(rsp, n*32), as_XMMRegister(n), 1);
 211       }
 212     }
 213   }
 214 
 215   // Set an oopmap for the call site.  This oopmap will map all
 216   // oop-registers and debug-info registers as callee-saved.  This
 217   // will allow deoptimization at this safepoint to find all possible
 218   // debug-info recordings, as well as let GC find all oops.
 219 
 220   OopMapSet *oop_maps = new OopMapSet();
 221   OopMap* map =  new OopMap( frame_words, 0 );
 222 
 223 #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_words)
 224 #define NEXTREG(x) (x)->as_VMReg()->next()
 225 
 226   map->set_callee_saved(STACK_OFFSET(rax_off), rax->as_VMReg());
 227   map->set_callee_saved(STACK_OFFSET(rcx_off), rcx->as_VMReg());
 228   map->set_callee_saved(STACK_OFFSET(rdx_off), rdx->as_VMReg());


 238     map->set_callee_saved(STACK_OFFSET(off), freg_name->as_VMReg());
 239     map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(freg_name));
 240     off += delta;
 241   }
 242   off = xmm0_off;
 243   delta = xmm1_off - off;
 244   for (int n = 0; n < num_xmm_regs; n++) {
 245     XMMRegister xmm_name = as_XMMRegister(n);
 246     map->set_callee_saved(STACK_OFFSET(off), xmm_name->as_VMReg());
 247     map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(xmm_name));
 248     off += delta;
 249   }
 250 #undef NEXTREG
 251 #undef STACK_OFFSET
 252 
 253   return map;
 254 }
 255 
 256 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
 257   int num_xmm_regs = XMMRegisterImpl::number_of_registers;


 258   // Recover XMM & FPU state
 259   int additional_frame_bytes = 0;
 260 #ifdef COMPILER2
 261   if (restore_vectors) {
 262     assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
 263     assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
 264     additional_frame_bytes = 128;





 265   }
 266 #else
 267   assert(!restore_vectors, "vectors are generated only by C2");
 268 #endif
 269 
 270   if (restore_vectors) {
 271     assert(additional_frame_bytes == 128, "");
 272     if (UseAVX > 2) {
 273       // Restore upper half of ZMM registers.
 274       for (int n = 0; n < num_xmm_regs; n++) {
 275         __ vinsertf64x4h(as_XMMRegister(n), Address(rsp, n*32), 1);
 276       }
 277       __ addptr(rsp, additional_frame_bytes*2); // Save upper half of ZMM registes
 278     }
 279     // Restore upper half of YMM registes.
 280     for (int n = 0; n < num_xmm_regs; n++) {
 281       __ vinsertf128h(as_XMMRegister(n), Address(rsp, n*16));
 282     }
 283     __ addptr(rsp, additional_frame_bytes); // Save upper half of YMM registes
 284   }
 285 
 286   int off = xmm0_off;
 287   int delta = xmm1_off - off;
 288 
 289   if (UseSSE == 1) {


 290     for (int n = 0; n < num_xmm_regs; n++) {
 291       __ movflt(as_XMMRegister(n), Address(rsp, off*wordSize));
 292       off += delta;
 293     }
 294   } else if (UseSSE >= 2) {
 295     // additional_frame_bytes only populated for the restore_vector case, else it is 0

 296     for (int n = 0; n < num_xmm_regs; n++) {
 297       __ movdqu(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes));
 298       off += delta;
 299     }
 300   }
 301 















 302   __ pop_FPU_state();
 303   __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers
 304 
 305   __ popf();
 306   __ popa();
 307   // Get the rbp, described implicitly by the frame sender code (no oopMap)
 308   __ pop(rbp);
 309 
 310 }
 311 
 312 void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
 313 
 314   // Just restore result register. Only used by deoptimization. By
 315   // now any callee save register that needs to be restore to a c2
 316   // caller of the deoptee has been extracted into the vframeArray
 317   // and will be stuffed into the c2i adapter we create for later
 318   // restoration so only result registers need to be restored here.
 319   //
 320 
 321   __ frstor(Address(rsp, 0));      // Restore fpu state
 322 
 323   // Recover XMM & FPU state
 324   if( UseSSE == 1 ) {
 325     __ movflt(xmm0, Address(rsp, xmm0_off*wordSize));
 326   } else if( UseSSE >= 2 ) {
 327     __ movdbl(xmm0, Address(rsp, xmm0_off*wordSize));
 328   }
 329   __ movptr(rax, Address(rsp, rax_off*wordSize));


   1 /*
   2  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   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  *


  97   // Offsets into the register save area
  98   // Used by deoptimization when it is managing result register
  99   // values on its own
 100 
 101   static int raxOffset(void) { return rax_off; }
 102   static int rdxOffset(void) { return rdx_off; }
 103   static int rbxOffset(void) { return rbx_off; }
 104   static int xmm0Offset(void) { return xmm0_off; }
 105   // This really returns a slot in the fp save area, which one is not important
 106   static int fpResultOffset(void) { return st0_off; }
 107 
 108   // During deoptimization only the result register need to be restored
 109   // all the other values have already been extracted.
 110 
 111   static void restore_result_registers(MacroAssembler* masm);
 112 
 113 };
 114 
 115 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words,
 116                                            int* total_frame_words, bool verify_fpu, bool save_vectors) {

 117   int num_xmm_regs = XMMRegisterImpl::number_of_registers;
 118   int ymm_bytes = num_xmm_regs * 16;
 119   int zmm_bytes = num_xmm_regs * 32;
 120 #ifdef COMPILER2
 121   if (save_vectors) {
 122     assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
 123     assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
 124     // Save upper half of YMM registers
 125     int vect_bytes = ymm_bytes;
 126     if (UseAVX > 2) {
 127       // Save upper half of ZMM registers as well
 128       vect_bytes += zmm_bytes;
 129     }
 130     additional_frame_words += vect_bytes / wordSize;
 131   }
 132 #else
 133   assert(!save_vectors, "vectors are generated only by C2");
 134 #endif
 135   int frame_size_in_bytes = (reg_save_size + additional_frame_words) * wordSize;
 136   int frame_words = frame_size_in_bytes / wordSize;
 137   *total_frame_words = frame_words;
 138 
 139   assert(FPUStateSizeInWords == 27, "update stack layout");
 140 
 141   // save registers, fpu state, and flags
 142   // We assume caller has already has return address slot on the stack
 143   // We push epb twice in this sequence because we want the real rbp,
 144   // to be under the return like a normal enter and we want to use pusha
 145   // We push by hand instead of pusing push
 146   __ enter();
 147   __ pusha();
 148   __ pushf();
 149   __ subptr(rsp,FPU_regs_live*wordSize); // Push FPU registers space
 150   __ push_FPU_state();          // Save FPU state & init


 173   }
 174 
 175   __ frstor(Address(rsp, 0));
 176   if (!verify_fpu) {
 177     // Set the control word so that exceptions are masked for the
 178     // following code.
 179     __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
 180   }
 181 
 182   int off = st0_off;
 183   int delta = st1_off - off;
 184 
 185   // Save the FPU registers in de-opt-able form
 186   for (int n = 0; n < FloatRegisterImpl::number_of_registers; n++) {
 187     __ fstp_d(Address(rsp, off*wordSize));
 188     off += delta;
 189   }
 190 
 191   off = xmm0_off;
 192   delta = xmm1_off - off;
 193   if(UseSSE == 1) {
 194     // Save the XMM state
 195     for (int n = 0; n < num_xmm_regs; n++) {
 196       __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n));
 197       off += delta;
 198     }
 199   } else if(UseSSE >= 2) {
 200     // Save whole 128bit (16 bytes) XMM registers
 201     for (int n = 0; n < num_xmm_regs; n++) {
 202       __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n));
 203       off += delta;
 204     }
 205   }
 206 
 207   if (save_vectors) {
 208     __ subptr(rsp, ymm_bytes);
 209     // Save upper half of YMM registers
 210     for (int n = 0; n < num_xmm_regs; n++) {
 211       __ vextractf128h(Address(rsp, n*16), as_XMMRegister(n));
 212     }
 213     if (UseAVX > 2) {
 214       __ subptr(rsp, zmm_bytes);
 215       // Save upper half of ZMM registers
 216       for (int n = 0; n < num_xmm_regs; n++) {
 217         __ vextractf64x4h(Address(rsp, n*32), as_XMMRegister(n), 1);
 218       }
 219     }
 220   }
 221 
 222   // Set an oopmap for the call site.  This oopmap will map all
 223   // oop-registers and debug-info registers as callee-saved.  This
 224   // will allow deoptimization at this safepoint to find all possible
 225   // debug-info recordings, as well as let GC find all oops.
 226 
 227   OopMapSet *oop_maps = new OopMapSet();
 228   OopMap* map =  new OopMap( frame_words, 0 );
 229 
 230 #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_words)
 231 #define NEXTREG(x) (x)->as_VMReg()->next()
 232 
 233   map->set_callee_saved(STACK_OFFSET(rax_off), rax->as_VMReg());
 234   map->set_callee_saved(STACK_OFFSET(rcx_off), rcx->as_VMReg());
 235   map->set_callee_saved(STACK_OFFSET(rdx_off), rdx->as_VMReg());


 245     map->set_callee_saved(STACK_OFFSET(off), freg_name->as_VMReg());
 246     map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(freg_name));
 247     off += delta;
 248   }
 249   off = xmm0_off;
 250   delta = xmm1_off - off;
 251   for (int n = 0; n < num_xmm_regs; n++) {
 252     XMMRegister xmm_name = as_XMMRegister(n);
 253     map->set_callee_saved(STACK_OFFSET(off), xmm_name->as_VMReg());
 254     map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(xmm_name));
 255     off += delta;
 256   }
 257 #undef NEXTREG
 258 #undef STACK_OFFSET
 259 
 260   return map;
 261 }
 262 
 263 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
 264   int num_xmm_regs = XMMRegisterImpl::number_of_registers;
 265   int ymm_bytes = num_xmm_regs * 16;
 266   int zmm_bytes = num_xmm_regs * 32;
 267   // Recover XMM & FPU state
 268   int additional_frame_bytes = 0;
 269 #ifdef COMPILER2
 270   if (restore_vectors) {
 271     assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
 272     assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
 273     // Save upper half of YMM registers
 274     additional_frame_bytes = ymm_bytes;
 275     if (UseAVX > 2) {
 276       // Save upper half of ZMM registers as well
 277       additional_frame_bytes += zmm_bytes;
 278     }
 279   }
 280 #else
 281   assert(!restore_vectors, "vectors are generated only by C2");
 282 #endif
 283 
















 284   int off = xmm0_off;
 285   int delta = xmm1_off - off;
 286 
 287   if (UseSSE == 1) {
 288     // Restore XMM registers
 289     assert(additional_frame_bytes == 0, "");
 290     for (int n = 0; n < num_xmm_regs; n++) {
 291       __ movflt(as_XMMRegister(n), Address(rsp, off*wordSize));
 292       off += delta;
 293     }
 294   } else if (UseSSE >= 2) {
 295     // Restore whole 128bit (16 bytes) XMM registers. Do this before restoring YMM and
 296     // ZMM because the movdqu instruction zeros the upper part of the XMM register.
 297     for (int n = 0; n < num_xmm_regs; n++) {
 298       __ movdqu(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes));
 299       off += delta;
 300     }
 301   }
 302 
 303   if (restore_vectors) {
 304     if (UseAVX > 2) {
 305       // Restore upper half of ZMM registers.
 306       for (int n = 0; n < num_xmm_regs; n++) {
 307         __ vinsertf64x4h(as_XMMRegister(n), Address(rsp, n*32), 1);
 308       }
 309       __ addptr(rsp, zmm_bytes);
 310     }
 311     // Restore upper half of YMM registers.
 312     for (int n = 0; n < num_xmm_regs; n++) {
 313       __ vinsertf128h(as_XMMRegister(n), Address(rsp, n*16));
 314     }
 315     __ addptr(rsp, ymm_bytes);
 316   }
 317 
 318   __ pop_FPU_state();
 319   __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers
 320 
 321   __ popf();
 322   __ popa();
 323   // Get the rbp, described implicitly by the frame sender code (no oopMap)
 324   __ pop(rbp);

 325 }
 326 
 327 void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
 328 
 329   // Just restore result register. Only used by deoptimization. By
 330   // now any callee save register that needs to be restore to a c2
 331   // caller of the deoptee has been extracted into the vframeArray
 332   // and will be stuffed into the c2i adapter we create for later
 333   // restoration so only result registers need to be restored here.
 334   //
 335 
 336   __ frstor(Address(rsp, 0));      // Restore fpu state
 337 
 338   // Recover XMM & FPU state
 339   if( UseSSE == 1 ) {
 340     __ movflt(xmm0, Address(rsp, xmm0_off*wordSize));
 341   } else if( UseSSE >= 2 ) {
 342     __ movdbl(xmm0, Address(rsp, xmm0_off*wordSize));
 343   }
 344   __ movptr(rax, Address(rsp, rax_off*wordSize));


< prev index next >