< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page




   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "jni.h"

  28 #include "ci/ciReplay.hpp"
  29 #include "classfile/altHashing.hpp"
  30 #include "classfile/classFileStream.hpp"
  31 #include "classfile/classLoader.hpp"
  32 #include "classfile/javaClasses.hpp"
  33 #include "classfile/javaClasses.inline.hpp"
  34 #include "classfile/modules.hpp"
  35 #include "classfile/symbolTable.hpp"
  36 #include "classfile/systemDictionary.hpp"
  37 #include "classfile/vmSymbols.hpp"
  38 #include "gc/shared/gcLocker.inline.hpp"
  39 #include "interpreter/linkResolver.hpp"
  40 #include "memory/allocation.hpp"
  41 #include "memory/allocation.inline.hpp"
  42 #include "memory/oopFactory.hpp"
  43 #include "memory/resourceArea.hpp"
  44 #include "memory/universe.inline.hpp"
  45 #include "oops/instanceKlass.hpp"
  46 #include "oops/instanceOop.hpp"
  47 #include "oops/markOop.hpp"
  48 #include "oops/method.hpp"
  49 #include "oops/objArrayKlass.hpp"
  50 #include "oops/objArrayOop.inline.hpp"
  51 #include "oops/oop.inline.hpp"
  52 #include "oops/symbol.hpp"
  53 #include "oops/typeArrayKlass.hpp"
  54 #include "oops/typeArrayOop.hpp"
  55 #include "prims/jniCheck.hpp"
  56 #include "prims/jniExport.hpp"
  57 #include "prims/jniFastGetField.hpp"
  58 #include "prims/jvm.h"
  59 #include "prims/jvm_misc.hpp"
  60 #include "prims/jvmtiExport.hpp"
  61 #include "prims/jvmtiThreadState.hpp"
  62 #include "runtime/atomic.hpp"
  63 #include "runtime/compilationPolicy.hpp"
  64 #include "runtime/fieldDescriptor.hpp"
  65 #include "runtime/handles.inline.hpp"
  66 #include "runtime/interfaceSupport.hpp"
  67 #include "runtime/java.hpp"
  68 #include "runtime/javaCalls.hpp"
  69 #include "runtime/jfieldIDWorkaround.hpp"
  70 #include "runtime/orderAccess.inline.hpp"
  71 #include "runtime/reflection.hpp"
  72 #include "runtime/sharedRuntime.hpp"
  73 #include "runtime/signature.hpp"
  74 #include "runtime/thread.inline.hpp"
  75 #include "runtime/vm_operations.hpp"
  76 #include "services/memTracker.hpp"
  77 #include "services/runtimeService.hpp"
  78 #include "trace/traceMacros.hpp"


 246     "Bug in native code: jfieldID class must match object");
 247     } else {
 248 #if 0
 249       #ifndef PRODUCT
 250       if (Verbose) {
 251   ResourceMark rm;
 252   warning("VerifyJNIFields: unverified offset %d for %s", offset, k->external_name());
 253       }
 254       #endif
 255 #endif
 256     }
 257   }
 258   guarantee(InstanceKlass::cast(k)->contains_field_offset(offset),
 259       "Bug in native code: jfieldID offset must address interior of object");
 260 }
 261 
 262 // Wrapper to trace JNI functions
 263 
 264 #ifdef ASSERT
 265   Histogram* JNIHistogram;
 266   static volatile jint JNIHistogram_lock = 0;
 267 
 268   class JNIHistogramElement : public HistogramElement {
 269     public:
 270      JNIHistogramElement(const char* name);
 271   };
 272 
 273   JNIHistogramElement::JNIHistogramElement(const char* elementName) {
 274     _name = elementName;
 275     uintx count = 0;
 276 
 277     while (Atomic::cmpxchg(1, &JNIHistogram_lock, 0) != 0) {
 278       while (OrderAccess::load_acquire(&JNIHistogram_lock) != 0) {
 279         count +=1;
 280         if ( (WarnOnStalledSpinLock > 0)
 281           && (count % WarnOnStalledSpinLock == 0)) {
 282           warning("JNIHistogram_lock seems to be stalled");
 283         }
 284       }
 285      }
 286 


3260 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
3261   JNIWrapper("jni_DeleteWeakGlobalRef");
3262   HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(env, ref);
3263   JNIHandles::destroy_weak_global(ref);
3264   HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN();
3265 JNI_END
3266 
3267 
3268 JNI_QUICK_ENTRY(jboolean, jni_ExceptionCheck(JNIEnv *env))
3269   JNIWrapper("jni_ExceptionCheck");
3270  HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(env);
3271   jni_check_async_exceptions(thread);
3272   jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;
3273  HOTSPOT_JNI_EXCEPTIONCHECK_RETURN(ret);
3274   return ret;
3275 JNI_END
3276 
3277 
3278 // Initialization state for three routines below relating to
3279 // java.nio.DirectBuffers
3280 static          jint directBufferSupportInitializeStarted = 0;
3281 static volatile jint directBufferSupportInitializeEnded   = 0;
3282 static volatile jint directBufferSupportInitializeFailed  = 0;
3283 static jclass    bufferClass                 = NULL;
3284 static jclass    directBufferClass           = NULL;
3285 static jclass    directByteBufferClass       = NULL;
3286 static jmethodID directByteBufferConstructor = NULL;
3287 static jfieldID  directBufferAddressField    = NULL;
3288 static jfieldID  bufferCapacityField         = NULL;
3289 
3290 static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) {
3291   Handle loader;            // null (bootstrap) loader
3292   Handle protection_domain; // null protection domain
3293 
3294   TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);
3295   jclass result =  find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);
3296 
3297   if (log_is_enabled(Debug, class, resolve) && result != NULL) {
3298     trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
3299   }
3300   return result;
3301 }
3302 


3827 struct JNINativeInterface_* jni_functions() {
3828 #if INCLUDE_JNI_CHECK
3829   if (CheckJNICalls) return jni_functions_check();
3830 #endif // INCLUDE_JNI_CHECK
3831   return &jni_NativeInterface;
3832 }
3833 
3834 // Returns the function structure
3835 struct JNINativeInterface_* jni_functions_nocheck() {
3836   return &jni_NativeInterface;
3837 }
3838 
3839 
3840 // Invocation API
3841 
3842 
3843 // Forward declaration
3844 extern const struct JNIInvokeInterface_ jni_InvokeInterface;
3845 
3846 // Global invocation API vars
3847 volatile jint vm_created = 0;
3848 // Indicate whether it is safe to recreate VM
3849 volatile jint safe_to_recreate_vm = 1;
3850 struct JavaVM_ main_vm = {&jni_InvokeInterface};
3851 
3852 
3853 #define JAVASTACKSIZE (400 * 1024)    /* Default size of a thread java stack */
3854 enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL };
3855 
3856 DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint
3857                     , HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN(_ret_ref));
3858 
3859 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
3860   HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY(args_);
3861   JDK1_1InitArgs *args = (JDK1_1InitArgs *)args_;
3862   jint ret = JNI_ERR;
3863   DT_RETURN_MARK(GetDefaultJavaVMInitArgs, jint, (const jint&)ret);
3864 
3865   if (Threads::is_supported_jni_version(args->version)) {
3866     ret = JNI_OK;
3867   }
3868   // 1.1 style no longer supported in hotspot.
3869   // According the JNI spec, we should update args->version on return.


4028   jint result = JNI_ERR;
4029   // On Windows, let CreateJavaVM run with SEH protection
4030 #ifdef _WIN32
4031   __try {
4032 #endif
4033     result = JNI_CreateJavaVM_inner(vm, penv, args);
4034 #ifdef _WIN32
4035   } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
4036     // Nothing to do.
4037   }
4038 #endif
4039   return result;
4040 }
4041 
4042 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {
4043   // See bug 4367188, the wrapper can sometimes cause VM crashes
4044   // JNIWrapper("GetCreatedJavaVMs");
4045 
4046   HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY((void **) vm_buf, bufLen, (uintptr_t *) numVMs);
4047 
4048   if (vm_created) {
4049     if (numVMs != NULL) *numVMs = 1;
4050     if (bufLen > 0)     *vm_buf = (JavaVM *)(&main_vm);
4051   } else {
4052     if (numVMs != NULL) *numVMs = 0;
4053   }
4054   HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN(JNI_OK);
4055   return JNI_OK;
4056 }
4057 
4058 extern "C" {
4059 
4060 DT_RETURN_MARK_DECL(DestroyJavaVM, jint
4061                     , HOTSPOT_JNI_DESTROYJAVAVM_RETURN(_ret_ref));
4062 
4063 static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) {
4064   HOTSPOT_JNI_DESTROYJAVAVM_ENTRY(vm);
4065   jint res = JNI_ERR;
4066   DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res);
4067 
4068   if (!vm_created) {
4069     res = JNI_ERR;
4070     return res;
4071   }
4072 
4073   JNIWrapper("DestroyJavaVM");
4074   JNIEnv *env;
4075   JavaVMAttachArgs destroyargs;
4076   destroyargs.version = CurrentVersion;
4077   destroyargs.name = (char *)"DestroyJavaVM";
4078   destroyargs.group = NULL;
4079   res = vm->AttachCurrentThread((void **)&env, (void *)&destroyargs);
4080   if (res != JNI_OK) {
4081     return res;
4082   }
4083 
4084   // Since this is not a JVM_ENTRY we have to set the thread state manually before entering.
4085   JavaThread* thread = JavaThread::current();
4086   ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
4087   if (Threads::destroy_vm()) {
4088     // Should not change thread state, VM is gone
4089     vm_created = false;
4090     res = JNI_OK;
4091     return res;
4092   } else {
4093     ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
4094     res = JNI_ERR;
4095     return res;
4096   }
4097 }
4098 
4099 jint JNICALL jni_DestroyJavaVM(JavaVM *vm) {
4100   jint result = JNI_ERR;
4101   // On Windows, we need SEH protection
4102 #ifdef _WIN32
4103   __try {
4104 #endif
4105     result = jni_DestroyJavaVM_inner(vm);
4106 #ifdef _WIN32
4107   } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
4108     // Nothing to do.
4109   }


4209   }
4210 
4211   *(JNIEnv**)penv = thread->jni_environment();
4212 
4213   // Now leaving the VM, so change thread_state. This is normally automatically taken care
4214   // of in the JVM_ENTRY. But in this situation we have to do it manually. Notice, that by
4215   // using ThreadStateTransition::transition, we do a callback to the safepoint code if
4216   // needed.
4217 
4218   ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
4219 
4220   // Perform any platform dependent FPU setup
4221   os::setup_fpu();
4222 
4223   return JNI_OK;
4224 }
4225 
4226 
4227 jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) {
4228   HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(vm, penv, _args);
4229   if (!vm_created) {
4230   HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR);
4231     return JNI_ERR;
4232   }
4233 
4234   JNIWrapper("AttachCurrentThread");
4235   jint ret = attach_current_thread(vm, penv, _args, false);
4236   HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(ret);
4237   return ret;
4238 }
4239 
4240 
4241 jint JNICALL jni_DetachCurrentThread(JavaVM *vm)  {
4242   HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY(vm);
4243   VM_Exit::block_if_vm_exited();
4244 
4245   JNIWrapper("DetachCurrentThread");
4246 
4247   // If the thread has already been detached the operation is a no-op
4248   if (Thread::current_or_null() == NULL) {
4249   HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);


4268   // the removal of the guards is buried below in JavaThread::exit()
4269   // here. The abstraction should be more symmetrically either exposed
4270   // or hidden (e.g. it could probably be hidden in the same
4271   // (platform-dependent) methods where we do alternate stack
4272   // maintenance work?)
4273   thread->exit(false, JavaThread::jni_detach);
4274   delete thread;
4275 
4276   HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);
4277   return JNI_OK;
4278 }
4279 
4280 DT_RETURN_MARK_DECL(GetEnv, jint
4281                     , HOTSPOT_JNI_GETENV_RETURN(_ret_ref));
4282 
4283 jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {
4284   HOTSPOT_JNI_GETENV_ENTRY(vm, penv, version);
4285   jint ret = JNI_ERR;
4286   DT_RETURN_MARK(GetEnv, jint, (const jint&)ret);
4287 
4288   if (!vm_created) {
4289     *penv = NULL;
4290     ret = JNI_EDETACHED;
4291     return ret;
4292   }
4293 
4294   if (JniExportedInterface::GetExportedInterface(vm, penv, version, &ret)) {
4295     return ret;
4296   }
4297 
4298 #ifndef JVMPI_VERSION_1
4299 // need these in order to be polite about older agents
4300 #define JVMPI_VERSION_1   ((jint)0x10000001)
4301 #define JVMPI_VERSION_1_1 ((jint)0x10000002)
4302 #define JVMPI_VERSION_1_2 ((jint)0x10000003)
4303 #endif // !JVMPI_VERSION_1
4304 
4305   Thread* thread = Thread::current_or_null();
4306   if (thread != NULL && thread->is_Java_thread()) {
4307     if (Threads::is_supported_jni_version_including_1_1(version)) {
4308       *(JNIEnv**)penv = ((JavaThread*) thread)->jni_environment();


4319     } else if (JvmtiExport::is_jvmdi_version(version)) {
4320       tty->print_cr("FATAL ERROR: JVMDI is no longer supported.");
4321       tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");
4322       ret = JNI_EVERSION;
4323       return ret;
4324     } else {
4325       *penv = NULL;
4326       ret = JNI_EVERSION;
4327       return ret;
4328     }
4329   } else {
4330     *penv = NULL;
4331     ret = JNI_EDETACHED;
4332     return ret;
4333   }
4334 }
4335 
4336 
4337 jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) {
4338   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(vm, penv, _args);
4339   if (!vm_created) {
4340   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN((uint32_t) JNI_ERR);
4341     return JNI_ERR;
4342   }
4343 
4344   JNIWrapper("AttachCurrentThreadAsDaemon");
4345   jint ret = attach_current_thread(vm, penv, _args, true);
4346   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(ret);
4347   return ret;
4348 }
4349 
4350 
4351 } // End extern "C"
4352 
4353 const struct JNIInvokeInterface_ jni_InvokeInterface = {
4354     NULL,
4355     NULL,
4356     NULL,
4357 
4358     jni_DestroyJavaVM,
4359     jni_AttachCurrentThread,


   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "jni.h"
  28 #include "jvm.h"
  29 #include "ci/ciReplay.hpp"
  30 #include "classfile/altHashing.hpp"
  31 #include "classfile/classFileStream.hpp"
  32 #include "classfile/classLoader.hpp"
  33 #include "classfile/javaClasses.hpp"
  34 #include "classfile/javaClasses.inline.hpp"
  35 #include "classfile/modules.hpp"
  36 #include "classfile/symbolTable.hpp"
  37 #include "classfile/systemDictionary.hpp"
  38 #include "classfile/vmSymbols.hpp"
  39 #include "gc/shared/gcLocker.inline.hpp"
  40 #include "interpreter/linkResolver.hpp"
  41 #include "memory/allocation.hpp"
  42 #include "memory/allocation.inline.hpp"
  43 #include "memory/oopFactory.hpp"
  44 #include "memory/resourceArea.hpp"
  45 #include "memory/universe.inline.hpp"
  46 #include "oops/instanceKlass.hpp"
  47 #include "oops/instanceOop.hpp"
  48 #include "oops/markOop.hpp"
  49 #include "oops/method.hpp"
  50 #include "oops/objArrayKlass.hpp"
  51 #include "oops/objArrayOop.inline.hpp"
  52 #include "oops/oop.inline.hpp"
  53 #include "oops/symbol.hpp"
  54 #include "oops/typeArrayKlass.hpp"
  55 #include "oops/typeArrayOop.hpp"
  56 #include "prims/jniCheck.hpp"
  57 #include "prims/jniExport.hpp"
  58 #include "prims/jniFastGetField.hpp"

  59 #include "prims/jvm_misc.hpp"
  60 #include "prims/jvmtiExport.hpp"
  61 #include "prims/jvmtiThreadState.hpp"
  62 #include "runtime/atomic.hpp"
  63 #include "runtime/compilationPolicy.hpp"
  64 #include "runtime/fieldDescriptor.hpp"
  65 #include "runtime/handles.inline.hpp"
  66 #include "runtime/interfaceSupport.hpp"
  67 #include "runtime/java.hpp"
  68 #include "runtime/javaCalls.hpp"
  69 #include "runtime/jfieldIDWorkaround.hpp"
  70 #include "runtime/orderAccess.inline.hpp"
  71 #include "runtime/reflection.hpp"
  72 #include "runtime/sharedRuntime.hpp"
  73 #include "runtime/signature.hpp"
  74 #include "runtime/thread.inline.hpp"
  75 #include "runtime/vm_operations.hpp"
  76 #include "services/memTracker.hpp"
  77 #include "services/runtimeService.hpp"
  78 #include "trace/traceMacros.hpp"


 246     "Bug in native code: jfieldID class must match object");
 247     } else {
 248 #if 0
 249       #ifndef PRODUCT
 250       if (Verbose) {
 251   ResourceMark rm;
 252   warning("VerifyJNIFields: unverified offset %d for %s", offset, k->external_name());
 253       }
 254       #endif
 255 #endif
 256     }
 257   }
 258   guarantee(InstanceKlass::cast(k)->contains_field_offset(offset),
 259       "Bug in native code: jfieldID offset must address interior of object");
 260 }
 261 
 262 // Wrapper to trace JNI functions
 263 
 264 #ifdef ASSERT
 265   Histogram* JNIHistogram;
 266   static volatile int JNIHistogram_lock = 0;
 267 
 268   class JNIHistogramElement : public HistogramElement {
 269     public:
 270      JNIHistogramElement(const char* name);
 271   };
 272 
 273   JNIHistogramElement::JNIHistogramElement(const char* elementName) {
 274     _name = elementName;
 275     uintx count = 0;
 276 
 277     while (Atomic::cmpxchg(1, &JNIHistogram_lock, 0) != 0) {
 278       while (OrderAccess::load_acquire(&JNIHistogram_lock) != 0) {
 279         count +=1;
 280         if ( (WarnOnStalledSpinLock > 0)
 281           && (count % WarnOnStalledSpinLock == 0)) {
 282           warning("JNIHistogram_lock seems to be stalled");
 283         }
 284       }
 285      }
 286 


3260 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
3261   JNIWrapper("jni_DeleteWeakGlobalRef");
3262   HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(env, ref);
3263   JNIHandles::destroy_weak_global(ref);
3264   HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN();
3265 JNI_END
3266 
3267 
3268 JNI_QUICK_ENTRY(jboolean, jni_ExceptionCheck(JNIEnv *env))
3269   JNIWrapper("jni_ExceptionCheck");
3270  HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(env);
3271   jni_check_async_exceptions(thread);
3272   jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;
3273  HOTSPOT_JNI_EXCEPTIONCHECK_RETURN(ret);
3274   return ret;
3275 JNI_END
3276 
3277 
3278 // Initialization state for three routines below relating to
3279 // java.nio.DirectBuffers
3280 static          int directBufferSupportInitializeStarted = 0;
3281 static volatile int directBufferSupportInitializeEnded   = 0;
3282 static volatile int directBufferSupportInitializeFailed  = 0;
3283 static jclass    bufferClass                 = NULL;
3284 static jclass    directBufferClass           = NULL;
3285 static jclass    directByteBufferClass       = NULL;
3286 static jmethodID directByteBufferConstructor = NULL;
3287 static jfieldID  directBufferAddressField    = NULL;
3288 static jfieldID  bufferCapacityField         = NULL;
3289 
3290 static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) {
3291   Handle loader;            // null (bootstrap) loader
3292   Handle protection_domain; // null protection domain
3293 
3294   TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);
3295   jclass result =  find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);
3296 
3297   if (log_is_enabled(Debug, class, resolve) && result != NULL) {
3298     trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
3299   }
3300   return result;
3301 }
3302 


3827 struct JNINativeInterface_* jni_functions() {
3828 #if INCLUDE_JNI_CHECK
3829   if (CheckJNICalls) return jni_functions_check();
3830 #endif // INCLUDE_JNI_CHECK
3831   return &jni_NativeInterface;
3832 }
3833 
3834 // Returns the function structure
3835 struct JNINativeInterface_* jni_functions_nocheck() {
3836   return &jni_NativeInterface;
3837 }
3838 
3839 
3840 // Invocation API
3841 
3842 
3843 // Forward declaration
3844 extern const struct JNIInvokeInterface_ jni_InvokeInterface;
3845 
3846 // Global invocation API vars
3847 volatile int vm_created = 0;
3848 // Indicate whether it is safe to recreate VM
3849 volatile int safe_to_recreate_vm = 1;
3850 struct JavaVM_ main_vm = {&jni_InvokeInterface};
3851 
3852 
3853 #define JAVASTACKSIZE (400 * 1024)    /* Default size of a thread java stack */
3854 enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL };
3855 
3856 DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint
3857                     , HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN(_ret_ref));
3858 
3859 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
3860   HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY(args_);
3861   JDK1_1InitArgs *args = (JDK1_1InitArgs *)args_;
3862   jint ret = JNI_ERR;
3863   DT_RETURN_MARK(GetDefaultJavaVMInitArgs, jint, (const jint&)ret);
3864 
3865   if (Threads::is_supported_jni_version(args->version)) {
3866     ret = JNI_OK;
3867   }
3868   // 1.1 style no longer supported in hotspot.
3869   // According the JNI spec, we should update args->version on return.


4028   jint result = JNI_ERR;
4029   // On Windows, let CreateJavaVM run with SEH protection
4030 #ifdef _WIN32
4031   __try {
4032 #endif
4033     result = JNI_CreateJavaVM_inner(vm, penv, args);
4034 #ifdef _WIN32
4035   } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
4036     // Nothing to do.
4037   }
4038 #endif
4039   return result;
4040 }
4041 
4042 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {
4043   // See bug 4367188, the wrapper can sometimes cause VM crashes
4044   // JNIWrapper("GetCreatedJavaVMs");
4045 
4046   HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY((void **) vm_buf, bufLen, (uintptr_t *) numVMs);
4047 
4048   if (vm_created == 1) {
4049     if (numVMs != NULL) *numVMs = 1;
4050     if (bufLen > 0)     *vm_buf = (JavaVM *)(&main_vm);
4051   } else {
4052     if (numVMs != NULL) *numVMs = 0;
4053   }
4054   HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN(JNI_OK);
4055   return JNI_OK;
4056 }
4057 
4058 extern "C" {
4059 
4060 DT_RETURN_MARK_DECL(DestroyJavaVM, jint
4061                     , HOTSPOT_JNI_DESTROYJAVAVM_RETURN(_ret_ref));
4062 
4063 static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) {
4064   HOTSPOT_JNI_DESTROYJAVAVM_ENTRY(vm);
4065   jint res = JNI_ERR;
4066   DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res);
4067 
4068   if (vm_created == 0) {
4069     res = JNI_ERR;
4070     return res;
4071   }
4072 
4073   JNIWrapper("DestroyJavaVM");
4074   JNIEnv *env;
4075   JavaVMAttachArgs destroyargs;
4076   destroyargs.version = CurrentVersion;
4077   destroyargs.name = (char *)"DestroyJavaVM";
4078   destroyargs.group = NULL;
4079   res = vm->AttachCurrentThread((void **)&env, (void *)&destroyargs);
4080   if (res != JNI_OK) {
4081     return res;
4082   }
4083 
4084   // Since this is not a JVM_ENTRY we have to set the thread state manually before entering.
4085   JavaThread* thread = JavaThread::current();
4086   ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
4087   if (Threads::destroy_vm()) {
4088     // Should not change thread state, VM is gone
4089     vm_created = 0;
4090     res = JNI_OK;
4091     return res;
4092   } else {
4093     ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
4094     res = JNI_ERR;
4095     return res;
4096   }
4097 }
4098 
4099 jint JNICALL jni_DestroyJavaVM(JavaVM *vm) {
4100   jint result = JNI_ERR;
4101   // On Windows, we need SEH protection
4102 #ifdef _WIN32
4103   __try {
4104 #endif
4105     result = jni_DestroyJavaVM_inner(vm);
4106 #ifdef _WIN32
4107   } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
4108     // Nothing to do.
4109   }


4209   }
4210 
4211   *(JNIEnv**)penv = thread->jni_environment();
4212 
4213   // Now leaving the VM, so change thread_state. This is normally automatically taken care
4214   // of in the JVM_ENTRY. But in this situation we have to do it manually. Notice, that by
4215   // using ThreadStateTransition::transition, we do a callback to the safepoint code if
4216   // needed.
4217 
4218   ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
4219 
4220   // Perform any platform dependent FPU setup
4221   os::setup_fpu();
4222 
4223   return JNI_OK;
4224 }
4225 
4226 
4227 jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) {
4228   HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(vm, penv, _args);
4229   if (vm_created == 0) {
4230   HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR);
4231     return JNI_ERR;
4232   }
4233 
4234   JNIWrapper("AttachCurrentThread");
4235   jint ret = attach_current_thread(vm, penv, _args, false);
4236   HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(ret);
4237   return ret;
4238 }
4239 
4240 
4241 jint JNICALL jni_DetachCurrentThread(JavaVM *vm)  {
4242   HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY(vm);
4243   VM_Exit::block_if_vm_exited();
4244 
4245   JNIWrapper("DetachCurrentThread");
4246 
4247   // If the thread has already been detached the operation is a no-op
4248   if (Thread::current_or_null() == NULL) {
4249   HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);


4268   // the removal of the guards is buried below in JavaThread::exit()
4269   // here. The abstraction should be more symmetrically either exposed
4270   // or hidden (e.g. it could probably be hidden in the same
4271   // (platform-dependent) methods where we do alternate stack
4272   // maintenance work?)
4273   thread->exit(false, JavaThread::jni_detach);
4274   delete thread;
4275 
4276   HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);
4277   return JNI_OK;
4278 }
4279 
4280 DT_RETURN_MARK_DECL(GetEnv, jint
4281                     , HOTSPOT_JNI_GETENV_RETURN(_ret_ref));
4282 
4283 jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {
4284   HOTSPOT_JNI_GETENV_ENTRY(vm, penv, version);
4285   jint ret = JNI_ERR;
4286   DT_RETURN_MARK(GetEnv, jint, (const jint&)ret);
4287 
4288   if (vm_created == 0) {
4289     *penv = NULL;
4290     ret = JNI_EDETACHED;
4291     return ret;
4292   }
4293 
4294   if (JniExportedInterface::GetExportedInterface(vm, penv, version, &ret)) {
4295     return ret;
4296   }
4297 
4298 #ifndef JVMPI_VERSION_1
4299 // need these in order to be polite about older agents
4300 #define JVMPI_VERSION_1   ((jint)0x10000001)
4301 #define JVMPI_VERSION_1_1 ((jint)0x10000002)
4302 #define JVMPI_VERSION_1_2 ((jint)0x10000003)
4303 #endif // !JVMPI_VERSION_1
4304 
4305   Thread* thread = Thread::current_or_null();
4306   if (thread != NULL && thread->is_Java_thread()) {
4307     if (Threads::is_supported_jni_version_including_1_1(version)) {
4308       *(JNIEnv**)penv = ((JavaThread*) thread)->jni_environment();


4319     } else if (JvmtiExport::is_jvmdi_version(version)) {
4320       tty->print_cr("FATAL ERROR: JVMDI is no longer supported.");
4321       tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");
4322       ret = JNI_EVERSION;
4323       return ret;
4324     } else {
4325       *penv = NULL;
4326       ret = JNI_EVERSION;
4327       return ret;
4328     }
4329   } else {
4330     *penv = NULL;
4331     ret = JNI_EDETACHED;
4332     return ret;
4333   }
4334 }
4335 
4336 
4337 jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) {
4338   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(vm, penv, _args);
4339   if (vm_created == 0) {
4340   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN((uint32_t) JNI_ERR);
4341     return JNI_ERR;
4342   }
4343 
4344   JNIWrapper("AttachCurrentThreadAsDaemon");
4345   jint ret = attach_current_thread(vm, penv, _args, true);
4346   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(ret);
4347   return ret;
4348 }
4349 
4350 
4351 } // End extern "C"
4352 
4353 const struct JNIInvokeInterface_ jni_InvokeInterface = {
4354     NULL,
4355     NULL,
4356     NULL,
4357 
4358     jni_DestroyJavaVM,
4359     jni_AttachCurrentThread,
< prev index next >