< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page
rev 60632 : 8248670: Windows: Exception handling support on AArch64
Reviewed-by:
Contributed-by: mbeckwit, luhenry, burban


  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)


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


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


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


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


< prev index next >