< prev index next >

src/hotspot/share/prims/unsafe.cpp

Print this page




  25 #include "precompiled.hpp"
  26 #include "jni.h"
  27 #include "jvm.h"
  28 #include "classfile/classFileStream.hpp"
  29 #include "classfile/vmSymbols.hpp"
  30 #include "jfr/jfrEvents.hpp"
  31 #include "memory/allocation.inline.hpp"
  32 #include "memory/resourceArea.hpp"
  33 #include "oops/access.inline.hpp"
  34 #include "oops/fieldStreams.hpp"
  35 #include "oops/objArrayOop.inline.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "oops/typeArrayOop.inline.hpp"
  38 #include "prims/unsafe.hpp"
  39 #include "runtime/atomic.hpp"
  40 #include "runtime/globals.hpp"
  41 #include "runtime/interfaceSupport.inline.hpp"
  42 #include "runtime/jniHandles.inline.hpp"
  43 #include "runtime/orderAccess.hpp"
  44 #include "runtime/reflection.hpp"

  45 #include "runtime/thread.hpp"
  46 #include "runtime/threadSMR.hpp"
  47 #include "runtime/vm_version.hpp"
  48 #include "services/threadService.hpp"
  49 #include "utilities/align.hpp"
  50 #include "utilities/copy.hpp"
  51 #include "utilities/dtrace.hpp"
  52 #include "utilities/macros.hpp"
  53 
  54 /**
  55  * Implementation of the jdk.internal.misc.Unsafe class
  56  */
  57 
  58 
  59 #define MAX_OBJECT_SIZE \
  60   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
  61     + ((julong)max_jint * sizeof(double)) )
  62 
  63 
  64 #define UNSAFE_ENTRY(result_type, header) \


 425     // Both src & dst are in native memory
 426     address src = (address)srcOffset;
 427     address dst = (address)dstOffset;
 428 
 429     Copy::conjoint_swap(src, dst, sz, esz);
 430   } else {
 431     // At least one of src/dst are on heap, transition to VM to access raw pointers
 432 
 433     JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
 434       oop srcp = JNIHandles::resolve(srcObj);
 435       oop dstp = JNIHandles::resolve(dstObj);
 436 
 437       address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
 438       address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
 439 
 440       Copy::conjoint_swap(src, dst, sz, esz);
 441     } JVM_END
 442   }
 443 } UNSAFE_END
 444 




































































 445 ////// Random queries
 446 
 447 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) {
 448   return sizeof(void*);
 449 } UNSAFE_END
 450 
 451 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
 452   return os::vm_page_size();
 453 } UNSAFE_END
 454 
 455 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) {
 456   assert(clazz != NULL, "clazz must not be NULL");
 457   assert(name != NULL, "name must not be NULL");
 458 
 459   ResourceMark rm(THREAD);
 460   char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
 461 
 462   InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
 463 
 464   jint offset = -1;


1044     DECLARE_GETPUTOOP(Boolean, Z),
1045     DECLARE_GETPUTOOP(Byte, B),
1046     DECLARE_GETPUTOOP(Short, S),
1047     DECLARE_GETPUTOOP(Char, C),
1048     DECLARE_GETPUTOOP(Int, I),
1049     DECLARE_GETPUTOOP(Long, J),
1050     DECLARE_GETPUTOOP(Float, F),
1051     DECLARE_GETPUTOOP(Double, D),
1052 
1053     {CC "allocateMemory0",    CC "(J)" ADR,              FN_PTR(Unsafe_AllocateMemory0)},
1054     {CC "reallocateMemory0",  CC "(" ADR "J)" ADR,       FN_PTR(Unsafe_ReallocateMemory0)},
1055     {CC "freeMemory0",        CC "(" ADR ")V",           FN_PTR(Unsafe_FreeMemory0)},
1056 
1057     {CC "objectFieldOffset0", CC "(" FLD ")J",           FN_PTR(Unsafe_ObjectFieldOffset0)},
1058     {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
1059     {CC "staticFieldOffset0", CC "(" FLD ")J",           FN_PTR(Unsafe_StaticFieldOffset0)},
1060     {CC "staticFieldBase0",   CC "(" FLD ")" OBJ,        FN_PTR(Unsafe_StaticFieldBase0)},
1061     {CC "ensureClassInitialized0", CC "(" CLS ")V",      FN_PTR(Unsafe_EnsureClassInitialized0)},
1062     {CC "arrayBaseOffset0",   CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayBaseOffset0)},
1063     {CC "arrayIndexScale0",   CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayIndexScale0)},

1064     {CC "addressSize0",       CC "()I",                  FN_PTR(Unsafe_AddressSize0)},
1065     {CC "pageSize",           CC "()I",                  FN_PTR(Unsafe_PageSize)},
1066 
1067     {CC "defineClass0",       CC "(" DC_Args ")" CLS,    FN_PTR(Unsafe_DefineClass0)},
1068     {CC "allocateInstance",   CC "(" CLS ")" OBJ,        FN_PTR(Unsafe_AllocateInstance)},
1069     {CC "throwException",     CC "(" THR ")V",           FN_PTR(Unsafe_ThrowException)},
1070     {CC "compareAndSetObject",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetObject)},
1071     {CC "compareAndSetInt",   CC "(" OBJ "J""I""I"")Z",  FN_PTR(Unsafe_CompareAndSetInt)},
1072     {CC "compareAndSetLong",  CC "(" OBJ "J""J""J"")Z",  FN_PTR(Unsafe_CompareAndSetLong)},
1073     {CC "compareAndExchangeObject", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeObject)},
1074     {CC "compareAndExchangeInt",  CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)},
1075     {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)},
1076 
1077     {CC "park",               CC "(ZJ)V",                FN_PTR(Unsafe_Park)},
1078     {CC "unpark",             CC "(" OBJ ")V",           FN_PTR(Unsafe_Unpark)},
1079 
1080     {CC "getLoadAverage0",    CC "([DI)I",               FN_PTR(Unsafe_GetLoadAverage0)},
1081 
1082     {CC "copyMemory0",        CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory0)},
1083     {CC "copySwapMemory0",    CC "(" OBJ "J" OBJ "JJJ)V", FN_PTR(Unsafe_CopySwapMemory0)},



1084     {CC "setMemory0",         CC "(" OBJ "JJB)V",        FN_PTR(Unsafe_SetMemory0)},
1085 
1086     {CC "defineAnonymousClass0", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass0)},
1087 
1088     {CC "shouldBeInitialized0", CC "(" CLS ")Z",         FN_PTR(Unsafe_ShouldBeInitialized0)},
1089 
1090     {CC "loadFence",          CC "()V",                  FN_PTR(Unsafe_LoadFence)},
1091     {CC "storeFence",         CC "()V",                  FN_PTR(Unsafe_StoreFence)},
1092     {CC "fullFence",          CC "()V",                  FN_PTR(Unsafe_FullFence)},
1093 
1094     {CC "isBigEndian0",       CC "()Z",                  FN_PTR(Unsafe_isBigEndian0)},
1095     {CC "unalignedAccess0",   CC "()Z",                  FN_PTR(Unsafe_unalignedAccess0)}
1096 };
1097 
1098 #undef CC
1099 #undef FN_PTR
1100 
1101 #undef ADR
1102 #undef LANG
1103 #undef OBJ


  25 #include "precompiled.hpp"
  26 #include "jni.h"
  27 #include "jvm.h"
  28 #include "classfile/classFileStream.hpp"
  29 #include "classfile/vmSymbols.hpp"
  30 #include "jfr/jfrEvents.hpp"
  31 #include "memory/allocation.inline.hpp"
  32 #include "memory/resourceArea.hpp"
  33 #include "oops/access.inline.hpp"
  34 #include "oops/fieldStreams.hpp"
  35 #include "oops/objArrayOop.inline.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "oops/typeArrayOop.inline.hpp"
  38 #include "prims/unsafe.hpp"
  39 #include "runtime/atomic.hpp"
  40 #include "runtime/globals.hpp"
  41 #include "runtime/interfaceSupport.inline.hpp"
  42 #include "runtime/jniHandles.inline.hpp"
  43 #include "runtime/orderAccess.hpp"
  44 #include "runtime/reflection.hpp"
  45 #include "runtime/sharedRuntime.hpp"
  46 #include "runtime/thread.hpp"
  47 #include "runtime/threadSMR.hpp"
  48 #include "runtime/vm_version.hpp"
  49 #include "services/threadService.hpp"
  50 #include "utilities/align.hpp"
  51 #include "utilities/copy.hpp"
  52 #include "utilities/dtrace.hpp"
  53 #include "utilities/macros.hpp"
  54 
  55 /**
  56  * Implementation of the jdk.internal.misc.Unsafe class
  57  */
  58 
  59 
  60 #define MAX_OBJECT_SIZE \
  61   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
  62     + ((julong)max_jint * sizeof(double)) )
  63 
  64 
  65 #define UNSAFE_ENTRY(result_type, header) \


 426     // Both src & dst are in native memory
 427     address src = (address)srcOffset;
 428     address dst = (address)dstOffset;
 429 
 430     Copy::conjoint_swap(src, dst, sz, esz);
 431   } else {
 432     // At least one of src/dst are on heap, transition to VM to access raw pointers
 433 
 434     JVM_ENTRY_FROM_LEAF(env, void, Unsafe_CopySwapMemory0) {
 435       oop srcp = JNIHandles::resolve(srcObj);
 436       oop dstp = JNIHandles::resolve(dstObj);
 437 
 438       address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
 439       address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
 440 
 441       Copy::conjoint_swap(src, dst, sz, esz);
 442     } JVM_END
 443   }
 444 } UNSAFE_END
 445 
 446 UNSAFE_LEAF (void, Unsafe_WriteBack0(JNIEnv *env, jobject unsafe, jlong line)) {
 447 #ifndef PRODUCT
 448   if (TraceMemoryWriteback) {
 449     tty->print_cr("Unsafe: writeback 0x%p", addr_from_java(line));
 450   }
 451 #endif
 452 
 453   // guard against currently unimplemented cases
 454 #if !defined(LINUX) || !(defined(AARCH64) || defined(AMD64))
 455   // TODO - implement for solaris/AIX/BSD/WINDOWS and for 32 bit
 456   JNU_ThrowRuntimeException(env, "writeback is not implemented");
 457   return IOS_THROWN;
 458 #else
 459   void (*wb)(void *);
 460   void *a = addr_from_java(line);
 461   wb = (void (*)(void *)) StubRoutines::data_cache_writeback();
 462   assert(wb != NULL, "generate writeback stub!");
 463   (*wb)(a);
 464 #endif
 465 } UNSAFE_END
 466 
 467 static void doWriteBackSync0(bool isPre)
 468 {
 469   void (*wbsync)(int);
 470   wbsync = (void (*)(int)) StubRoutines::data_cache_writeback_sync();
 471   assert(wbsync != NULL, "generate writeback sync stub!");
 472   (*wbsync)(isPre);
 473 }
 474 
 475 UNSAFE_LEAF (void, Unsafe_WriteBackPreSync0(JNIEnv *env, jobject unsafe)) {
 476 #ifndef PRODUCT
 477   if (TraceMemoryWriteback) {
 478       tty->print_cr("Unsafe: writeback pre-sync");
 479   }
 480 #endif
 481 #if !defined(LINUX) || !(defined(AARCH64) || defined(AMD64))
 482   // TODO - implement for solaris/AIX/BSD/WINDOWS and for 32 bit
 483   JNU_ThrowRuntimeException(env, "writeback sync is not implemented");
 484   return IOS_THROWN;
 485 #else
 486   doWriteBackSync0(true);
 487 #endif
 488 } UNSAFE_END
 489 
 490 UNSAFE_LEAF (void, Unsafe_WriteBackPostSync0(JNIEnv *env, jobject unsafe)) {
 491 #ifndef PRODUCT
 492   if (TraceMemoryWriteback) {
 493     tty->print_cr("Unsafe: writeback pre-sync");
 494   }
 495 #endif
 496 #if !defined(LINUX) || !(defined(AARCH64) || defined(AMD64))
 497   // TODO - implement for solaris/AIX/BSD/WINDOWS and for 32 bit
 498   JNU_ThrowRuntimeException(env, "writeback sync is not implemented");
 499   return IOS_THROWN;
 500 #else
 501   doWriteBackSync0(false);
 502 #endif
 503 } UNSAFE_END
 504 
 505 UNSAFE_LEAF(jint, Unsafe_DataCacheLineFlushSize0()) {
 506   jint size = (jint)VM_Version::data_cache_line_flush_size();
 507   // TODO -- ensure every CPU actually sets this
 508   if (size == 0) {
 509     size = (jint)DEFAULT_CACHE_LINE_SIZE;
 510   }
 511   return size;
 512 } UNSAFE_END
 513 
 514 ////// Random queries
 515 
 516 UNSAFE_LEAF(jint, Unsafe_AddressSize0(JNIEnv *env, jobject unsafe)) {
 517   return sizeof(void*);
 518 } UNSAFE_END
 519 
 520 UNSAFE_LEAF(jint, Unsafe_PageSize()) {
 521   return os::vm_page_size();
 522 } UNSAFE_END
 523 
 524 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) {
 525   assert(clazz != NULL, "clazz must not be NULL");
 526   assert(name != NULL, "name must not be NULL");
 527 
 528   ResourceMark rm(THREAD);
 529   char *utf_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
 530 
 531   InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
 532 
 533   jint offset = -1;


1113     DECLARE_GETPUTOOP(Boolean, Z),
1114     DECLARE_GETPUTOOP(Byte, B),
1115     DECLARE_GETPUTOOP(Short, S),
1116     DECLARE_GETPUTOOP(Char, C),
1117     DECLARE_GETPUTOOP(Int, I),
1118     DECLARE_GETPUTOOP(Long, J),
1119     DECLARE_GETPUTOOP(Float, F),
1120     DECLARE_GETPUTOOP(Double, D),
1121 
1122     {CC "allocateMemory0",    CC "(J)" ADR,              FN_PTR(Unsafe_AllocateMemory0)},
1123     {CC "reallocateMemory0",  CC "(" ADR "J)" ADR,       FN_PTR(Unsafe_ReallocateMemory0)},
1124     {CC "freeMemory0",        CC "(" ADR ")V",           FN_PTR(Unsafe_FreeMemory0)},
1125 
1126     {CC "objectFieldOffset0", CC "(" FLD ")J",           FN_PTR(Unsafe_ObjectFieldOffset0)},
1127     {CC "objectFieldOffset1", CC "(" CLS LANG "String;)J", FN_PTR(Unsafe_ObjectFieldOffset1)},
1128     {CC "staticFieldOffset0", CC "(" FLD ")J",           FN_PTR(Unsafe_StaticFieldOffset0)},
1129     {CC "staticFieldBase0",   CC "(" FLD ")" OBJ,        FN_PTR(Unsafe_StaticFieldBase0)},
1130     {CC "ensureClassInitialized0", CC "(" CLS ")V",      FN_PTR(Unsafe_EnsureClassInitialized0)},
1131     {CC "arrayBaseOffset0",   CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayBaseOffset0)},
1132     {CC "arrayIndexScale0",   CC "(" CLS ")I",           FN_PTR(Unsafe_ArrayIndexScale0)},
1133     {CC "dataCacheLineFlushSize0", CC "()I",             FN_PTR(Unsafe_DataCacheLineFlushSize0)},
1134     {CC "addressSize0",       CC "()I",                  FN_PTR(Unsafe_AddressSize0)},
1135     {CC "pageSize",           CC "()I",                  FN_PTR(Unsafe_PageSize)},
1136 
1137     {CC "defineClass0",       CC "(" DC_Args ")" CLS,    FN_PTR(Unsafe_DefineClass0)},
1138     {CC "allocateInstance",   CC "(" CLS ")" OBJ,        FN_PTR(Unsafe_AllocateInstance)},
1139     {CC "throwException",     CC "(" THR ")V",           FN_PTR(Unsafe_ThrowException)},
1140     {CC "compareAndSetObject",CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSetObject)},
1141     {CC "compareAndSetInt",   CC "(" OBJ "J""I""I"")Z",  FN_PTR(Unsafe_CompareAndSetInt)},
1142     {CC "compareAndSetLong",  CC "(" OBJ "J""J""J"")Z",  FN_PTR(Unsafe_CompareAndSetLong)},
1143     {CC "compareAndExchangeObject", CC "(" OBJ "J" OBJ "" OBJ ")" OBJ, FN_PTR(Unsafe_CompareAndExchangeObject)},
1144     {CC "compareAndExchangeInt",  CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)},
1145     {CC "compareAndExchangeLong", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)},
1146 
1147     {CC "park",               CC "(ZJ)V",                FN_PTR(Unsafe_Park)},
1148     {CC "unpark",             CC "(" OBJ ")V",           FN_PTR(Unsafe_Unpark)},
1149 
1150     {CC "getLoadAverage0",    CC "([DI)I",               FN_PTR(Unsafe_GetLoadAverage0)},
1151 
1152     {CC "copyMemory0",        CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory0)},
1153     {CC "copySwapMemory0",    CC "(" OBJ "J" OBJ "JJJ)V", FN_PTR(Unsafe_CopySwapMemory0)},
1154     {CC "writeback0",         CC "(" "J" ")V",           FN_PTR(Unsafe_WriteBack0)},
1155     {CC "writebackPreSync0",     CC "()V",               FN_PTR(Unsafe_WriteBackPreSync0)},
1156     {CC "writebackPostSync0",     CC "()V",              FN_PTR(Unsafe_WriteBackPostSync0)},
1157     {CC "setMemory0",         CC "(" OBJ "JJB)V",        FN_PTR(Unsafe_SetMemory0)},
1158 
1159     {CC "defineAnonymousClass0", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass0)},
1160 
1161     {CC "shouldBeInitialized0", CC "(" CLS ")Z",         FN_PTR(Unsafe_ShouldBeInitialized0)},
1162 
1163     {CC "loadFence",          CC "()V",                  FN_PTR(Unsafe_LoadFence)},
1164     {CC "storeFence",         CC "()V",                  FN_PTR(Unsafe_StoreFence)},
1165     {CC "fullFence",          CC "()V",                  FN_PTR(Unsafe_FullFence)},
1166 
1167     {CC "isBigEndian0",       CC "()Z",                  FN_PTR(Unsafe_isBigEndian0)},
1168     {CC "unalignedAccess0",   CC "()Z",                  FN_PTR(Unsafe_unalignedAccess0)}
1169 };
1170 
1171 #undef CC
1172 #undef FN_PTR
1173 
1174 #undef ADR
1175 #undef LANG
1176 #undef OBJ
< prev index next >