< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page
8248238: Adding Windows support to OpenJDK on AArch64

Summary: Adding Windows support for AArch64

Contributed-by: Ludovic Henry <luhenry@microsoft.com>, Monica Beckwith <monica.beckwith@microsoft.com>
Reviewed-by:


  76 #include "runtime/reflection.hpp"
  77 #include "runtime/safepointVerifiers.hpp"
  78 #include "runtime/sharedRuntime.hpp"
  79 #include "runtime/signature.hpp"
  80 #include "runtime/thread.inline.hpp"
  81 #include "runtime/vmOperations.hpp"
  82 #include "services/memTracker.hpp"
  83 #include "services/runtimeService.hpp"
  84 #include "utilities/defaultStream.hpp"
  85 #include "utilities/dtrace.hpp"
  86 #include "utilities/events.hpp"
  87 #include "utilities/histogram.hpp"
  88 #include "utilities/macros.hpp"
  89 #include "utilities/vmError.hpp"
  90 #if INCLUDE_JVMCI
  91 #include "jvmci/jvmciCompiler.hpp"
  92 #endif
  93 
  94 static jint CurrentVersion = JNI_VERSION_10;
  95 
  96 #ifdef _WIN32
  97 extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
  98 #endif
  99 
 100 // The DT_RETURN_MARK macros create a scoped object to fire the dtrace
 101 // '-return' probe regardless of the return path is taken out of the function.
 102 // Methods that have multiple return paths use this to avoid having to
 103 // instrument each return path.  Methods that use CHECK or THROW must use this
 104 // since those macros can cause an immedate uninstrumented return.
 105 //
 106 // In order to get the return value, a reference to the variable containing
 107 // the return value must be passed to the contructor of the object, and
 108 // the return value must be set before return (since the mark object has
 109 // a reference to it).
 110 //
 111 // Example:
 112 // DT_RETURN_MARK_DECL(SomeFunc, int);
 113 // JNI_ENTRY(int, SomeFunc, ...)
 114 //   int return_value = 0;
 115 //   DT_RETURN_MARK(SomeFunc, int, (const int&)return_value);
 116 //   foo(CHECK_0)


3814 
3815     // Creation failed. We must reset vm_created
3816     *vm = 0;
3817     *(JNIEnv**)penv = 0;
3818     // reset vm_created last to avoid race condition. Use OrderAccess to
3819     // control both compiler and architectural-based reordering.
3820     Atomic::release_store(&vm_created, 0);
3821   }
3822 
3823   // Flush stdout and stderr before exit.
3824   fflush(stdout);
3825   fflush(stderr);
3826 
3827   return result;
3828 
3829 }
3830 
3831 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
3832   jint result = JNI_ERR;
3833   // On Windows, let CreateJavaVM run with SEH protection
3834 #ifdef _WIN32
3835   __try {
3836 #endif
3837     result = JNI_CreateJavaVM_inner(vm, penv, args);
3838 #ifdef _WIN32
3839   } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
3840     // Nothing to do.
3841   }
3842 #endif
3843   return result;
3844 }
3845 
3846 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {
3847   // See bug 4367188, the wrapper can sometimes cause VM crashes
3848   // JNIWrapper("GetCreatedJavaVMs");
3849 
3850   HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY((void **) vm_buf, bufLen, (uintptr_t *) numVMs);
3851 
3852   if (vm_created == 1) {
3853     if (numVMs != NULL) *numVMs = 1;
3854     if (bufLen > 0)     *vm_buf = (JavaVM *)(&main_vm);
3855   } else {
3856     if (numVMs != NULL) *numVMs = 0;
3857   }
3858   HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN(JNI_OK);


3886   }
3887 
3888   // Since this is not a JVM_ENTRY we have to set the thread state manually before entering.
3889   JavaThread* thread = JavaThread::current();
3890   ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
3891   if (Threads::destroy_vm()) {
3892     // Should not change thread state, VM is gone
3893     vm_created = 0;
3894     res = JNI_OK;
3895     return res;
3896   } else {
3897     ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_native);
3898     res = JNI_ERR;
3899     return res;
3900   }
3901 }
3902 
3903 jint JNICALL jni_DestroyJavaVM(JavaVM *vm) {
3904   jint result = JNI_ERR;
3905   // On Windows, we need SEH protection
3906 #ifdef _WIN32
3907   __try {
3908 #endif
3909     result = jni_DestroyJavaVM_inner(vm);
3910 #ifdef _WIN32
3911   } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
3912     // Nothing to do.
3913   }
3914 #endif
3915   return result;
3916 }
3917 
3918 static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool daemon) {
3919   JavaVMAttachArgs *args = (JavaVMAttachArgs *) _args;
3920 
3921   // Check below commented out from JDK1.2fcs as well
3922   /*
3923   if (args && (args->version != JNI_VERSION_1_1 || args->version != JNI_VERSION_1_2)) {
3924     return JNI_EVERSION;
3925   }
3926   */
3927 
3928   Thread* t = Thread::current_or_null();
3929   if (t != NULL) {
3930     // If executing from an atexit hook we may be in the VMThread.




  76 #include "runtime/reflection.hpp"
  77 #include "runtime/safepointVerifiers.hpp"
  78 #include "runtime/sharedRuntime.hpp"
  79 #include "runtime/signature.hpp"
  80 #include "runtime/thread.inline.hpp"
  81 #include "runtime/vmOperations.hpp"
  82 #include "services/memTracker.hpp"
  83 #include "services/runtimeService.hpp"
  84 #include "utilities/defaultStream.hpp"
  85 #include "utilities/dtrace.hpp"
  86 #include "utilities/events.hpp"
  87 #include "utilities/histogram.hpp"
  88 #include "utilities/macros.hpp"
  89 #include "utilities/vmError.hpp"
  90 #if INCLUDE_JVMCI
  91 #include "jvmci/jvmciCompiler.hpp"
  92 #endif
  93 
  94 static jint CurrentVersion = JNI_VERSION_10;
  95 
  96 #if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
  97 extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
  98 #endif
  99 
 100 // The DT_RETURN_MARK macros create a scoped object to fire the dtrace
 101 // '-return' probe regardless of the return path is taken out of the function.
 102 // Methods that have multiple return paths use this to avoid having to
 103 // instrument each return path.  Methods that use CHECK or THROW must use this
 104 // since those macros can cause an immedate uninstrumented return.
 105 //
 106 // In order to get the return value, a reference to the variable containing
 107 // the return value must be passed to the contructor of the object, and
 108 // the return value must be set before return (since the mark object has
 109 // a reference to it).
 110 //
 111 // Example:
 112 // DT_RETURN_MARK_DECL(SomeFunc, int);
 113 // JNI_ENTRY(int, SomeFunc, ...)
 114 //   int return_value = 0;
 115 //   DT_RETURN_MARK(SomeFunc, int, (const int&)return_value);
 116 //   foo(CHECK_0)


3814 
3815     // Creation failed. We must reset vm_created
3816     *vm = 0;
3817     *(JNIEnv**)penv = 0;
3818     // reset vm_created last to avoid race condition. Use OrderAccess to
3819     // control both compiler and architectural-based reordering.
3820     Atomic::release_store(&vm_created, 0);
3821   }
3822 
3823   // Flush stdout and stderr before exit.
3824   fflush(stdout);
3825   fflush(stderr);
3826 
3827   return result;
3828 
3829 }
3830 
3831 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
3832   jint result = JNI_ERR;
3833   // On Windows, let CreateJavaVM run with SEH protection
3834 #if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
3835   __try {
3836 #endif
3837     result = JNI_CreateJavaVM_inner(vm, penv, args);
3838 #if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
3839   } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
3840     // Nothing to do.
3841   }
3842 #endif
3843   return result;
3844 }
3845 
3846 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {
3847   // See bug 4367188, the wrapper can sometimes cause VM crashes
3848   // JNIWrapper("GetCreatedJavaVMs");
3849 
3850   HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY((void **) vm_buf, bufLen, (uintptr_t *) numVMs);
3851 
3852   if (vm_created == 1) {
3853     if (numVMs != NULL) *numVMs = 1;
3854     if (bufLen > 0)     *vm_buf = (JavaVM *)(&main_vm);
3855   } else {
3856     if (numVMs != NULL) *numVMs = 0;
3857   }
3858   HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN(JNI_OK);


3886   }
3887 
3888   // Since this is not a JVM_ENTRY we have to set the thread state manually before entering.
3889   JavaThread* thread = JavaThread::current();
3890   ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
3891   if (Threads::destroy_vm()) {
3892     // Should not change thread state, VM is gone
3893     vm_created = 0;
3894     res = JNI_OK;
3895     return res;
3896   } else {
3897     ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_native);
3898     res = JNI_ERR;
3899     return res;
3900   }
3901 }
3902 
3903 jint JNICALL jni_DestroyJavaVM(JavaVM *vm) {
3904   jint result = JNI_ERR;
3905   // On Windows, we need SEH protection
3906 #if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
3907   __try {
3908 #endif
3909     result = jni_DestroyJavaVM_inner(vm);
3910 #if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
3911   } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
3912     // Nothing to do.
3913   }
3914 #endif
3915   return result;
3916 }
3917 
3918 static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool daemon) {
3919   JavaVMAttachArgs *args = (JavaVMAttachArgs *) _args;
3920 
3921   // Check below commented out from JDK1.2fcs as well
3922   /*
3923   if (args && (args->version != JNI_VERSION_1_1 || args->version != JNI_VERSION_1_2)) {
3924     return JNI_EVERSION;
3925   }
3926   */
3927 
3928   Thread* t = Thread::current_or_null();
3929   if (t != NULL) {
3930     // If executing from an atexit hook we may be in the VMThread.


< prev index next >