< prev index next >

src/cpu/x86/vm/jniFastGetField_x86_32.cpp

Print this page




  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 "asm/macroAssembler.hpp"
  27 #include "memory/resourceArea.hpp"
  28 #include "prims/jniFastGetField.hpp"
  29 #include "prims/jvm_misc.hpp"
  30 #include "runtime/safepoint.hpp"

  31 
  32 #define __ masm->
  33 
  34 #define BUFFER_SIZE 30
  35 
  36 #ifdef _WINDOWS
  37 GetBooleanField_t JNI_FastGetField::jni_fast_GetBooleanField_fp;
  38 GetByteField_t    JNI_FastGetField::jni_fast_GetByteField_fp;
  39 GetCharField_t    JNI_FastGetField::jni_fast_GetCharField_fp;
  40 GetShortField_t   JNI_FastGetField::jni_fast_GetShortField_fp;
  41 GetIntField_t     JNI_FastGetField::jni_fast_GetIntField_fp;
  42 GetLongField_t    JNI_FastGetField::jni_fast_GetLongField_fp;
  43 GetFloatField_t   JNI_FastGetField::jni_fast_GetFloatField_fp;
  44 GetDoubleField_t  JNI_FastGetField::jni_fast_GetDoubleField_fp;
  45 #endif
  46 
  47 // Instead of issuing lfence for LoadLoad barrier, we create data dependency
  48 // between loads, which is much more efficient than lfence.
  49 
  50 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {


  69   //  return pc        0
  70   //  jni env          1
  71   //  obj              2
  72   //  jfieldID         3
  73 
  74   ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
  75   __ mov32 (rcx, counter);
  76   __ testb (rcx, 1);
  77   __ jcc (Assembler::notZero, slow);
  78   if (os::is_MP()) {
  79     __ mov(rax, rcx);
  80     __ andptr(rax, 1);                         // rax, must end up 0
  81     __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize));
  82                                               // obj, notice rax, is 0.
  83                                               // rdx is data dependent on rcx.
  84   } else {
  85     __ movptr (rdx, Address(rsp, 2*wordSize));  // obj
  86   }
  87   __ movptr(rax, Address(rsp, 3*wordSize));  // jfieldID
  88   __ movptr(rdx, Address(rdx, 0));           // *obj
  89   __ shrptr (rax, 2);                         // offset
  90 
  91   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
  92   speculative_load_pclist[count] = __ pc();
  93   switch (type) {
  94     case T_BOOLEAN: __ movzbl (rax, Address(rdx, rax, Address::times_1)); break;
  95     case T_BYTE:    __ movsbl (rax, Address(rdx, rax, Address::times_1)); break;
  96     case T_CHAR:    __ movzwl (rax, Address(rdx, rax, Address::times_1)); break;
  97     case T_SHORT:   __ movswl (rax, Address(rdx, rax, Address::times_1)); break;
  98     case T_INT:     __ movl   (rax, Address(rdx, rax, Address::times_1)); break;
  99     default:        ShouldNotReachHere();
 100   }
 101 
 102   Address ca1;
 103   if (os::is_MP()) {
 104     __ lea(rdx, counter);
 105     __ xorptr(rdx, rax);
 106     __ xorptr(rdx, rax);
 107     __ cmp32(rcx, Address(rdx, 0));
 108     // ca1 is the same as ca because
 109     // rax, ^ counter_addr ^ rax, = address


 186   //  obj              3
 187   //  jfieldID         4
 188 
 189   ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
 190 
 191   __ push  (rsi);
 192   __ mov32 (rcx, counter);
 193   __ testb (rcx, 1);
 194   __ jcc (Assembler::notZero, slow);
 195   if (os::is_MP()) {
 196     __ mov(rax, rcx);
 197     __ andptr(rax, 1);                         // rax, must end up 0
 198     __ movptr(rdx, Address(rsp, rax, Address::times_1, 3*wordSize));
 199                                               // obj, notice rax, is 0.
 200                                               // rdx is data dependent on rcx.
 201   } else {
 202     __ movptr(rdx, Address(rsp, 3*wordSize));  // obj
 203   }
 204   __ movptr(rsi, Address(rsp, 4*wordSize));  // jfieldID
 205   __ movptr(rdx, Address(rdx, 0));           // *obj
 206   __ shrptr(rsi, 2);                         // offset
 207 
 208   assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small");
 209   speculative_load_pclist[count++] = __ pc();
 210   __ movptr(rax, Address(rdx, rsi, Address::times_1));
 211 #ifndef _LP64
 212   speculative_load_pclist[count] = __ pc();
 213   __ movl(rdx, Address(rdx, rsi, Address::times_1, 4));
 214 #endif // _LP64
 215 
 216   if (os::is_MP()) {
 217     __ lea(rsi, counter);
 218     __ xorptr(rsi, rdx);
 219     __ xorptr(rsi, rax);
 220     __ xorptr(rsi, rdx);
 221     __ xorptr(rsi, rax);
 222     __ cmp32(rcx, Address(rsi, 0));
 223     // ca1 is the same as ca because
 224     // rax, ^ rdx ^ counter_addr ^ rax, ^ rdx = address
 225     // ca1 is data dependent on both rax, and rdx.
 226   } else {


 275   //  jni env          1
 276   //  obj              2
 277   //  jfieldID         3
 278 
 279   ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
 280 
 281   __ mov32 (rcx, counter);
 282   __ testb (rcx, 1);
 283   __ jcc (Assembler::notZero, slow);
 284   if (os::is_MP()) {
 285     __ mov(rax, rcx);
 286     __ andptr(rax, 1);                         // rax, must end up 0
 287     __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize));
 288                                               // obj, notice rax, is 0.
 289                                               // rdx is data dependent on rcx.
 290   } else {
 291     __ movptr(rdx, Address(rsp, 2*wordSize)); // obj
 292   }
 293   __ movptr(rax, Address(rsp, 3*wordSize));  // jfieldID
 294   __ movptr(rdx, Address(rdx, 0));           // *obj
 295   __ shrptr(rax, 2);                         // offset
 296 
 297   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
 298   speculative_load_pclist[count] = __ pc();
 299   switch (type) {
 300 #ifndef _LP64
 301     case T_FLOAT:  __ fld_s (Address(rdx, rax, Address::times_1)); break;
 302     case T_DOUBLE: __ fld_d (Address(rdx, rax, Address::times_1)); break;
 303 #else
 304     case T_FLOAT:  __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break;
 305     case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break;
 306 #endif // _LP64
 307     default:       ShouldNotReachHere();
 308   }
 309 
 310   Address ca1;
 311   if (os::is_MP()) {
 312     __ fst_s (Address(rsp, -4));
 313     __ lea(rdx, counter);
 314     __ movl (rax, Address(rsp, -4));
 315     // garbage hi-order bits on 64bit are harmless.




  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 "asm/macroAssembler.hpp"
  27 #include "memory/resourceArea.hpp"
  28 #include "prims/jniFastGetField.hpp"
  29 #include "prims/jvm_misc.hpp"
  30 #include "runtime/safepoint.hpp"
  31 #include "runtime/jfieldIDWorkaround.hpp"
  32 
  33 #define __ masm->
  34 
  35 #define BUFFER_SIZE 30
  36 
  37 #ifdef _WINDOWS
  38 GetBooleanField_t JNI_FastGetField::jni_fast_GetBooleanField_fp;
  39 GetByteField_t    JNI_FastGetField::jni_fast_GetByteField_fp;
  40 GetCharField_t    JNI_FastGetField::jni_fast_GetCharField_fp;
  41 GetShortField_t   JNI_FastGetField::jni_fast_GetShortField_fp;
  42 GetIntField_t     JNI_FastGetField::jni_fast_GetIntField_fp;
  43 GetLongField_t    JNI_FastGetField::jni_fast_GetLongField_fp;
  44 GetFloatField_t   JNI_FastGetField::jni_fast_GetFloatField_fp;
  45 GetDoubleField_t  JNI_FastGetField::jni_fast_GetDoubleField_fp;
  46 #endif
  47 
  48 // Instead of issuing lfence for LoadLoad barrier, we create data dependency
  49 // between loads, which is much more efficient than lfence.
  50 
  51 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {


  70   //  return pc        0
  71   //  jni env          1
  72   //  obj              2
  73   //  jfieldID         3
  74 
  75   ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
  76   __ mov32 (rcx, counter);
  77   __ testb (rcx, 1);
  78   __ jcc (Assembler::notZero, slow);
  79   if (os::is_MP()) {
  80     __ mov(rax, rcx);
  81     __ andptr(rax, 1);                         // rax, must end up 0
  82     __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize));
  83                                               // obj, notice rax, is 0.
  84                                               // rdx is data dependent on rcx.
  85   } else {
  86     __ movptr (rdx, Address(rsp, 2*wordSize));  // obj
  87   }
  88   __ movptr(rax, Address(rsp, 3*wordSize));  // jfieldID
  89   __ movptr(rdx, Address(rdx, 0));           // *obj
  90   __ shrptr (rax, jfieldIDWorkaround::offset_shift); // offset
  91 
  92   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
  93   speculative_load_pclist[count] = __ pc();
  94   switch (type) {
  95     case T_BOOLEAN: __ movzbl (rax, Address(rdx, rax, Address::times_1)); break;
  96     case T_BYTE:    __ movsbl (rax, Address(rdx, rax, Address::times_1)); break;
  97     case T_CHAR:    __ movzwl (rax, Address(rdx, rax, Address::times_1)); break;
  98     case T_SHORT:   __ movswl (rax, Address(rdx, rax, Address::times_1)); break;
  99     case T_INT:     __ movl   (rax, Address(rdx, rax, Address::times_1)); break;
 100     default:        ShouldNotReachHere();
 101   }
 102 
 103   Address ca1;
 104   if (os::is_MP()) {
 105     __ lea(rdx, counter);
 106     __ xorptr(rdx, rax);
 107     __ xorptr(rdx, rax);
 108     __ cmp32(rcx, Address(rdx, 0));
 109     // ca1 is the same as ca because
 110     // rax, ^ counter_addr ^ rax, = address


 187   //  obj              3
 188   //  jfieldID         4
 189 
 190   ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
 191 
 192   __ push  (rsi);
 193   __ mov32 (rcx, counter);
 194   __ testb (rcx, 1);
 195   __ jcc (Assembler::notZero, slow);
 196   if (os::is_MP()) {
 197     __ mov(rax, rcx);
 198     __ andptr(rax, 1);                         // rax, must end up 0
 199     __ movptr(rdx, Address(rsp, rax, Address::times_1, 3*wordSize));
 200                                               // obj, notice rax, is 0.
 201                                               // rdx is data dependent on rcx.
 202   } else {
 203     __ movptr(rdx, Address(rsp, 3*wordSize));  // obj
 204   }
 205   __ movptr(rsi, Address(rsp, 4*wordSize));  // jfieldID
 206   __ movptr(rdx, Address(rdx, 0));           // *obj
 207   __ shrptr(rsi, jfieldIDWorkaround::offset_shift); // offset
 208 
 209   assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small");
 210   speculative_load_pclist[count++] = __ pc();
 211   __ movptr(rax, Address(rdx, rsi, Address::times_1));
 212 #ifndef _LP64
 213   speculative_load_pclist[count] = __ pc();
 214   __ movl(rdx, Address(rdx, rsi, Address::times_1, 4));
 215 #endif // _LP64
 216 
 217   if (os::is_MP()) {
 218     __ lea(rsi, counter);
 219     __ xorptr(rsi, rdx);
 220     __ xorptr(rsi, rax);
 221     __ xorptr(rsi, rdx);
 222     __ xorptr(rsi, rax);
 223     __ cmp32(rcx, Address(rsi, 0));
 224     // ca1 is the same as ca because
 225     // rax, ^ rdx ^ counter_addr ^ rax, ^ rdx = address
 226     // ca1 is data dependent on both rax, and rdx.
 227   } else {


 276   //  jni env          1
 277   //  obj              2
 278   //  jfieldID         3
 279 
 280   ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
 281 
 282   __ mov32 (rcx, counter);
 283   __ testb (rcx, 1);
 284   __ jcc (Assembler::notZero, slow);
 285   if (os::is_MP()) {
 286     __ mov(rax, rcx);
 287     __ andptr(rax, 1);                         // rax, must end up 0
 288     __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize));
 289                                               // obj, notice rax, is 0.
 290                                               // rdx is data dependent on rcx.
 291   } else {
 292     __ movptr(rdx, Address(rsp, 2*wordSize)); // obj
 293   }
 294   __ movptr(rax, Address(rsp, 3*wordSize));  // jfieldID
 295   __ movptr(rdx, Address(rdx, 0));           // *obj
 296   __ shrptr(rax, jfieldIDWorkaround::offset_shift); // offset
 297 
 298   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
 299   speculative_load_pclist[count] = __ pc();
 300   switch (type) {
 301 #ifndef _LP64
 302     case T_FLOAT:  __ fld_s (Address(rdx, rax, Address::times_1)); break;
 303     case T_DOUBLE: __ fld_d (Address(rdx, rax, Address::times_1)); break;
 304 #else
 305     case T_FLOAT:  __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break;
 306     case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break;
 307 #endif // _LP64
 308     default:       ShouldNotReachHere();
 309   }
 310 
 311   Address ca1;
 312   if (os::is_MP()) {
 313     __ fst_s (Address(rsp, -4));
 314     __ lea(rdx, counter);
 315     __ movl (rax, Address(rsp, -4));
 316     // garbage hi-order bits on 64bit are harmless.


< prev index next >