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,
|