1 /*
2 * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012 Red Hat, Inc.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
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/moduleEntry.hpp"
36 #include "classfile/modules.hpp"
37 #include "classfile/symbolTable.hpp"
38 #include "classfile/systemDictionary.hpp"
39 #include "classfile/vmSymbols.hpp"
40 #include "gc/shared/gcLocker.inline.hpp"
41 #include "interpreter/linkResolver.hpp"
42 #include "jfr/jfrEvents.hpp"
43 #include "jfr/support/jfrThreadId.hpp"
44 #include "logging/log.hpp"
45 #include "memory/allocation.hpp"
46 #include "memory/allocation.inline.hpp"
47 #include "memory/oopFactory.hpp"
48 #include "memory/resourceArea.hpp"
49 #include "memory/universe.hpp"
50 #include "oops/access.inline.hpp"
51 #include "oops/arrayOop.inline.hpp"
52 #include "oops/instanceKlass.inline.hpp"
53 #include "oops/instanceOop.hpp"
54 #include "oops/markWord.hpp"
55 #include "oops/method.hpp"
56 #include "oops/objArrayKlass.hpp"
57 #include "oops/objArrayOop.inline.hpp"
58 #include "oops/oop.inline.hpp"
59 #include "oops/symbol.hpp"
60 #include "oops/typeArrayKlass.hpp"
61 #include "oops/typeArrayOop.inline.hpp"
62 #include "prims/jniCheck.hpp"
63 #include "prims/jniExport.hpp"
64 #include "prims/jniFastGetField.hpp"
65 #include "prims/jvm_misc.hpp"
66 #include "prims/jvmtiExport.hpp"
67 #include "prims/jvmtiThreadState.hpp"
68 #include "runtime/atomic.hpp"
69 #include "runtime/fieldDescriptor.inline.hpp"
70 #include "runtime/handles.inline.hpp"
71 #include "runtime/interfaceSupport.inline.hpp"
72 #include "runtime/java.hpp"
73 #include "runtime/javaCalls.hpp"
74 #include "runtime/jfieldIDWorkaround.hpp"
75 #include "runtime/jniHandles.inline.hpp"
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)
117 // return_value = 5;
118 // return return_value;
119 // JNI_END
120 #define DT_RETURN_MARK_DECL(name, type, probe) \
121 DTRACE_ONLY( \
122 class DTraceReturnProbeMark_##name { \
123 public: \
124 const type& _ret_ref; \
125 DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {} \
126 ~DTraceReturnProbeMark_##name() { \
127 probe; \
128 } \
129 } \
130 )
131 // Void functions are simpler since there's no return value
132 #define DT_VOID_RETURN_MARK_DECL(name, probe) \
133 DTRACE_ONLY( \
134 class DTraceReturnProbeMark_##name { \
135 public: \
136 ~DTraceReturnProbeMark_##name() { \
137 probe; \
138 } \
139 } \
140 )
141
142 // Place these macros in the function to mark the return. Non-void
143 // functions need the type and address of the return value.
144 #define DT_RETURN_MARK(name, type, ref) \
145 DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark(ref) )
146 #define DT_VOID_RETURN_MARK(name) \
147 DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark )
148
149
150 // Use these to select distinct code for floating-point vs. non-floating point
151 // situations. Used from within common macros where we need slightly
152 // different behavior for Float/Double
153 #define FP_SELECT_Boolean(intcode, fpcode) intcode
154 #define FP_SELECT_Byte(intcode, fpcode) intcode
155 #define FP_SELECT_Char(intcode, fpcode) intcode
156 #define FP_SELECT_Short(intcode, fpcode) intcode
157 #define FP_SELECT_Object(intcode, fpcode) intcode
158 #define FP_SELECT_Int(intcode, fpcode) intcode
159 #define FP_SELECT_Long(intcode, fpcode) intcode
160 #define FP_SELECT_Float(intcode, fpcode) fpcode
161 #define FP_SELECT_Double(intcode, fpcode) fpcode
162 #define FP_SELECT(TypeName, intcode, fpcode) \
163 FP_SELECT_##TypeName(intcode, fpcode)
164
165 // Choose DT_RETURN_MARK macros based on the type: float/double -> void
166 // (dtrace doesn't do FP yet)
167 #define DT_RETURN_MARK_DECL_FOR(TypeName, name, type, probe) \
168 FP_SELECT(TypeName, \
169 DT_RETURN_MARK_DECL(name, type, probe), DT_VOID_RETURN_MARK_DECL(name, probe) )
170 #define DT_RETURN_MARK_FOR(TypeName, name, type, ref) \
171 FP_SELECT(TypeName, \
172 DT_RETURN_MARK(name, type, ref), DT_VOID_RETURN_MARK(name) )
173
174
175 // out-of-line helpers for class jfieldIDWorkaround:
176
is_valid_jfieldID(Klass * k,jfieldID id)177 bool jfieldIDWorkaround::is_valid_jfieldID(Klass* k, jfieldID id) {
178 if (jfieldIDWorkaround::is_instance_jfieldID(k, id)) {
179 uintptr_t as_uint = (uintptr_t) id;
180 intptr_t offset = raw_instance_offset(id);
181 if (is_checked_jfieldID(id)) {
182 if (!klass_hash_ok(k, id)) {
183 return false;
184 }
185 }
186 return InstanceKlass::cast(k)->contains_field_offset(offset);
187 } else {
188 JNIid* result = (JNIid*) id;
189 #ifdef ASSERT
190 return result != NULL && result->is_static_field_id();
191 #else
192 return result != NULL;
193 #endif
194 }
195 }
196
197
encode_klass_hash(Klass * k,intptr_t offset)198 intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) {
199 if (offset <= small_offset_mask) {
200 Klass* field_klass = k;
201 Klass* super_klass = field_klass->super();
202 // With compressed oops the most super class with nonstatic fields would
203 // be the owner of fields embedded in the header.
204 while (InstanceKlass::cast(super_klass)->has_nonstatic_fields() &&
205 InstanceKlass::cast(super_klass)->contains_field_offset(offset)) {
206 field_klass = super_klass; // super contains the field also
207 super_klass = field_klass->super();
208 }
209 debug_only(NoSafepointVerifier nosafepoint;)
210 uintptr_t klass_hash = field_klass->identity_hash();
211 return ((klass_hash & klass_mask) << klass_shift) | checked_mask_in_place;
212 } else {
213 #if 0
214 #ifndef PRODUCT
215 {
216 ResourceMark rm;
217 warning("VerifyJNIFields: long offset %d in %s", offset, k->external_name());
218 }
219 #endif
220 #endif
221 return 0;
222 }
223 }
224
klass_hash_ok(Klass * k,jfieldID id)225 bool jfieldIDWorkaround::klass_hash_ok(Klass* k, jfieldID id) {
226 uintptr_t as_uint = (uintptr_t) id;
227 intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask;
228 do {
229 debug_only(NoSafepointVerifier nosafepoint;)
230 // Could use a non-blocking query for identity_hash here...
231 if ((k->identity_hash() & klass_mask) == klass_hash)
232 return true;
233 k = k->super();
234 } while (k != NULL);
235 return false;
236 }
237
verify_instance_jfieldID(Klass * k,jfieldID id)238 void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) {
239 guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" );
240 uintptr_t as_uint = (uintptr_t) id;
241 intptr_t offset = raw_instance_offset(id);
242 if (VerifyJNIFields) {
243 if (is_checked_jfieldID(id)) {
244 guarantee(klass_hash_ok(k, id),
245 "Bug in native code: jfieldID class must match object");
246 } else {
247 #if 0
248 #ifndef PRODUCT
249 if (Verbose) {
250 ResourceMark rm;
251 warning("VerifyJNIFields: unverified offset %d for %s", offset, k->external_name());
252 }
253 #endif
254 #endif
255 }
256 }
257 guarantee(InstanceKlass::cast(k)->contains_field_offset(offset),
258 "Bug in native code: jfieldID offset must address interior of object");
259 }
260
261 // Wrapper to trace JNI functions
262
263 #ifdef ASSERT
264 Histogram* JNIHistogram;
265 static volatile int JNIHistogram_lock = 0;
266
267 class JNIHistogramElement : public HistogramElement {
268 public:
269 JNIHistogramElement(const char* name);
270 };
271
JNIHistogramElement(const char * elementName)272 JNIHistogramElement::JNIHistogramElement(const char* elementName) {
273 _name = elementName;
274 uintx count = 0;
275
276 while (Atomic::cmpxchg(&JNIHistogram_lock, 0, 1) != 0) {
277 while (Atomic::load_acquire(&JNIHistogram_lock) != 0) {
278 count +=1;
279 if ( (WarnOnStalledSpinLock > 0)
280 && (count % WarnOnStalledSpinLock == 0)) {
281 warning("JNIHistogram_lock seems to be stalled");
282 }
283 }
284 }
285
286
287 if(JNIHistogram == NULL)
288 JNIHistogram = new Histogram("JNI Call Counts",100);
289
290 JNIHistogram->add_element(this);
291 Atomic::dec(&JNIHistogram_lock);
292 }
293
294 #define JNICountWrapper(arg) \
295 static JNIHistogramElement* e = new JNIHistogramElement(arg); \
296 /* There is a MT-race condition in VC++. So we need to make sure that that e has been initialized */ \
297 if (e != NULL) e->increment_count()
298 #define JNIWrapper(arg) JNICountWrapper(arg);
299 #else
300 #define JNIWrapper(arg)
301 #endif
302
303
304 // Implementation of JNI entries
305
306 DT_RETURN_MARK_DECL(DefineClass, jclass
307 , HOTSPOT_JNI_DEFINECLASS_RETURN(_ret_ref));
308
309 JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderRef,
310 const jbyte *buf, jsize bufLen))
311 JNIWrapper("DefineClass");
312
313 HOTSPOT_JNI_DEFINECLASS_ENTRY(
314 env, (char*) name, loaderRef, (char*) buf, bufLen);
315
316 jclass cls = NULL;
317 DT_RETURN_MARK(DefineClass, jclass, (const jclass&)cls);
318
319 // Class resolution will get the class name from the .class stream if the name is null.
320 TempNewSymbol class_name = name == NULL ? NULL :
321 SystemDictionary::class_name_symbol(name, vmSymbols::java_lang_NoClassDefFoundError(),
322 CHECK_NULL);
323
324 ResourceMark rm(THREAD);
325 ClassFileStream st((u1*)buf, bufLen, NULL, ClassFileStream::verify);
326 Handle class_loader (THREAD, JNIHandles::resolve(loaderRef));
327
328 if (UsePerfData && !class_loader.is_null()) {
329 // check whether the current caller thread holds the lock or not.
330 // If not, increment the corresponding counter
331 if (ObjectSynchronizer::
332 query_lock_ownership((JavaThread*)THREAD, class_loader) !=
333 ObjectSynchronizer::owner_self) {
334 ClassLoader::sync_JNIDefineClassLockFreeCounter()->inc();
335 }
336 }
337 Klass* k = SystemDictionary::resolve_from_stream(class_name,
338 class_loader,
339 Handle(),
340 &st,
341 CHECK_NULL);
342
343 if (log_is_enabled(Debug, class, resolve) && k != NULL) {
344 trace_class_resolution(k);
345 }
346
347 cls = (jclass)JNIHandles::make_local(
348 env, k->java_mirror());
349 return cls;
350 JNI_END
351
352
353
354 DT_RETURN_MARK_DECL(FindClass, jclass
355 , HOTSPOT_JNI_FINDCLASS_RETURN(_ret_ref));
356
357 JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
358 JNIWrapper("FindClass");
359
360 HOTSPOT_JNI_FINDCLASS_ENTRY(env, (char *)name);
361
362 jclass result = NULL;
363 DT_RETURN_MARK(FindClass, jclass, (const jclass&)result);
364
365 // This should be ClassNotFoundException imo.
366 TempNewSymbol class_name =
367 SystemDictionary::class_name_symbol(name, vmSymbols::java_lang_NoClassDefFoundError(),
368 CHECK_NULL);
369
370 //%note jni_3
371 Handle protection_domain;
372 // Find calling class
373 Klass* k = thread->security_get_caller_class(0);
374 // default to the system loader when no context
375 Handle loader(THREAD, SystemDictionary::java_system_loader());
376 if (k != NULL) {
377 // Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed
378 // in the correct class context.
379 if (k->class_loader() == NULL &&
380 k->name() == vmSymbols::jdk_internal_loader_NativeLibraries()) {
381 JavaValue result(T_OBJECT);
382 JavaCalls::call_static(&result, k,
383 vmSymbols::getFromClass_name(),
384 vmSymbols::void_class_signature(),
385 CHECK_NULL);
386 // When invoked from JNI_OnLoad, NativeLibraries::getFromClass returns
387 // a non-NULL Class object. When invoked from JNI_OnUnload,
388 // it will return NULL to indicate no context.
389 oop mirror = (oop) result.get_jobject();
390 if (mirror != NULL) {
391 Klass* fromClass = java_lang_Class::as_Klass(mirror);
392 loader = Handle(THREAD, fromClass->class_loader());
393 protection_domain = Handle(THREAD, fromClass->protection_domain());
394 }
395 } else {
396 loader = Handle(THREAD, k->class_loader());
397 }
398 }
399
400 result = find_class_from_class_loader(env, class_name, true, loader,
401 protection_domain, true, thread);
402
403 if (log_is_enabled(Debug, class, resolve) && result != NULL) {
404 trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
405 }
406
407 return result;
408 JNI_END
409
410 DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID
411 , HOTSPOT_JNI_FROMREFLECTEDMETHOD_RETURN((uintptr_t)_ret_ref));
412
413 JNI_ENTRY(jmethodID, jni_FromReflectedMethod(JNIEnv *env, jobject method))
414 JNIWrapper("FromReflectedMethod");
415
416 HOTSPOT_JNI_FROMREFLECTEDMETHOD_ENTRY(env, method);
417
418 jmethodID ret = NULL;
419 DT_RETURN_MARK(FromReflectedMethod, jmethodID, (const jmethodID&)ret);
420
421 // method is a handle to a java.lang.reflect.Method object
422 oop reflected = JNIHandles::resolve_non_null(method);
423 oop mirror = NULL;
424 int slot = 0;
425
426 if (reflected->klass() == SystemDictionary::reflect_Constructor_klass()) {
427 mirror = java_lang_reflect_Constructor::clazz(reflected);
428 slot = java_lang_reflect_Constructor::slot(reflected);
429 } else {
430 assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");
431 mirror = java_lang_reflect_Method::clazz(reflected);
432 slot = java_lang_reflect_Method::slot(reflected);
433 }
434 Klass* k1 = java_lang_Class::as_Klass(mirror);
435
436 // Make sure class is initialized before handing id's out to methods
437 k1->initialize(CHECK_NULL);
438 Method* m = InstanceKlass::cast(k1)->method_with_idnum(slot);
439 ret = m==NULL? NULL : m->jmethod_id(); // return NULL if reflected method deleted
440 return ret;
441 JNI_END
442
443 DT_RETURN_MARK_DECL(FromReflectedField, jfieldID
444 , HOTSPOT_JNI_FROMREFLECTEDFIELD_RETURN((uintptr_t)_ret_ref));
445
446 JNI_ENTRY(jfieldID, jni_FromReflectedField(JNIEnv *env, jobject field))
447 JNIWrapper("FromReflectedField");
448
449 HOTSPOT_JNI_FROMREFLECTEDFIELD_ENTRY(env, field);
450
451 jfieldID ret = NULL;
452 DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret);
453
454 // field is a handle to a java.lang.reflect.Field object
455 oop reflected = JNIHandles::resolve_non_null(field);
456 oop mirror = java_lang_reflect_Field::clazz(reflected);
457 Klass* k1 = java_lang_Class::as_Klass(mirror);
458 int slot = java_lang_reflect_Field::slot(reflected);
459 int modifiers = java_lang_reflect_Field::modifiers(reflected);
460
461 // Make sure class is initialized before handing id's out to fields
462 k1->initialize(CHECK_NULL);
463
464 // First check if this is a static field
465 if (modifiers & JVM_ACC_STATIC) {
466 intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
467 JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
468 assert(id != NULL, "corrupt Field object");
469 debug_only(id->set_is_static_field_id();)
470 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
471 ret = jfieldIDWorkaround::to_static_jfieldID(id);
472 return ret;
473 }
474
475 // The slot is the index of the field description in the field-array
476 // The jfieldID is the offset of the field within the object
477 // It may also have hash bits for k, if VerifyJNIFields is turned on.
478 intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
479 assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
480 ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
481 return ret;
482 JNI_END
483
484
485 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
486 , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
487
488 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
489 JNIWrapper("ToReflectedMethod");
490
491 HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
492
493 jobject ret = NULL;
494 DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
495
496 methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
497 assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
498 oop reflection_method;
499 if (m->is_initializer()) {
500 reflection_method = Reflection::new_constructor(m, CHECK_NULL);
501 } else {
502 reflection_method = Reflection::new_method(m, false, CHECK_NULL);
503 }
504 ret = JNIHandles::make_local(env, reflection_method);
505 return ret;
506 JNI_END
507
508 DT_RETURN_MARK_DECL(GetSuperclass, jclass
509 , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
510
511 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
512 JNIWrapper("GetSuperclass");
513
514 HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
515
516 jclass obj = NULL;
517 DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
518
519 oop mirror = JNIHandles::resolve_non_null(sub);
520 // primitive classes return NULL
521 if (java_lang_Class::is_primitive(mirror)) return NULL;
522
523 // Rules of Class.getSuperClass as implemented by KLass::java_super:
524 // arrays return Object
525 // interfaces return NULL
526 // proper classes return Klass::super()
527 Klass* k = java_lang_Class::as_Klass(mirror);
528 if (k->is_interface()) return NULL;
529
530 // return mirror for superclass
531 Klass* super = k->java_super();
532 // super2 is the value computed by the compiler's getSuperClass intrinsic:
533 debug_only(Klass* super2 = ( k->is_array_klass()
534 ? SystemDictionary::Object_klass()
535 : k->super() ) );
536 assert(super == super2,
537 "java_super computation depends on interface, array, other super");
538 obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(super->java_mirror());
539 return obj;
540 JNI_END
541
542 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
543 JNIWrapper("IsSubclassOf");
544
545 HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
546
547 oop sub_mirror = JNIHandles::resolve_non_null(sub);
548 oop super_mirror = JNIHandles::resolve_non_null(super);
549 if (java_lang_Class::is_primitive(sub_mirror) ||
550 java_lang_Class::is_primitive(super_mirror)) {
551 jboolean ret = (sub_mirror == super_mirror);
552
553 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
554 return ret;
555 }
556 Klass* sub_klass = java_lang_Class::as_Klass(sub_mirror);
557 Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
558 assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
559 jboolean ret = sub_klass->is_subtype_of(super_klass) ?
560 JNI_TRUE : JNI_FALSE;
561
562 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
563 return ret;
564 JNI_END
565
566
567 DT_RETURN_MARK_DECL(Throw, jint
568 , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
569
570 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
571 JNIWrapper("Throw");
572
573 HOTSPOT_JNI_THROW_ENTRY(env, obj);
574
575 jint ret = JNI_OK;
576 DT_RETURN_MARK(Throw, jint, (const jint&)ret);
577
578 THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
579 ShouldNotReachHere();
580 return 0; // Mute compiler.
581 JNI_END
582
583
584 DT_RETURN_MARK_DECL(ThrowNew, jint
585 , HOTSPOT_JNI_THROWNEW_RETURN(_ret_ref));
586
587 JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message))
588 JNIWrapper("ThrowNew");
589
590 HOTSPOT_JNI_THROWNEW_ENTRY(env, clazz, (char *) message);
591
592 jint ret = JNI_OK;
593 DT_RETURN_MARK(ThrowNew, jint, (const jint&)ret);
594
595 InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
596 Symbol* name = k->name();
597 Handle class_loader (THREAD, k->class_loader());
598 Handle protection_domain (THREAD, k->protection_domain());
599 THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK);
600 ShouldNotReachHere();
601 return 0; // Mute compiler.
602 JNI_END
603
604
605 // JNI functions only transform a pending async exception to a synchronous
606 // exception in ExceptionOccurred and ExceptionCheck calls, since
607 // delivering an async exception in other places won't change the native
608 // code's control flow and would be harmful when native code further calls
609 // JNI functions with a pending exception. Async exception is also checked
610 // during the call, so ExceptionOccurred/ExceptionCheck won't return
611 // false but deliver the async exception at the very end during
612 // state transition.
613
jni_check_async_exceptions(JavaThread * thread)614 static void jni_check_async_exceptions(JavaThread *thread) {
615 assert(thread == Thread::current(), "must be itself");
616 thread->check_and_handle_async_exceptions();
617 }
618
619 JNI_ENTRY_NO_PRESERVE(jthrowable, jni_ExceptionOccurred(JNIEnv *env))
620 JNIWrapper("ExceptionOccurred");
621
622 HOTSPOT_JNI_EXCEPTIONOCCURRED_ENTRY(env);
623
624 jni_check_async_exceptions(thread);
625 oop exception = thread->pending_exception();
626 jthrowable ret = (jthrowable) JNIHandles::make_local(env, exception);
627
628 HOTSPOT_JNI_EXCEPTIONOCCURRED_RETURN(ret);
629 return ret;
630 JNI_END
631
632
633 JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionDescribe(JNIEnv *env))
634 JNIWrapper("ExceptionDescribe");
635
636 HOTSPOT_JNI_EXCEPTIONDESCRIBE_ENTRY(env);
637
638 if (thread->has_pending_exception()) {
639 Handle ex(thread, thread->pending_exception());
640 thread->clear_pending_exception();
641 if (ex->is_a(SystemDictionary::ThreadDeath_klass())) {
642 // Don't print anything if we are being killed.
643 } else {
644 jio_fprintf(defaultStream::error_stream(), "Exception ");
645 if (thread != NULL && thread->threadObj() != NULL) {
646 ResourceMark rm(THREAD);
647 jio_fprintf(defaultStream::error_stream(),
648 "in thread \"%s\" ", thread->get_thread_name());
649 }
650 if (ex->is_a(SystemDictionary::Throwable_klass())) {
651 JavaValue result(T_VOID);
652 JavaCalls::call_virtual(&result,
653 ex,
654 SystemDictionary::Throwable_klass(),
655 vmSymbols::printStackTrace_name(),
656 vmSymbols::void_method_signature(),
657 THREAD);
658 // If an exception is thrown in the call it gets thrown away. Not much
659 // we can do with it. The native code that calls this, does not check
660 // for the exception - hence, it might still be in the thread when DestroyVM gets
661 // called, potentially causing a few asserts to trigger - since no pending exception
662 // is expected.
663 CLEAR_PENDING_EXCEPTION;
664 } else {
665 ResourceMark rm(THREAD);
666 jio_fprintf(defaultStream::error_stream(),
667 ". Uncaught exception of type %s.",
668 ex->klass()->external_name());
669 }
670 }
671 }
672
673 HOTSPOT_JNI_EXCEPTIONDESCRIBE_RETURN();
674 JNI_END
675
676
677 JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionClear(JNIEnv *env))
678 JNIWrapper("ExceptionClear");
679
680 HOTSPOT_JNI_EXCEPTIONCLEAR_ENTRY(env);
681
682 // The jni code might be using this API to clear java thrown exception.
683 // So just mark jvmti thread exception state as exception caught.
684 JvmtiThreadState *state = JavaThread::current()->jvmti_thread_state();
685 if (state != NULL && state->is_exception_detected()) {
686 state->set_exception_caught();
687 }
688 thread->clear_pending_exception();
689
690 HOTSPOT_JNI_EXCEPTIONCLEAR_RETURN();
691 JNI_END
692
693
694 JNI_ENTRY(void, jni_FatalError(JNIEnv *env, const char *msg))
695 JNIWrapper("FatalError");
696
697 HOTSPOT_JNI_FATALERROR_ENTRY(env, (char *) msg);
698
699 tty->print_cr("FATAL ERROR in native method: %s", msg);
700 thread->print_stack();
701 os::abort(); // Dump core and abort
702 JNI_END
703
704
705 JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity))
706 JNIWrapper("PushLocalFrame");
707
708 HOTSPOT_JNI_PUSHLOCALFRAME_ENTRY(env, capacity);
709
710 //%note jni_11
711 if (capacity < 0 ||
712 ((MaxJNILocalCapacity > 0) && (capacity > MaxJNILocalCapacity))) {
713 HOTSPOT_JNI_PUSHLOCALFRAME_RETURN((uint32_t)JNI_ERR);
714 return JNI_ERR;
715 }
716 JNIHandleBlock* old_handles = thread->active_handles();
717 JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);
718 assert(new_handles != NULL, "should not be NULL");
719 new_handles->set_pop_frame_link(old_handles);
720 thread->set_active_handles(new_handles);
721 jint ret = JNI_OK;
722 HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(ret);
723 return ret;
724 JNI_END
725
726
727 JNI_ENTRY(jobject, jni_PopLocalFrame(JNIEnv *env, jobject result))
728 JNIWrapper("PopLocalFrame");
729
730 HOTSPOT_JNI_POPLOCALFRAME_ENTRY(env, result);
731
732 //%note jni_11
733 Handle result_handle(thread, JNIHandles::resolve(result));
734 JNIHandleBlock* old_handles = thread->active_handles();
735 JNIHandleBlock* new_handles = old_handles->pop_frame_link();
736 if (new_handles != NULL) {
737 // As a sanity check we only release the handle blocks if the pop_frame_link is not NULL.
738 // This way code will still work if PopLocalFrame is called without a corresponding
739 // PushLocalFrame call. Note that we set the pop_frame_link to NULL explicitly, otherwise
740 // the release_block call will release the blocks.
741 thread->set_active_handles(new_handles);
742 old_handles->set_pop_frame_link(NULL); // clear link we won't release new_handles below
743 JNIHandleBlock::release_block(old_handles, thread); // may block
744 result = JNIHandles::make_local(thread, result_handle());
745 }
746 HOTSPOT_JNI_POPLOCALFRAME_RETURN(result);
747 return result;
748 JNI_END
749
750
751 JNI_ENTRY(jobject, jni_NewGlobalRef(JNIEnv *env, jobject ref))
752 JNIWrapper("NewGlobalRef");
753
754 HOTSPOT_JNI_NEWGLOBALREF_ENTRY(env, ref);
755
756 Handle ref_handle(thread, JNIHandles::resolve(ref));
757 jobject ret = JNIHandles::make_global(ref_handle);
758
759 HOTSPOT_JNI_NEWGLOBALREF_RETURN(ret);
760 return ret;
761 JNI_END
762
763 // Must be JNI_ENTRY (with HandleMark)
764 JNI_ENTRY_NO_PRESERVE(void, jni_DeleteGlobalRef(JNIEnv *env, jobject ref))
765 JNIWrapper("DeleteGlobalRef");
766
767 HOTSPOT_JNI_DELETEGLOBALREF_ENTRY(env, ref);
768
769 JNIHandles::destroy_global(ref);
770
771 HOTSPOT_JNI_DELETEGLOBALREF_RETURN();
772 JNI_END
773
774 JNI_ENTRY_NO_PRESERVE(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj))
775 JNIWrapper("DeleteLocalRef");
776
777 HOTSPOT_JNI_DELETELOCALREF_ENTRY(env, obj);
778
779 JNIHandles::destroy_local(obj);
780
781 HOTSPOT_JNI_DELETELOCALREF_RETURN();
782 JNI_END
783
784 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))
785 JNIWrapper("IsSameObject");
786
787 HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(env, r1, r2);
788
789 jboolean ret = JNIHandles::is_same_object(r1, r2) ? JNI_TRUE : JNI_FALSE;
790
791 HOTSPOT_JNI_ISSAMEOBJECT_RETURN(ret);
792 return ret;
793 JNI_END
794
795
796 JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))
797 JNIWrapper("NewLocalRef");
798
799 HOTSPOT_JNI_NEWLOCALREF_ENTRY(env, ref);
800
801 jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));
802
803 HOTSPOT_JNI_NEWLOCALREF_RETURN(ret);
804 return ret;
805 JNI_END
806
807 JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))
808 JNIWrapper("EnsureLocalCapacity");
809
810 HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY(env, capacity);
811
812 jint ret;
813 if (capacity >= 0 &&
814 ((MaxJNILocalCapacity <= 0) || (capacity <= MaxJNILocalCapacity))) {
815 ret = JNI_OK;
816 } else {
817 ret = JNI_ERR;
818 }
819
820 HOTSPOT_JNI_ENSURELOCALCAPACITY_RETURN(ret);
821 return ret;
822 JNI_END
823
824 // Return the Handle Type
825 JNI_LEAF(jobjectRefType, jni_GetObjectRefType(JNIEnv *env, jobject obj))
826 JNIWrapper("GetObjectRefType");
827
828 HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY(env, obj);
829
830 jobjectRefType ret = JNIInvalidRefType;
831 if (obj != NULL) {
832 ret = JNIHandles::handle_type(thread, obj);
833 }
834
835 HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN((void *) ret);
836 return ret;
837 JNI_END
838
839
840 class JNI_ArgumentPusher : public SignatureIterator {
841 protected:
842 JavaCallArguments* _arguments;
843
push_int(jint x)844 void push_int(jint x) { _arguments->push_int(x); }
push_long(jlong x)845 void push_long(jlong x) { _arguments->push_long(x); }
push_float(jfloat x)846 void push_float(jfloat x) { _arguments->push_float(x); }
push_double(jdouble x)847 void push_double(jdouble x) { _arguments->push_double(x); }
push_object(jobject x)848 void push_object(jobject x) { _arguments->push_jobject(x); }
849
push_boolean(jboolean b)850 void push_boolean(jboolean b) {
851 // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and
852 // 0 to JNI_FALSE. Boolean return values from native are normalized the same in
853 // TemplateInterpreterGenerator::generate_result_handler_for and
854 // SharedRuntime::generate_native_wrapper.
855 push_int(b == 0 ? JNI_FALSE : JNI_TRUE);
856 }
857
JNI_ArgumentPusher(Method * method)858 JNI_ArgumentPusher(Method* method)
859 : SignatureIterator(method->signature(),
860 Fingerprinter(methodHandle(Thread::current(), method)).fingerprint())
861 {
862 _arguments = NULL;
863 }
864
865 public:
866 virtual void push_arguments_on(JavaCallArguments* arguments) = 0;
867 };
868
869
870 class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {
871 protected:
872 va_list _ap;
873
set_ap(va_list rap)874 void set_ap(va_list rap) {
875 va_copy(_ap, rap);
876 }
877
878 friend class SignatureIterator; // so do_parameters_on can call do_type
do_type(BasicType type)879 void do_type(BasicType type) {
880 switch (type) {
881 // these are coerced to int when using va_arg
882 case T_BYTE:
883 case T_CHAR:
884 case T_SHORT:
885 case T_INT: push_int(va_arg(_ap, jint)); break;
886 case T_BOOLEAN: push_boolean((jboolean) va_arg(_ap, jint)); break;
887
888 // each of these paths is exercised by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
889
890 case T_LONG: push_long(va_arg(_ap, jlong)); break;
891 // float is coerced to double w/ va_arg
892 case T_FLOAT: push_float((jfloat) va_arg(_ap, jdouble)); break;
893 case T_DOUBLE: push_double(va_arg(_ap, jdouble)); break;
894
895 case T_ARRAY:
896 case T_OBJECT: push_object(va_arg(_ap, jobject)); break;
897 default: ShouldNotReachHere();
898 }
899 }
900
901 public:
JNI_ArgumentPusherVaArg(jmethodID method_id,va_list rap)902 JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
903 : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
904 set_ap(rap);
905 }
906
push_arguments_on(JavaCallArguments * arguments)907 virtual void push_arguments_on(JavaCallArguments* arguments) {
908 _arguments = arguments;
909 do_parameters_on(this);
910 }
911 };
912
913
914 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
915 protected:
916 const jvalue *_ap;
917
set_ap(const jvalue * rap)918 inline void set_ap(const jvalue *rap) { _ap = rap; }
919
920 friend class SignatureIterator; // so do_parameters_on can call do_type
do_type(BasicType type)921 void do_type(BasicType type) {
922 switch (type) {
923 case T_CHAR: push_int((_ap++)->c); break;
924 case T_SHORT: push_int((_ap++)->s); break;
925 case T_BYTE: push_int((_ap++)->b); break;
926 case T_INT: push_int((_ap++)->i); break;
927 case T_BOOLEAN: push_boolean((_ap++)->z); break;
928 case T_LONG: push_long((_ap++)->j); break;
929 case T_FLOAT: push_float((_ap++)->f); break;
930 case T_DOUBLE: push_double((_ap++)->d); break;
931 case T_ARRAY:
932 case T_OBJECT: push_object((_ap++)->l); break;
933 default: ShouldNotReachHere();
934 }
935 }
936
937 public:
JNI_ArgumentPusherArray(jmethodID method_id,const jvalue * rap)938 JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
939 : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
940 set_ap(rap);
941 }
942
push_arguments_on(JavaCallArguments * arguments)943 virtual void push_arguments_on(JavaCallArguments* arguments) {
944 _arguments = arguments;
945 do_parameters_on(this);
946 }
947 };
948
949
950 enum JNICallType {
951 JNI_STATIC,
952 JNI_VIRTUAL,
953 JNI_NONVIRTUAL
954 };
955
956
957
jni_invoke_static(JNIEnv * env,JavaValue * result,jobject receiver,JNICallType call_type,jmethodID method_id,JNI_ArgumentPusher * args,TRAPS)958 static void jni_invoke_static(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
959 methodHandle method(THREAD, Method::resolve_jmethod_id(method_id));
960
961 // Create object to hold arguments for the JavaCall, and associate it with
962 // the jni parser
963 ResourceMark rm(THREAD);
964 int number_of_parameters = method->size_of_parameters();
965 JavaCallArguments java_args(number_of_parameters);
966
967 assert(method->is_static(), "method should be static");
968
969 // Fill out JavaCallArguments object
970 args->push_arguments_on(&java_args);
971 // Initialize result type
972 result->set_type(args->return_type());
973
974 // Invoke the method. Result is returned as oop.
975 JavaCalls::call(result, method, &java_args, CHECK);
976
977 // Convert result
978 if (is_reference_type(result->get_type())) {
979 result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
980 }
981 }
982
983
jni_invoke_nonstatic(JNIEnv * env,JavaValue * result,jobject receiver,JNICallType call_type,jmethodID method_id,JNI_ArgumentPusher * args,TRAPS)984 static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
985 oop recv = JNIHandles::resolve(receiver);
986 if (recv == NULL) {
987 THROW(vmSymbols::java_lang_NullPointerException());
988 }
989 Handle h_recv(THREAD, recv);
990
991 int number_of_parameters;
992 Method* selected_method;
993 {
994 Method* m = Method::resolve_jmethod_id(method_id);
995 number_of_parameters = m->size_of_parameters();
996 Klass* holder = m->method_holder();
997 if (call_type != JNI_VIRTUAL) {
998 selected_method = m;
999 } else if (!m->has_itable_index()) {
1000 // non-interface call -- for that little speed boost, don't handlize
1001 debug_only(NoSafepointVerifier nosafepoint;)
1002 // jni_GetMethodID makes sure class is linked and initialized
1003 // so m should have a valid vtable index.
1004 assert(m->valid_vtable_index(), "no valid vtable index");
1005 int vtbl_index = m->vtable_index();
1006 if (vtbl_index != Method::nonvirtual_vtable_index) {
1007 selected_method = h_recv->klass()->method_at_vtable(vtbl_index);
1008 } else {
1009 // final method
1010 selected_method = m;
1011 }
1012 } else {
1013 // interface call
1014 int itbl_index = m->itable_index();
1015 Klass* k = h_recv->klass();
1016 selected_method = InstanceKlass::cast(k)->method_at_itable(holder, itbl_index, CHECK);
1017 }
1018 }
1019
1020 methodHandle method(THREAD, selected_method);
1021
1022 // Create object to hold arguments for the JavaCall, and associate it with
1023 // the jni parser
1024 ResourceMark rm(THREAD);
1025 JavaCallArguments java_args(number_of_parameters);
1026
1027 // handle arguments
1028 assert(!method->is_static(), "method %s should not be static", method->name_and_sig_as_C_string());
1029 java_args.push_oop(h_recv); // Push jobject handle
1030
1031 // Fill out JavaCallArguments object
1032 args->push_arguments_on(&java_args);
1033 // Initialize result type
1034 result->set_type(args->return_type());
1035
1036 // Invoke the method. Result is returned as oop.
1037 JavaCalls::call(result, method, &java_args, CHECK);
1038
1039 // Convert result
1040 if (is_reference_type(result->get_type())) {
1041 result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
1042 }
1043 }
1044
1045 DT_RETURN_MARK_DECL(AllocObject, jobject
1046 , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
1047
1048 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
1049 JNIWrapper("AllocObject");
1050
1051 HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
1052
1053 jobject ret = NULL;
1054 DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
1055
1056 instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
1057 ret = JNIHandles::make_local(env, i);
1058 return ret;
1059 JNI_END
1060
1061 DT_RETURN_MARK_DECL(NewObjectA, jobject
1062 , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
1063
1064 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
1065 JNIWrapper("NewObjectA");
1066
1067 HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
1068
1069 jobject obj = NULL;
1070 DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj);
1071
1072 instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
1073 obj = JNIHandles::make_local(env, i);
1074 JavaValue jvalue(T_VOID);
1075 JNI_ArgumentPusherArray ap(methodID, args);
1076 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1077 return obj;
1078 JNI_END
1079
1080
1081 DT_RETURN_MARK_DECL(NewObjectV, jobject
1082 , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
1083
1084 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
1085 JNIWrapper("NewObjectV");
1086
1087 HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
1088
1089 jobject obj = NULL;
1090 DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
1091
1092 instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
1093 obj = JNIHandles::make_local(env, i);
1094 JavaValue jvalue(T_VOID);
1095 JNI_ArgumentPusherVaArg ap(methodID, args);
1096 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1097 return obj;
1098 JNI_END
1099
1100
1101 DT_RETURN_MARK_DECL(NewObject, jobject
1102 , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1103
1104 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1105 JNIWrapper("NewObject");
1106
1107 HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1108
1109 jobject obj = NULL;
1110 DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1111
1112 instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
1113 obj = JNIHandles::make_local(env, i);
1114 va_list args;
1115 va_start(args, methodID);
1116 JavaValue jvalue(T_VOID);
1117 JNI_ArgumentPusherVaArg ap(methodID, args);
1118 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1119 va_end(args);
1120 return obj;
1121 JNI_END
1122
1123
1124 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
1125 JNIWrapper("GetObjectClass");
1126
1127 HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(env, obj);
1128
1129 Klass* k = JNIHandles::resolve_non_null(obj)->klass();
1130 jclass ret =
1131 (jclass) JNIHandles::make_local(env, k->java_mirror());
1132
1133 HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
1134 return ret;
1135 JNI_END
1136
1137 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
1138 JNIWrapper("IsInstanceOf");
1139
1140 HOTSPOT_JNI_ISINSTANCEOF_ENTRY(env, obj, clazz);
1141
1142 jboolean ret = JNI_TRUE;
1143 if (obj != NULL) {
1144 ret = JNI_FALSE;
1145 Klass* k = java_lang_Class::as_Klass(
1146 JNIHandles::resolve_non_null(clazz));
1147 if (k != NULL) {
1148 ret = JNIHandles::resolve_non_null(obj)->is_a(k) ? JNI_TRUE : JNI_FALSE;
1149 }
1150 }
1151
1152 HOTSPOT_JNI_ISINSTANCEOF_RETURN(ret);
1153 return ret;
1154 JNI_END
1155
1156
get_method_id(JNIEnv * env,jclass clazz,const char * name_str,const char * sig,bool is_static,TRAPS)1157 static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str,
1158 const char *sig, bool is_static, TRAPS) {
1159 // %%%% This code should probably just call into a method in the LinkResolver
1160 //
1161 // The class should have been loaded (we have an instance of the class
1162 // passed in) so the method and signature should already be in the symbol
1163 // table. If they're not there, the method doesn't exist.
1164 const char *name_to_probe = (name_str == NULL)
1165 ? vmSymbols::object_initializer_name()->as_C_string()
1166 : name_str;
1167 TempNewSymbol name = SymbolTable::probe(name_to_probe, (int)strlen(name_to_probe));
1168 TempNewSymbol signature = SymbolTable::probe(sig, (int)strlen(sig));
1169
1170 if (name == NULL || signature == NULL) {
1171 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
1172 }
1173
1174 Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
1175
1176 // Throw a NoSuchMethodError exception if we have an instance of a
1177 // primitive java.lang.Class
1178 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) {
1179 ResourceMark rm;
1180 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), err_msg("%s%s.%s%s", is_static ? "static " : "", klass->signature_name(), name_str, sig));
1181 }
1182
1183 // Make sure class is linked and initialized before handing id's out to
1184 // Method*s.
1185 klass->initialize(CHECK_NULL);
1186
1187 Method* m;
1188 if (name == vmSymbols::object_initializer_name() ||
1189 name == vmSymbols::class_initializer_name()) {
1190 // Never search superclasses for constructors
1191 if (klass->is_instance_klass()) {
1192 m = InstanceKlass::cast(klass)->find_method(name, signature);
1193 } else {
1194 m = NULL;
1195 }
1196 } else {
1197 m = klass->lookup_method(name, signature);
1198 if (m == NULL && klass->is_instance_klass()) {
1199 m = InstanceKlass::cast(klass)->lookup_method_in_ordered_interfaces(name, signature);
1200 }
1201 }
1202 if (m == NULL || (m->is_static() != is_static)) {
1203 ResourceMark rm;
1204 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), err_msg("%s%s.%s%s", is_static ? "static " : "", klass->signature_name(), name_str, sig));
1205 }
1206 return m->jmethod_id();
1207 }
1208
1209
1210 JNI_ENTRY(jmethodID, jni_GetMethodID(JNIEnv *env, jclass clazz,
1211 const char *name, const char *sig))
1212 JNIWrapper("GetMethodID");
1213 HOTSPOT_JNI_GETMETHODID_ENTRY(env, clazz, (char *) name, (char *) sig);
1214 jmethodID ret = get_method_id(env, clazz, name, sig, false, thread);
1215 HOTSPOT_JNI_GETMETHODID_RETURN((uintptr_t) ret);
1216 return ret;
1217 JNI_END
1218
1219
1220 JNI_ENTRY(jmethodID, jni_GetStaticMethodID(JNIEnv *env, jclass clazz,
1221 const char *name, const char *sig))
1222 JNIWrapper("GetStaticMethodID");
1223 HOTSPOT_JNI_GETSTATICMETHODID_ENTRY(env, (char *) clazz, (char *) name, (char *)sig);
1224 jmethodID ret = get_method_id(env, clazz, name, sig, true, thread);
1225 HOTSPOT_JNI_GETSTATICMETHODID_RETURN((uintptr_t) ret);
1226 return ret;
1227 JNI_END
1228
1229
1230
1231 //
1232 // Calling Methods
1233 //
1234
1235
1236 #define DEFINE_CALLMETHOD(ResultType, Result, Tag \
1237 , EntryProbe, ReturnProbe) \
1238 \
1239 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType \
1240 , ReturnProbe); \
1241 \
1242 JNI_ENTRY(ResultType, \
1243 jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \
1244 JNIWrapper("Call" XSTR(Result) "Method"); \
1245 \
1246 EntryProbe; \
1247 ResultType ret = 0;\
1248 DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \
1249 (const ResultType&)ret);\
1250 \
1251 va_list args; \
1252 va_start(args, methodID); \
1253 JavaValue jvalue(Tag); \
1254 JNI_ArgumentPusherVaArg ap(methodID, args); \
1255 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1256 va_end(args); \
1257 ret = jvalue.get_##ResultType(); \
1258 return ret;\
1259 JNI_END
1260
1261 // the runtime type of subword integral basic types is integer
1262 DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN
1263 , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1264 HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
1265 DEFINE_CALLMETHOD(jbyte, Byte, T_BYTE
1266 , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1267 HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
1268 DEFINE_CALLMETHOD(jchar, Char, T_CHAR
1269 , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1270 HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
1271 DEFINE_CALLMETHOD(jshort, Short, T_SHORT
1272 , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1273 HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
1274
1275 DEFINE_CALLMETHOD(jobject, Object, T_OBJECT
1276 , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1277 HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
1278 DEFINE_CALLMETHOD(jint, Int, T_INT,
1279 HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1280 HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
1281 DEFINE_CALLMETHOD(jlong, Long, T_LONG
1282 , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1283 HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
1284 // Float and double probes don't return value because dtrace doesn't currently support it
1285 DEFINE_CALLMETHOD(jfloat, Float, T_FLOAT
1286 , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1287 HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
1288 DEFINE_CALLMETHOD(jdouble, Double, T_DOUBLE
1289 , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1290 HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
1291
1292 #define DEFINE_CALLMETHODV(ResultType, Result, Tag \
1293 , EntryProbe, ReturnProbe) \
1294 \
1295 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType \
1296 , ReturnProbe); \
1297 \
1298 JNI_ENTRY(ResultType, \
1299 jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \
1300 JNIWrapper("Call" XSTR(Result) "MethodV"); \
1301 \
1302 EntryProbe;\
1303 ResultType ret = 0;\
1304 DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \
1305 (const ResultType&)ret);\
1306 \
1307 JavaValue jvalue(Tag); \
1308 JNI_ArgumentPusherVaArg ap(methodID, args); \
1309 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1310 ret = jvalue.get_##ResultType(); \
1311 return ret;\
1312 JNI_END
1313
1314 // the runtime type of subword integral basic types is integer
1315 DEFINE_CALLMETHODV(jboolean, Boolean, T_BOOLEAN
1316 , HOTSPOT_JNI_CALLBOOLEANMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1317 HOTSPOT_JNI_CALLBOOLEANMETHODV_RETURN(_ret_ref))
1318 DEFINE_CALLMETHODV(jbyte, Byte, T_BYTE
1319 , HOTSPOT_JNI_CALLBYTEMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1320 HOTSPOT_JNI_CALLBYTEMETHODV_RETURN(_ret_ref))
1321 DEFINE_CALLMETHODV(jchar, Char, T_CHAR
1322 , HOTSPOT_JNI_CALLCHARMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1323 HOTSPOT_JNI_CALLCHARMETHODV_RETURN(_ret_ref))
1324 DEFINE_CALLMETHODV(jshort, Short, T_SHORT
1325 , HOTSPOT_JNI_CALLSHORTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1326 HOTSPOT_JNI_CALLSHORTMETHODV_RETURN(_ret_ref))
1327
1328 DEFINE_CALLMETHODV(jobject, Object, T_OBJECT
1329 , HOTSPOT_JNI_CALLOBJECTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1330 HOTSPOT_JNI_CALLOBJECTMETHODV_RETURN(_ret_ref))
1331 DEFINE_CALLMETHODV(jint, Int, T_INT,
1332 HOTSPOT_JNI_CALLINTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1333 HOTSPOT_JNI_CALLINTMETHODV_RETURN(_ret_ref))
1334 DEFINE_CALLMETHODV(jlong, Long, T_LONG
1335 , HOTSPOT_JNI_CALLLONGMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1336 HOTSPOT_JNI_CALLLONGMETHODV_RETURN(_ret_ref))
1337 // Float and double probes don't return value because dtrace doesn't currently support it
1338 DEFINE_CALLMETHODV(jfloat, Float, T_FLOAT
1339 , HOTSPOT_JNI_CALLFLOATMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1340 HOTSPOT_JNI_CALLFLOATMETHODV_RETURN())
1341 DEFINE_CALLMETHODV(jdouble, Double, T_DOUBLE
1342 , HOTSPOT_JNI_CALLDOUBLEMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1343 HOTSPOT_JNI_CALLDOUBLEMETHODV_RETURN())
1344
1345 #define DEFINE_CALLMETHODA(ResultType, Result, Tag \
1346 , EntryProbe, ReturnProbe) \
1347 \
1348 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType \
1349 , ReturnProbe); \
1350 \
1351 JNI_ENTRY(ResultType, \
1352 jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \
1353 JNIWrapper("Call" XSTR(Result) "MethodA"); \
1354 EntryProbe; \
1355 ResultType ret = 0;\
1356 DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \
1357 (const ResultType&)ret);\
1358 \
1359 JavaValue jvalue(Tag); \
1360 JNI_ArgumentPusherArray ap(methodID, args); \
1361 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1362 ret = jvalue.get_##ResultType(); \
1363 return ret;\
1364 JNI_END
1365
1366 // the runtime type of subword integral basic types is integer
1367 DEFINE_CALLMETHODA(jboolean, Boolean, T_BOOLEAN
1368 , HOTSPOT_JNI_CALLBOOLEANMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1369 HOTSPOT_JNI_CALLBOOLEANMETHODA_RETURN(_ret_ref))
1370 DEFINE_CALLMETHODA(jbyte, Byte, T_BYTE
1371 , HOTSPOT_JNI_CALLBYTEMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1372 HOTSPOT_JNI_CALLBYTEMETHODA_RETURN(_ret_ref))
1373 DEFINE_CALLMETHODA(jchar, Char, T_CHAR
1374 , HOTSPOT_JNI_CALLCHARMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1375 HOTSPOT_JNI_CALLCHARMETHODA_RETURN(_ret_ref))
1376 DEFINE_CALLMETHODA(jshort, Short, T_SHORT
1377 , HOTSPOT_JNI_CALLSHORTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1378 HOTSPOT_JNI_CALLSHORTMETHODA_RETURN(_ret_ref))
1379
1380 DEFINE_CALLMETHODA(jobject, Object, T_OBJECT
1381 , HOTSPOT_JNI_CALLOBJECTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1382 HOTSPOT_JNI_CALLOBJECTMETHODA_RETURN(_ret_ref))
1383 DEFINE_CALLMETHODA(jint, Int, T_INT,
1384 HOTSPOT_JNI_CALLINTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1385 HOTSPOT_JNI_CALLINTMETHODA_RETURN(_ret_ref))
1386 DEFINE_CALLMETHODA(jlong, Long, T_LONG
1387 , HOTSPOT_JNI_CALLLONGMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1388 HOTSPOT_JNI_CALLLONGMETHODA_RETURN(_ret_ref))
1389 // Float and double probes don't return value because dtrace doesn't currently support it
1390 DEFINE_CALLMETHODA(jfloat, Float, T_FLOAT
1391 , HOTSPOT_JNI_CALLFLOATMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1392 HOTSPOT_JNI_CALLFLOATMETHODA_RETURN())
1393 DEFINE_CALLMETHODA(jdouble, Double, T_DOUBLE
1394 , HOTSPOT_JNI_CALLDOUBLEMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1395 HOTSPOT_JNI_CALLDOUBLEMETHODA_RETURN())
1396
1397 DT_VOID_RETURN_MARK_DECL(CallVoidMethod, HOTSPOT_JNI_CALLVOIDMETHOD_RETURN());
1398 DT_VOID_RETURN_MARK_DECL(CallVoidMethodV, HOTSPOT_JNI_CALLVOIDMETHODV_RETURN());
1399 DT_VOID_RETURN_MARK_DECL(CallVoidMethodA, HOTSPOT_JNI_CALLVOIDMETHODA_RETURN());
1400
1401
1402 JNI_ENTRY(void, jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...))
1403 JNIWrapper("CallVoidMethod");
1404 HOTSPOT_JNI_CALLVOIDMETHOD_ENTRY(env, obj, (uintptr_t) methodID);
1405 DT_VOID_RETURN_MARK(CallVoidMethod);
1406
1407 va_list args;
1408 va_start(args, methodID);
1409 JavaValue jvalue(T_VOID);
1410 JNI_ArgumentPusherVaArg ap(methodID, args);
1411 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1412 va_end(args);
1413 JNI_END
1414
1415
1416 JNI_ENTRY(void, jni_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args))
1417 JNIWrapper("CallVoidMethodV");
1418 HOTSPOT_JNI_CALLVOIDMETHODV_ENTRY(env, obj, (uintptr_t) methodID);
1419 DT_VOID_RETURN_MARK(CallVoidMethodV);
1420
1421 JavaValue jvalue(T_VOID);
1422 JNI_ArgumentPusherVaArg ap(methodID, args);
1423 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1424 JNI_END
1425
1426
1427 JNI_ENTRY(void, jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args))
1428 JNIWrapper("CallVoidMethodA");
1429 HOTSPOT_JNI_CALLVOIDMETHODA_ENTRY(env, obj, (uintptr_t) methodID);
1430 DT_VOID_RETURN_MARK(CallVoidMethodA);
1431
1432 JavaValue jvalue(T_VOID);
1433 JNI_ArgumentPusherArray ap(methodID, args);
1434 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1435 JNI_END
1436
1437
1438
1439 #define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag \
1440 , EntryProbe, ReturnProbe) \
1441 \
1442 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType \
1443 , ReturnProbe);\
1444 \
1445 JNI_ENTRY(ResultType, \
1446 jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \
1447 JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \
1448 \
1449 EntryProbe;\
1450 ResultType ret;\
1451 DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \
1452 (const ResultType&)ret);\
1453 \
1454 va_list args; \
1455 va_start(args, methodID); \
1456 JavaValue jvalue(Tag); \
1457 JNI_ArgumentPusherVaArg ap(methodID, args); \
1458 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
1459 va_end(args); \
1460 ret = jvalue.get_##ResultType(); \
1461 return ret;\
1462 JNI_END
1463
1464 // the runtime type of subword integral basic types is integer
1465 DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN
1466 , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1467 HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_RETURN(_ret_ref))
1468 DEFINE_CALLNONVIRTUALMETHOD(jbyte, Byte, T_BYTE
1469 , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1470 HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_RETURN(_ret_ref))
1471 DEFINE_CALLNONVIRTUALMETHOD(jchar, Char, T_CHAR
1472 , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1473 HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_RETURN(_ret_ref))
1474 DEFINE_CALLNONVIRTUALMETHOD(jshort, Short, T_SHORT
1475 , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1476 HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_RETURN(_ret_ref))
1477
1478 DEFINE_CALLNONVIRTUALMETHOD(jobject, Object, T_OBJECT
1479 , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1480 HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_RETURN(_ret_ref))
1481 DEFINE_CALLNONVIRTUALMETHOD(jint, Int, T_INT
1482 , HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1483 HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_RETURN(_ret_ref))
1484 DEFINE_CALLNONVIRTUALMETHOD(jlong, Long, T_LONG
1485 , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1486 // Float and double probes don't return value because dtrace doesn't currently support it
1487 HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_RETURN(_ret_ref))
1488 DEFINE_CALLNONVIRTUALMETHOD(jfloat, Float, T_FLOAT
1489 , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1490 HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_RETURN())
1491 DEFINE_CALLNONVIRTUALMETHOD(jdouble, Double, T_DOUBLE
1492 , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1493 HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_RETURN())
1494
1495 #define DEFINE_CALLNONVIRTUALMETHODV(ResultType, Result, Tag \
1496 , EntryProbe, ReturnProbe) \
1497 \
1498 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType \
1499 , ReturnProbe);\
1500 \
1501 JNI_ENTRY(ResultType, \
1502 jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \
1503 JNIWrapper("CallNonvitual" XSTR(Result) "MethodV"); \
1504 \
1505 EntryProbe;\
1506 ResultType ret;\
1507 DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \
1508 (const ResultType&)ret);\
1509 \
1510 JavaValue jvalue(Tag); \
1511 JNI_ArgumentPusherVaArg ap(methodID, args); \
1512 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
1513 ret = jvalue.get_##ResultType(); \
1514 return ret;\
1515 JNI_END
1516
1517 // the runtime type of subword integral basic types is integer
1518 DEFINE_CALLNONVIRTUALMETHODV(jboolean, Boolean, T_BOOLEAN
1519 , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1520 HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_RETURN(_ret_ref))
1521 DEFINE_CALLNONVIRTUALMETHODV(jbyte, Byte, T_BYTE
1522 , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1523 HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_RETURN(_ret_ref))
1524 DEFINE_CALLNONVIRTUALMETHODV(jchar, Char, T_CHAR
1525 , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1526 HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_RETURN(_ret_ref))
1527 DEFINE_CALLNONVIRTUALMETHODV(jshort, Short, T_SHORT
1528 , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1529 HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_RETURN(_ret_ref))
1530
1531 DEFINE_CALLNONVIRTUALMETHODV(jobject, Object, T_OBJECT
1532 , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1533 HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_RETURN(_ret_ref))
1534 DEFINE_CALLNONVIRTUALMETHODV(jint, Int, T_INT
1535 , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1536 HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_RETURN(_ret_ref))
1537 DEFINE_CALLNONVIRTUALMETHODV(jlong, Long, T_LONG
1538 , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1539 // Float and double probes don't return value because dtrace doesn't currently support it
1540 HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_RETURN(_ret_ref))
1541 DEFINE_CALLNONVIRTUALMETHODV(jfloat, Float, T_FLOAT
1542 , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1543 HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_RETURN())
1544 DEFINE_CALLNONVIRTUALMETHODV(jdouble, Double, T_DOUBLE
1545 , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1546 HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_RETURN())
1547
1548 #define DEFINE_CALLNONVIRTUALMETHODA(ResultType, Result, Tag \
1549 , EntryProbe, ReturnProbe) \
1550 \
1551 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType \
1552 , ReturnProbe);\
1553 \
1554 JNI_ENTRY(ResultType, \
1555 jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \
1556 JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \
1557 \
1558 EntryProbe;\
1559 ResultType ret;\
1560 DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \
1561 (const ResultType&)ret);\
1562 \
1563 JavaValue jvalue(Tag); \
1564 JNI_ArgumentPusherArray ap(methodID, args); \
1565 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
1566 ret = jvalue.get_##ResultType(); \
1567 return ret;\
1568 JNI_END
1569
1570 // the runtime type of subword integral basic types is integer
1571 DEFINE_CALLNONVIRTUALMETHODA(jboolean, Boolean, T_BOOLEAN
1572 , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1573 HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_RETURN(_ret_ref))
1574 DEFINE_CALLNONVIRTUALMETHODA(jbyte, Byte, T_BYTE
1575 , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1576 HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_RETURN(_ret_ref))
1577 DEFINE_CALLNONVIRTUALMETHODA(jchar, Char, T_CHAR
1578 , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1579 HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_RETURN(_ret_ref))
1580 DEFINE_CALLNONVIRTUALMETHODA(jshort, Short, T_SHORT
1581 , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1582 HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_RETURN(_ret_ref))
1583
1584 DEFINE_CALLNONVIRTUALMETHODA(jobject, Object, T_OBJECT
1585 , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1586 HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_RETURN(_ret_ref))
1587 DEFINE_CALLNONVIRTUALMETHODA(jint, Int, T_INT
1588 , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1589 HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_RETURN(_ret_ref))
1590 DEFINE_CALLNONVIRTUALMETHODA(jlong, Long, T_LONG
1591 , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1592 // Float and double probes don't return value because dtrace doesn't currently support it
1593 HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_RETURN(_ret_ref))
1594 DEFINE_CALLNONVIRTUALMETHODA(jfloat, Float, T_FLOAT
1595 , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1596 HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_RETURN())
1597 DEFINE_CALLNONVIRTUALMETHODA(jdouble, Double, T_DOUBLE
1598 , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1599 HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_RETURN())
1600
1601 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod
1602 , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_RETURN());
1603 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV
1604 , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_RETURN());
1605 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA
1606 , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_RETURN());
1607
1608 JNI_ENTRY(void, jni_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...))
1609 JNIWrapper("CallNonvirtualVoidMethod");
1610
1611 HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_ENTRY(env, obj, cls, (uintptr_t) methodID);
1612 DT_VOID_RETURN_MARK(CallNonvirtualVoidMethod);
1613
1614 va_list args;
1615 va_start(args, methodID);
1616 JavaValue jvalue(T_VOID);
1617 JNI_ArgumentPusherVaArg ap(methodID, args);
1618 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
1619 va_end(args);
1620 JNI_END
1621
1622
1623 JNI_ENTRY(void, jni_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args))
1624 JNIWrapper("CallNonvirtualVoidMethodV");
1625
1626 HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_ENTRY(
1627 env, obj, cls, (uintptr_t) methodID);
1628 DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodV);
1629
1630 JavaValue jvalue(T_VOID);
1631 JNI_ArgumentPusherVaArg ap(methodID, args);
1632 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
1633 JNI_END
1634
1635
1636 JNI_ENTRY(void, jni_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args))
1637 JNIWrapper("CallNonvirtualVoidMethodA");
1638 HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_ENTRY(
1639 env, obj, cls, (uintptr_t) methodID);
1640 DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodA);
1641 JavaValue jvalue(T_VOID);
1642 JNI_ArgumentPusherArray ap(methodID, args);
1643 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
1644 JNI_END
1645
1646
1647
1648 #define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag \
1649 , EntryProbe, ResultProbe) \
1650 \
1651 DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType \
1652 , ResultProbe); \
1653 \
1654 JNI_ENTRY(ResultType, \
1655 jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \
1656 JNIWrapper("CallStatic" XSTR(Result) "Method"); \
1657 \
1658 EntryProbe; \
1659 ResultType ret = 0;\
1660 DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \
1661 (const ResultType&)ret);\
1662 \
1663 va_list args; \
1664 va_start(args, methodID); \
1665 JavaValue jvalue(Tag); \
1666 JNI_ArgumentPusherVaArg ap(methodID, args); \
1667 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
1668 va_end(args); \
1669 ret = jvalue.get_##ResultType(); \
1670 return ret;\
1671 JNI_END
1672
1673 // the runtime type of subword integral basic types is integer
1674 DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN
1675 , HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1676 HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_RETURN(_ret_ref));
1677 DEFINE_CALLSTATICMETHOD(jbyte, Byte, T_BYTE
1678 , HOTSPOT_JNI_CALLSTATICBYTEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1679 HOTSPOT_JNI_CALLSTATICBYTEMETHOD_RETURN(_ret_ref));
1680 DEFINE_CALLSTATICMETHOD(jchar, Char, T_CHAR
1681 , HOTSPOT_JNI_CALLSTATICCHARMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1682 HOTSPOT_JNI_CALLSTATICCHARMETHOD_RETURN(_ret_ref));
1683 DEFINE_CALLSTATICMETHOD(jshort, Short, T_SHORT
1684 , HOTSPOT_JNI_CALLSTATICSHORTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1685 HOTSPOT_JNI_CALLSTATICSHORTMETHOD_RETURN(_ret_ref));
1686
1687 DEFINE_CALLSTATICMETHOD(jobject, Object, T_OBJECT
1688 , HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1689 HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_RETURN(_ret_ref));
1690 DEFINE_CALLSTATICMETHOD(jint, Int, T_INT
1691 , HOTSPOT_JNI_CALLSTATICINTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1692 HOTSPOT_JNI_CALLSTATICINTMETHOD_RETURN(_ret_ref));
1693 DEFINE_CALLSTATICMETHOD(jlong, Long, T_LONG
1694 , HOTSPOT_JNI_CALLSTATICLONGMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1695 HOTSPOT_JNI_CALLSTATICLONGMETHOD_RETURN(_ret_ref));
1696 // Float and double probes don't return value because dtrace doesn't currently support it
1697 DEFINE_CALLSTATICMETHOD(jfloat, Float, T_FLOAT
1698 , HOTSPOT_JNI_CALLSTATICFLOATMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1699 HOTSPOT_JNI_CALLSTATICFLOATMETHOD_RETURN());
1700 DEFINE_CALLSTATICMETHOD(jdouble, Double, T_DOUBLE
1701 , HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1702 HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_RETURN());
1703
1704 #define DEFINE_CALLSTATICMETHODV(ResultType, Result, Tag \
1705 , EntryProbe, ResultProbe) \
1706 \
1707 DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType \
1708 , ResultProbe); \
1709 \
1710 JNI_ENTRY(ResultType, \
1711 jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \
1712 JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \
1713 \
1714 EntryProbe; \
1715 ResultType ret = 0;\
1716 DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \
1717 (const ResultType&)ret);\
1718 \
1719 JavaValue jvalue(Tag); \
1720 JNI_ArgumentPusherVaArg ap(methodID, args); \
1721 /* Make sure class is initialized before trying to invoke its method */ \
1722 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); \
1723 k->initialize(CHECK_0); \
1724 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
1725 va_end(args); \
1726 ret = jvalue.get_##ResultType(); \
1727 return ret;\
1728 JNI_END
1729
1730 // the runtime type of subword integral basic types is integer
1731 DEFINE_CALLSTATICMETHODV(jboolean, Boolean, T_BOOLEAN
1732 , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1733 HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_RETURN(_ret_ref));
1734 DEFINE_CALLSTATICMETHODV(jbyte, Byte, T_BYTE
1735 , HOTSPOT_JNI_CALLSTATICBYTEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1736 HOTSPOT_JNI_CALLSTATICBYTEMETHODV_RETURN(_ret_ref));
1737 DEFINE_CALLSTATICMETHODV(jchar, Char, T_CHAR
1738 , HOTSPOT_JNI_CALLSTATICCHARMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1739 HOTSPOT_JNI_CALLSTATICCHARMETHODV_RETURN(_ret_ref));
1740 DEFINE_CALLSTATICMETHODV(jshort, Short, T_SHORT
1741 , HOTSPOT_JNI_CALLSTATICSHORTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1742 HOTSPOT_JNI_CALLSTATICSHORTMETHODV_RETURN(_ret_ref));
1743
1744 DEFINE_CALLSTATICMETHODV(jobject, Object, T_OBJECT
1745 , HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1746 HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_RETURN(_ret_ref));
1747 DEFINE_CALLSTATICMETHODV(jint, Int, T_INT
1748 , HOTSPOT_JNI_CALLSTATICINTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1749 HOTSPOT_JNI_CALLSTATICINTMETHODV_RETURN(_ret_ref));
1750 DEFINE_CALLSTATICMETHODV(jlong, Long, T_LONG
1751 , HOTSPOT_JNI_CALLSTATICLONGMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1752 HOTSPOT_JNI_CALLSTATICLONGMETHODV_RETURN(_ret_ref));
1753 // Float and double probes don't return value because dtrace doesn't currently support it
1754 DEFINE_CALLSTATICMETHODV(jfloat, Float, T_FLOAT
1755 , HOTSPOT_JNI_CALLSTATICFLOATMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1756 HOTSPOT_JNI_CALLSTATICFLOATMETHODV_RETURN());
1757 DEFINE_CALLSTATICMETHODV(jdouble, Double, T_DOUBLE
1758 , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1759 HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_RETURN());
1760
1761 #define DEFINE_CALLSTATICMETHODA(ResultType, Result, Tag \
1762 , EntryProbe, ResultProbe) \
1763 \
1764 DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType \
1765 , ResultProbe); \
1766 \
1767 JNI_ENTRY(ResultType, \
1768 jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \
1769 JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \
1770 \
1771 EntryProbe; \
1772 ResultType ret = 0;\
1773 DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \
1774 (const ResultType&)ret);\
1775 \
1776 JavaValue jvalue(Tag); \
1777 JNI_ArgumentPusherArray ap(methodID, args); \
1778 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
1779 ret = jvalue.get_##ResultType(); \
1780 return ret;\
1781 JNI_END
1782
1783 // the runtime type of subword integral basic types is integer
1784 DEFINE_CALLSTATICMETHODA(jboolean, Boolean, T_BOOLEAN
1785 , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1786 HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_RETURN(_ret_ref));
1787 DEFINE_CALLSTATICMETHODA(jbyte, Byte, T_BYTE
1788 , HOTSPOT_JNI_CALLSTATICBYTEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1789 HOTSPOT_JNI_CALLSTATICBYTEMETHODA_RETURN(_ret_ref));
1790 DEFINE_CALLSTATICMETHODA(jchar, Char, T_CHAR
1791 , HOTSPOT_JNI_CALLSTATICCHARMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1792 HOTSPOT_JNI_CALLSTATICCHARMETHODA_RETURN(_ret_ref));
1793 DEFINE_CALLSTATICMETHODA(jshort, Short, T_SHORT
1794 , HOTSPOT_JNI_CALLSTATICSHORTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1795 HOTSPOT_JNI_CALLSTATICSHORTMETHODA_RETURN(_ret_ref));
1796
1797 DEFINE_CALLSTATICMETHODA(jobject, Object, T_OBJECT
1798 , HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1799 HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_RETURN(_ret_ref));
1800 DEFINE_CALLSTATICMETHODA(jint, Int, T_INT
1801 , HOTSPOT_JNI_CALLSTATICINTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1802 HOTSPOT_JNI_CALLSTATICINTMETHODA_RETURN(_ret_ref));
1803 DEFINE_CALLSTATICMETHODA(jlong, Long, T_LONG
1804 , HOTSPOT_JNI_CALLSTATICLONGMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1805 HOTSPOT_JNI_CALLSTATICLONGMETHODA_RETURN(_ret_ref));
1806 // Float and double probes don't return value because dtrace doesn't currently support it
1807 DEFINE_CALLSTATICMETHODA(jfloat, Float, T_FLOAT
1808 , HOTSPOT_JNI_CALLSTATICFLOATMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1809 HOTSPOT_JNI_CALLSTATICFLOATMETHODA_RETURN());
1810 DEFINE_CALLSTATICMETHODA(jdouble, Double, T_DOUBLE
1811 , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1812 HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_RETURN());
1813
1814 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod
1815 , HOTSPOT_JNI_CALLSTATICVOIDMETHOD_RETURN());
1816 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV
1817 , HOTSPOT_JNI_CALLSTATICVOIDMETHODV_RETURN());
1818 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA
1819 , HOTSPOT_JNI_CALLSTATICVOIDMETHODA_RETURN());
1820
1821 JNI_ENTRY(void, jni_CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...))
1822 JNIWrapper("CallStaticVoidMethod");
1823 HOTSPOT_JNI_CALLSTATICVOIDMETHOD_ENTRY(env, cls, (uintptr_t) methodID);
1824 DT_VOID_RETURN_MARK(CallStaticVoidMethod);
1825
1826 va_list args;
1827 va_start(args, methodID);
1828 JavaValue jvalue(T_VOID);
1829 JNI_ArgumentPusherVaArg ap(methodID, args);
1830 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
1831 va_end(args);
1832 JNI_END
1833
1834
1835 JNI_ENTRY(void, jni_CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args))
1836 JNIWrapper("CallStaticVoidMethodV");
1837 HOTSPOT_JNI_CALLSTATICVOIDMETHODV_ENTRY(env, cls, (uintptr_t) methodID);
1838 DT_VOID_RETURN_MARK(CallStaticVoidMethodV);
1839
1840 JavaValue jvalue(T_VOID);
1841 JNI_ArgumentPusherVaArg ap(methodID, args);
1842 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
1843 JNI_END
1844
1845
1846 JNI_ENTRY(void, jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args))
1847 JNIWrapper("CallStaticVoidMethodA");
1848 HOTSPOT_JNI_CALLSTATICVOIDMETHODA_ENTRY(env, cls, (uintptr_t) methodID);
1849 DT_VOID_RETURN_MARK(CallStaticVoidMethodA);
1850
1851 JavaValue jvalue(T_VOID);
1852 JNI_ArgumentPusherArray ap(methodID, args);
1853 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
1854 JNI_END
1855
1856
1857 //
1858 // Accessing Fields
1859 //
1860
1861
1862 DT_RETURN_MARK_DECL(GetFieldID, jfieldID
1863 , HOTSPOT_JNI_GETFIELDID_RETURN((uintptr_t)_ret_ref));
1864
1865 JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz,
1866 const char *name, const char *sig))
1867 JNIWrapper("GetFieldID");
1868 HOTSPOT_JNI_GETFIELDID_ENTRY(env, clazz, (char *) name, (char *) sig);
1869 jfieldID ret = 0;
1870 DT_RETURN_MARK(GetFieldID, jfieldID, (const jfieldID&)ret);
1871
1872 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
1873
1874 // The class should have been loaded (we have an instance of the class
1875 // passed in) so the field and signature should already be in the symbol
1876 // table. If they're not there, the field doesn't exist.
1877 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
1878 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
1879 if (fieldname == NULL || signame == NULL) {
1880 ResourceMark rm;
1881 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1882 }
1883
1884 // Make sure class is initialized before handing id's out to fields
1885 k->initialize(CHECK_NULL);
1886
1887 fieldDescriptor fd;
1888 if (!k->is_instance_klass() ||
1889 !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
1890 ResourceMark rm;
1891 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1892 }
1893
1894 // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
1895 // It may also have hash bits for k, if VerifyJNIFields is turned on.
1896 ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset());
1897 return ret;
1898 JNI_END
1899
1900
1901 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
1902 JNIWrapper("GetObjectField");
1903 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
1904 oop o = JNIHandles::resolve_non_null(obj);
1905 Klass* k = o->klass();
1906 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1907 // Keep JVMTI addition small and only check enabled flag here.
1908 // jni_GetField_probe() assumes that is okay to create handles.
1909 if (JvmtiExport::should_post_field_access()) {
1910 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
1911 }
1912 oop loaded_obj = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
1913 jobject ret = JNIHandles::make_local(env, loaded_obj);
1914 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
1915 return ret;
1916 JNI_END
1917
1918
1919
1920 #define DEFINE_GETFIELD(Return,Fieldname,Result \
1921 , EntryProbe, ReturnProbe) \
1922 \
1923 DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
1924 , ReturnProbe); \
1925 \
1926 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
1927 JNIWrapper("Get" XSTR(Result) "Field"); \
1928 \
1929 EntryProbe; \
1930 Return ret = 0;\
1931 DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
1932 \
1933 oop o = JNIHandles::resolve_non_null(obj); \
1934 Klass* k = o->klass(); \
1935 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
1936 /* Keep JVMTI addition small and only check enabled flag here. */ \
1937 /* jni_GetField_probe_nh() assumes that is not okay to create handles */ \
1938 /* and creates a ResetNoHandleMark. */ \
1939 if (JvmtiExport::should_post_field_access()) { \
1940 o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \
1941 } \
1942 ret = o->Fieldname##_field(offset); \
1943 return ret; \
1944 JNI_END
1945
1946 DEFINE_GETFIELD(jboolean, bool, Boolean
1947 , HOTSPOT_JNI_GETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
1948 HOTSPOT_JNI_GETBOOLEANFIELD_RETURN(_ret_ref))
1949 DEFINE_GETFIELD(jbyte, byte, Byte
1950 , HOTSPOT_JNI_GETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
1951 HOTSPOT_JNI_GETBYTEFIELD_RETURN(_ret_ref))
1952 DEFINE_GETFIELD(jchar, char, Char
1953 , HOTSPOT_JNI_GETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
1954 HOTSPOT_JNI_GETCHARFIELD_RETURN(_ret_ref))
1955 DEFINE_GETFIELD(jshort, short, Short
1956 , HOTSPOT_JNI_GETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
1957 HOTSPOT_JNI_GETSHORTFIELD_RETURN(_ret_ref))
1958 DEFINE_GETFIELD(jint, int, Int
1959 , HOTSPOT_JNI_GETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
1960 HOTSPOT_JNI_GETINTFIELD_RETURN(_ret_ref))
1961 DEFINE_GETFIELD(jlong, long, Long
1962 , HOTSPOT_JNI_GETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
1963 HOTSPOT_JNI_GETLONGFIELD_RETURN(_ret_ref))
1964 // Float and double probes don't return value because dtrace doesn't currently support it
1965 DEFINE_GETFIELD(jfloat, float, Float
1966 , HOTSPOT_JNI_GETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
1967 HOTSPOT_JNI_GETFLOATFIELD_RETURN())
1968 DEFINE_GETFIELD(jdouble, double, Double
1969 , HOTSPOT_JNI_GETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
1970 HOTSPOT_JNI_GETDOUBLEFIELD_RETURN())
1971
jni_GetBooleanField_addr()1972 address jni_GetBooleanField_addr() {
1973 return (address)jni_GetBooleanField;
1974 }
jni_GetByteField_addr()1975 address jni_GetByteField_addr() {
1976 return (address)jni_GetByteField;
1977 }
jni_GetCharField_addr()1978 address jni_GetCharField_addr() {
1979 return (address)jni_GetCharField;
1980 }
jni_GetShortField_addr()1981 address jni_GetShortField_addr() {
1982 return (address)jni_GetShortField;
1983 }
jni_GetIntField_addr()1984 address jni_GetIntField_addr() {
1985 return (address)jni_GetIntField;
1986 }
jni_GetLongField_addr()1987 address jni_GetLongField_addr() {
1988 return (address)jni_GetLongField;
1989 }
jni_GetFloatField_addr()1990 address jni_GetFloatField_addr() {
1991 return (address)jni_GetFloatField;
1992 }
jni_GetDoubleField_addr()1993 address jni_GetDoubleField_addr() {
1994 return (address)jni_GetDoubleField;
1995 }
1996
1997 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
1998 JNIWrapper("SetObjectField");
1999 HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
2000 oop o = JNIHandles::resolve_non_null(obj);
2001 Klass* k = o->klass();
2002 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2003 // Keep JVMTI addition small and only check enabled flag here.
2004 // jni_SetField_probe_nh() assumes that is not okay to create handles
2005 // and creates a ResetNoHandleMark.
2006 if (JvmtiExport::should_post_field_modification()) {
2007 jvalue field_value;
2008 field_value.l = value;
2009 o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
2010 }
2011 HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));
2012 HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
2013 JNI_END
2014
2015
2016 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
2017 , EntryProbe, ReturnProbe) \
2018 \
2019 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
2020 JNIWrapper("Set" XSTR(Result) "Field"); \
2021 \
2022 EntryProbe; \
2023 \
2024 oop o = JNIHandles::resolve_non_null(obj); \
2025 Klass* k = o->klass(); \
2026 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
2027 /* Keep JVMTI addition small and only check enabled flag here. */ \
2028 /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
2029 /* and creates a ResetNoHandleMark. */ \
2030 if (JvmtiExport::should_post_field_modification()) { \
2031 jvalue field_value; \
2032 field_value.unionType = value; \
2033 o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
2034 } \
2035 if (SigType == JVM_SIGNATURE_BOOLEAN) { value = ((jboolean)value) & 1; } \
2036 o->Fieldname##_field_put(offset, value); \
2037 ReturnProbe; \
2038 JNI_END
2039
2040 DEFINE_SETFIELD(jboolean, bool, Boolean, JVM_SIGNATURE_BOOLEAN, z
2041 , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2042 HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
2043 DEFINE_SETFIELD(jbyte, byte, Byte, JVM_SIGNATURE_BYTE, b
2044 , HOTSPOT_JNI_SETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2045 HOTSPOT_JNI_SETBYTEFIELD_RETURN())
2046 DEFINE_SETFIELD(jchar, char, Char, JVM_SIGNATURE_CHAR, c
2047 , HOTSPOT_JNI_SETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2048 HOTSPOT_JNI_SETCHARFIELD_RETURN())
2049 DEFINE_SETFIELD(jshort, short, Short, JVM_SIGNATURE_SHORT, s
2050 , HOTSPOT_JNI_SETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2051 HOTSPOT_JNI_SETSHORTFIELD_RETURN())
2052 DEFINE_SETFIELD(jint, int, Int, JVM_SIGNATURE_INT, i
2053 , HOTSPOT_JNI_SETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2054 HOTSPOT_JNI_SETINTFIELD_RETURN())
2055 DEFINE_SETFIELD(jlong, long, Long, JVM_SIGNATURE_LONG, j
2056 , HOTSPOT_JNI_SETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2057 HOTSPOT_JNI_SETLONGFIELD_RETURN())
2058 // Float and double probes don't return value because dtrace doesn't currently support it
2059 DEFINE_SETFIELD(jfloat, float, Float, JVM_SIGNATURE_FLOAT, f
2060 , HOTSPOT_JNI_SETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2061 HOTSPOT_JNI_SETFLOATFIELD_RETURN())
2062 DEFINE_SETFIELD(jdouble, double, Double, JVM_SIGNATURE_DOUBLE, d
2063 , HOTSPOT_JNI_SETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2064 HOTSPOT_JNI_SETDOUBLEFIELD_RETURN())
2065
2066 DT_RETURN_MARK_DECL(ToReflectedField, jobject
2067 , HOTSPOT_JNI_TOREFLECTEDFIELD_RETURN(_ret_ref));
2068
2069 JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic))
2070 JNIWrapper("ToReflectedField");
2071 HOTSPOT_JNI_TOREFLECTEDFIELD_ENTRY(env, cls, (uintptr_t) fieldID, isStatic);
2072 jobject ret = NULL;
2073 DT_RETURN_MARK(ToReflectedField, jobject, (const jobject&)ret);
2074
2075 fieldDescriptor fd;
2076 bool found = false;
2077 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
2078
2079 assert(jfieldIDWorkaround::is_static_jfieldID(fieldID) == (isStatic != 0), "invalid fieldID");
2080
2081 if (isStatic) {
2082 // Static field. The fieldID a JNIid specifying the field holder and the offset within the Klass*.
2083 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
2084 assert(id->is_static_field_id(), "invalid static field id");
2085 found = id->find_local_field(&fd);
2086 } else {
2087 // Non-static field. The fieldID is really the offset of the field within the instanceOop.
2088 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2089 found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, &fd);
2090 }
2091 assert(found, "bad fieldID passed into jni_ToReflectedField");
2092 oop reflected = Reflection::new_field(&fd, CHECK_NULL);
2093 ret = JNIHandles::make_local(env, reflected);
2094 return ret;
2095 JNI_END
2096
2097
2098 //
2099 // Accessing Static Fields
2100 //
2101 DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID
2102 , HOTSPOT_JNI_GETSTATICFIELDID_RETURN((uintptr_t)_ret_ref));
2103
2104 JNI_ENTRY(jfieldID, jni_GetStaticFieldID(JNIEnv *env, jclass clazz,
2105 const char *name, const char *sig))
2106 JNIWrapper("GetStaticFieldID");
2107 HOTSPOT_JNI_GETSTATICFIELDID_ENTRY(env, clazz, (char *) name, (char *) sig);
2108 jfieldID ret = NULL;
2109 DT_RETURN_MARK(GetStaticFieldID, jfieldID, (const jfieldID&)ret);
2110
2111 // The class should have been loaded (we have an instance of the class
2112 // passed in) so the field and signature should already be in the symbol
2113 // table. If they're not there, the field doesn't exist.
2114 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
2115 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
2116 if (fieldname == NULL || signame == NULL) {
2117 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2118 }
2119 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
2120 // Make sure class is initialized before handing id's out to static fields
2121 k->initialize(CHECK_NULL);
2122
2123 fieldDescriptor fd;
2124 if (!k->is_instance_klass() ||
2125 !InstanceKlass::cast(k)->find_field(fieldname, signame, true, &fd)) {
2126 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2127 }
2128
2129 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
2130 JNIid* id = fd.field_holder()->jni_id_for(fd.offset());
2131 debug_only(id->set_is_static_field_id();)
2132
2133 debug_only(id->verify(fd.field_holder()));
2134
2135 ret = jfieldIDWorkaround::to_static_jfieldID(id);
2136 return ret;
2137 JNI_END
2138
2139
2140 JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID))
2141 JNIWrapper("GetStaticObjectField");
2142 HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID);
2143 #if INCLUDE_JNI_CHECK
2144 DEBUG_ONLY(Klass* param_k = jniCheck::validate_class(thread, clazz);)
2145 #endif // INCLUDE_JNI_CHECK
2146 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
2147 assert(id->is_static_field_id(), "invalid static field id");
2148 // Keep JVMTI addition small and only check enabled flag here.
2149 // jni_GetField_probe() assumes that is okay to create handles.
2150 if (JvmtiExport::should_post_field_access()) {
2151 JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);
2152 }
2153 jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset()));
2154 HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN(ret);
2155 return ret;
2156 JNI_END
2157
2158
2159 #define DEFINE_GETSTATICFIELD(Return,Fieldname,Result \
2160 , EntryProbe, ReturnProbe) \
2161 \
2162 DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return \
2163 , ReturnProbe); \
2164 \
2165 JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \
2166 JNIWrapper("GetStatic" XSTR(Result) "Field"); \
2167 EntryProbe; \
2168 Return ret = 0;\
2169 DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \
2170 (const Return&)ret);\
2171 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
2172 assert(id->is_static_field_id(), "invalid static field id"); \
2173 /* Keep JVMTI addition small and only check enabled flag here. */ \
2174 /* jni_GetField_probe() assumes that is okay to create handles. */ \
2175 if (JvmtiExport::should_post_field_access()) { \
2176 JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \
2177 } \
2178 ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \
2179 return ret;\
2180 JNI_END
2181
2182 DEFINE_GETSTATICFIELD(jboolean, bool, Boolean
2183 , HOTSPOT_JNI_GETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBOOLEANFIELD_RETURN(_ret_ref))
2184 DEFINE_GETSTATICFIELD(jbyte, byte, Byte
2185 , HOTSPOT_JNI_GETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBYTEFIELD_RETURN(_ret_ref) )
2186 DEFINE_GETSTATICFIELD(jchar, char, Char
2187 , HOTSPOT_JNI_GETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICCHARFIELD_RETURN(_ret_ref) )
2188 DEFINE_GETSTATICFIELD(jshort, short, Short
2189 , HOTSPOT_JNI_GETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICSHORTFIELD_RETURN(_ret_ref) )
2190 DEFINE_GETSTATICFIELD(jint, int, Int
2191 , HOTSPOT_JNI_GETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICINTFIELD_RETURN(_ret_ref) )
2192 DEFINE_GETSTATICFIELD(jlong, long, Long
2193 , HOTSPOT_JNI_GETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICLONGFIELD_RETURN(_ret_ref) )
2194 // Float and double probes don't return value because dtrace doesn't currently support it
2195 DEFINE_GETSTATICFIELD(jfloat, float, Float
2196 , HOTSPOT_JNI_GETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICFLOATFIELD_RETURN() )
2197 DEFINE_GETSTATICFIELD(jdouble, double, Double
2198 , HOTSPOT_JNI_GETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICDOUBLEFIELD_RETURN() )
2199
2200 JNI_ENTRY(void, jni_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value))
2201 JNIWrapper("SetStaticObjectField");
2202 HOTSPOT_JNI_SETSTATICOBJECTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value);
2203 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
2204 assert(id->is_static_field_id(), "invalid static field id");
2205 // Keep JVMTI addition small and only check enabled flag here.
2206 // jni_SetField_probe() assumes that is okay to create handles.
2207 if (JvmtiExport::should_post_field_modification()) {
2208 jvalue field_value;
2209 field_value.l = value;
2210 JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
2211 }
2212 id->holder()->java_mirror()->obj_field_put(id->offset(), JNIHandles::resolve(value));
2213 HOTSPOT_JNI_SETSTATICOBJECTFIELD_RETURN();
2214 JNI_END
2215
2216
2217
2218 #define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType \
2219 , EntryProbe, ReturnProbe) \
2220 \
2221 JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \
2222 JNIWrapper("SetStatic" XSTR(Result) "Field"); \
2223 EntryProbe; \
2224 \
2225 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
2226 assert(id->is_static_field_id(), "invalid static field id"); \
2227 /* Keep JVMTI addition small and only check enabled flag here. */ \
2228 /* jni_SetField_probe() assumes that is okay to create handles. */ \
2229 if (JvmtiExport::should_post_field_modification()) { \
2230 jvalue field_value; \
2231 field_value.unionType = value; \
2232 JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \
2233 } \
2234 if (SigType == JVM_SIGNATURE_BOOLEAN) { value = ((jboolean)value) & 1; } \
2235 id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \
2236 ReturnProbe;\
2237 JNI_END
2238
2239 DEFINE_SETSTATICFIELD(jboolean, bool, Boolean, JVM_SIGNATURE_BOOLEAN, z
2240 , HOTSPOT_JNI_SETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t)fieldID, value),
2241 HOTSPOT_JNI_SETSTATICBOOLEANFIELD_RETURN())
2242 DEFINE_SETSTATICFIELD(jbyte, byte, Byte, JVM_SIGNATURE_BYTE, b
2243 , HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
2244 HOTSPOT_JNI_SETSTATICBYTEFIELD_RETURN())
2245 DEFINE_SETSTATICFIELD(jchar, char, Char, JVM_SIGNATURE_CHAR, c
2246 , HOTSPOT_JNI_SETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
2247 HOTSPOT_JNI_SETSTATICCHARFIELD_RETURN())
2248 DEFINE_SETSTATICFIELD(jshort, short, Short, JVM_SIGNATURE_SHORT, s
2249 , HOTSPOT_JNI_SETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
2250 HOTSPOT_JNI_SETSTATICSHORTFIELD_RETURN())
2251 DEFINE_SETSTATICFIELD(jint, int, Int, JVM_SIGNATURE_INT, i
2252 , HOTSPOT_JNI_SETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
2253 HOTSPOT_JNI_SETSTATICINTFIELD_RETURN())
2254 DEFINE_SETSTATICFIELD(jlong, long, Long, JVM_SIGNATURE_LONG, j
2255 , HOTSPOT_JNI_SETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
2256 HOTSPOT_JNI_SETSTATICLONGFIELD_RETURN())
2257 // Float and double probes don't return value because dtrace doesn't currently support it
2258 DEFINE_SETSTATICFIELD(jfloat, float, Float, JVM_SIGNATURE_FLOAT, f
2259 , HOTSPOT_JNI_SETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),
2260 HOTSPOT_JNI_SETSTATICFLOATFIELD_RETURN())
2261 DEFINE_SETSTATICFIELD(jdouble, double, Double, JVM_SIGNATURE_DOUBLE, d
2262 , HOTSPOT_JNI_SETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),
2263 HOTSPOT_JNI_SETSTATICDOUBLEFIELD_RETURN())
2264
2265 //
2266 // String Operations
2267 //
2268
2269 // Unicode Interface
2270
2271 DT_RETURN_MARK_DECL(NewString, jstring
2272 , HOTSPOT_JNI_NEWSTRING_RETURN(_ret_ref));
2273
2274 JNI_ENTRY(jstring, jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len))
2275 JNIWrapper("NewString");
2276 HOTSPOT_JNI_NEWSTRING_ENTRY(env, (uint16_t *) unicodeChars, len);
2277 jstring ret = NULL;
2278 DT_RETURN_MARK(NewString, jstring, (const jstring&)ret);
2279 oop string=java_lang_String::create_oop_from_unicode((jchar*) unicodeChars, len, CHECK_NULL);
2280 ret = (jstring) JNIHandles::make_local(env, string);
2281 return ret;
2282 JNI_END
2283
2284
2285 JNI_ENTRY_NO_PRESERVE(jsize, jni_GetStringLength(JNIEnv *env, jstring string))
2286 JNIWrapper("GetStringLength");
2287 HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(env, string);
2288 jsize ret = 0;
2289 oop s = JNIHandles::resolve_non_null(string);
2290 ret = java_lang_String::length(s);
2291 HOTSPOT_JNI_GETSTRINGLENGTH_RETURN(ret);
2292 return ret;
2293 JNI_END
2294
2295
2296 JNI_ENTRY_NO_PRESERVE(const jchar*, jni_GetStringChars(
2297 JNIEnv *env, jstring string, jboolean *isCopy))
2298 JNIWrapper("GetStringChars");
2299 HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(env, string, (uintptr_t *) isCopy);
2300 jchar* buf = NULL;
2301 oop s = JNIHandles::resolve_non_null(string);
2302 typeArrayOop s_value = java_lang_String::value(s);
2303 if (s_value != NULL) {
2304 int s_len = java_lang_String::length(s, s_value);
2305 bool is_latin1 = java_lang_String::is_latin1(s);
2306 buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination
2307 /* JNI Specification states return NULL on OOM */
2308 if (buf != NULL) {
2309 if (s_len > 0) {
2310 if (!is_latin1) {
2311 ArrayAccess<>::arraycopy_to_native(s_value, (size_t) typeArrayOopDesc::element_offset<jchar>(0),
2312 buf, s_len);
2313 } else {
2314 for (int i = 0; i < s_len; i++) {
2315 buf[i] = ((jchar) s_value->byte_at(i)) & 0xff;
2316 }
2317 }
2318 }
2319 buf[s_len] = 0;
2320 //%note jni_5
2321 if (isCopy != NULL) {
2322 *isCopy = JNI_TRUE;
2323 }
2324 }
2325 }
2326 HOTSPOT_JNI_GETSTRINGCHARS_RETURN(buf);
2327 return buf;
2328 JNI_END
2329
2330
2331 JNI_ENTRY_NO_PRESERVE(void, jni_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars))
2332 JNIWrapper("ReleaseStringChars");
2333 HOTSPOT_JNI_RELEASESTRINGCHARS_ENTRY(env, str, (uint16_t *) chars);
2334 //%note jni_6
2335 if (chars != NULL) {
2336 // Since String objects are supposed to be immutable, don't copy any
2337 // new data back. A bad user will have to go after the char array.
2338 FreeHeap((void*) chars);
2339 }
2340 HOTSPOT_JNI_RELEASESTRINGCHARS_RETURN();
2341 JNI_END
2342
2343
2344 // UTF Interface
2345
2346 DT_RETURN_MARK_DECL(NewStringUTF, jstring
2347 , HOTSPOT_JNI_NEWSTRINGUTF_RETURN(_ret_ref));
2348
2349 JNI_ENTRY(jstring, jni_NewStringUTF(JNIEnv *env, const char *bytes))
2350 JNIWrapper("NewStringUTF");
2351 HOTSPOT_JNI_NEWSTRINGUTF_ENTRY(env, (char *) bytes);
2352 jstring ret;
2353 DT_RETURN_MARK(NewStringUTF, jstring, (const jstring&)ret);
2354
2355 oop result = java_lang_String::create_oop_from_str((char*) bytes, CHECK_NULL);
2356 ret = (jstring) JNIHandles::make_local(env, result);
2357 return ret;
2358 JNI_END
2359
2360
2361 JNI_ENTRY(jsize, jni_GetStringUTFLength(JNIEnv *env, jstring string))
2362 JNIWrapper("GetStringUTFLength");
2363 HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY(env, string);
2364 oop java_string = JNIHandles::resolve_non_null(string);
2365 jsize ret = java_lang_String::utf8_length(java_string);
2366 HOTSPOT_JNI_GETSTRINGUTFLENGTH_RETURN(ret);
2367 return ret;
2368 JNI_END
2369
2370
2371 JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy))
2372 JNIWrapper("GetStringUTFChars");
2373 HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY(env, string, (uintptr_t *) isCopy);
2374 char* result = NULL;
2375 oop java_string = JNIHandles::resolve_non_null(string);
2376 typeArrayOop s_value = java_lang_String::value(java_string);
2377 if (s_value != NULL) {
2378 size_t length = java_lang_String::utf8_length(java_string, s_value);
2379 /* JNI Specification states return NULL on OOM */
2380 result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL);
2381 if (result != NULL) {
2382 java_lang_String::as_utf8_string(java_string, s_value, result, (int) length + 1);
2383 if (isCopy != NULL) {
2384 *isCopy = JNI_TRUE;
2385 }
2386 }
2387 }
2388 HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN(result);
2389 return result;
2390 JNI_END
2391
2392
2393 JNI_LEAF(void, jni_ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars))
2394 JNIWrapper("ReleaseStringUTFChars");
2395 HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY(env, str, (char *) chars);
2396 if (chars != NULL) {
2397 FreeHeap((char*) chars);
2398 }
2399 HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN();
2400 JNI_END
2401
2402
2403 JNI_ENTRY_NO_PRESERVE(jsize, jni_GetArrayLength(JNIEnv *env, jarray array))
2404 JNIWrapper("GetArrayLength");
2405 HOTSPOT_JNI_GETARRAYLENGTH_ENTRY(env, array);
2406 arrayOop a = arrayOop(JNIHandles::resolve_non_null(array));
2407 assert(a->is_array(), "must be array");
2408 jsize ret = a->length();
2409 HOTSPOT_JNI_GETARRAYLENGTH_RETURN(ret);
2410 return ret;
2411 JNI_END
2412
2413
2414 //
2415 // Object Array Operations
2416 //
2417
2418 DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray
2419 , HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(_ret_ref));
2420
2421 JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))
2422 JNIWrapper("NewObjectArray");
2423 HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(env, length, elementClass, initialElement);
2424 jobjectArray ret = NULL;
2425 DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
2426 Klass* ek = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass));
2427 Klass* ak = ek->array_klass(CHECK_NULL);
2428 ObjArrayKlass::cast(ak)->initialize(CHECK_NULL);
2429 objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL);
2430 oop initial_value = JNIHandles::resolve(initialElement);
2431 if (initial_value != NULL) { // array already initialized with NULL
2432 for (int index = 0; index < length; index++) {
2433 result->obj_at_put(index, initial_value);
2434 }
2435 }
2436 ret = (jobjectArray) JNIHandles::make_local(env, result);
2437 return ret;
2438 JNI_END
2439
2440 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2441 , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2442
2443 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2444 JNIWrapper("GetObjectArrayElement");
2445 HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2446 jobject ret = NULL;
2447 DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2448 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2449 if (a->is_within_bounds(index)) {
2450 ret = JNIHandles::make_local(env, a->obj_at(index));
2451 return ret;
2452 } else {
2453 ResourceMark rm(THREAD);
2454 stringStream ss;
2455 ss.print("Index %d out of bounds for length %d", index, a->length());
2456 THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2457 }
2458 JNI_END
2459
2460 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2461 , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2462
2463 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2464 JNIWrapper("SetObjectArrayElement");
2465 HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2466 DT_VOID_RETURN_MARK(SetObjectArrayElement);
2467
2468 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2469 oop v = JNIHandles::resolve(value);
2470 if (a->is_within_bounds(index)) {
2471 if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2472 a->obj_at_put(index, v);
2473 } else {
2474 ResourceMark rm(THREAD);
2475 stringStream ss;
2476 Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2477 ss.print("type mismatch: can not store %s to %s[%d]",
2478 v->klass()->external_name(),
2479 bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2480 index);
2481 for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2482 ss.print("[]");
2483 }
2484 THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2485 }
2486 } else {
2487 ResourceMark rm(THREAD);
2488 stringStream ss;
2489 ss.print("Index %d out of bounds for length %d", index, a->length());
2490 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2491 }
2492 JNI_END
2493
2494
2495
2496 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2497 ,EntryProbe,ReturnProbe) \
2498 \
2499 DT_RETURN_MARK_DECL(New##Result##Array, Return \
2500 , ReturnProbe); \
2501 \
2502 JNI_ENTRY(Return, \
2503 jni_New##Result##Array(JNIEnv *env, jsize len)) \
2504 JNIWrapper("New" XSTR(Result) "Array"); \
2505 EntryProbe; \
2506 Return ret = NULL;\
2507 DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2508 \
2509 oop obj= oopFactory::Allocator(len, CHECK_NULL); \
2510 ret = (Return) JNIHandles::make_local(env, obj); \
2511 return ret;\
2512 JNI_END
2513
DEFINE_NEWSCALARARRAY(jbooleanArray,new_boolArray,Boolean,HOTSPOT_JNI_NEWBOOLEANARRAY_ENTRY (env,len),HOTSPOT_JNI_NEWBOOLEANARRAY_RETURN (_ret_ref))2514 DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray, Boolean,
2515 HOTSPOT_JNI_NEWBOOLEANARRAY_ENTRY(env, len),
2516 HOTSPOT_JNI_NEWBOOLEANARRAY_RETURN(_ret_ref))
2517 DEFINE_NEWSCALARARRAY(jbyteArray, new_byteArray, Byte,
2518 HOTSPOT_JNI_NEWBYTEARRAY_ENTRY(env, len),
2519 HOTSPOT_JNI_NEWBYTEARRAY_RETURN(_ret_ref))
2520 DEFINE_NEWSCALARARRAY(jshortArray, new_shortArray, Short,
2521 HOTSPOT_JNI_NEWSHORTARRAY_ENTRY(env, len),
2522 HOTSPOT_JNI_NEWSHORTARRAY_RETURN(_ret_ref))
2523 DEFINE_NEWSCALARARRAY(jcharArray, new_charArray, Char,
2524 HOTSPOT_JNI_NEWCHARARRAY_ENTRY(env, len),
2525 HOTSPOT_JNI_NEWCHARARRAY_RETURN(_ret_ref))
2526 DEFINE_NEWSCALARARRAY(jintArray, new_intArray, Int,
2527 HOTSPOT_JNI_NEWINTARRAY_ENTRY(env, len),
2528 HOTSPOT_JNI_NEWINTARRAY_RETURN(_ret_ref))
2529 DEFINE_NEWSCALARARRAY(jlongArray, new_longArray, Long,
2530 HOTSPOT_JNI_NEWLONGARRAY_ENTRY(env, len),
2531 HOTSPOT_JNI_NEWLONGARRAY_RETURN(_ret_ref))
2532 DEFINE_NEWSCALARARRAY(jfloatArray, new_floatArray, Float,
2533 HOTSPOT_JNI_NEWFLOATARRAY_ENTRY(env, len),
2534 HOTSPOT_JNI_NEWFLOATARRAY_RETURN(_ret_ref))
2535 DEFINE_NEWSCALARARRAY(jdoubleArray, new_doubleArray, Double,
2536 HOTSPOT_JNI_NEWDOUBLEARRAY_ENTRY(env, len),
2537 HOTSPOT_JNI_NEWDOUBLEARRAY_RETURN(_ret_ref))
2538
2539 // Return an address which will fault if the caller writes to it.
2540
2541 static char* get_bad_address() {
2542 static char* bad_address = NULL;
2543 if (bad_address == NULL) {
2544 size_t size = os::vm_allocation_granularity();
2545 bad_address = os::reserve_memory(size);
2546 if (bad_address != NULL) {
2547 os::protect_memory(bad_address, size, os::MEM_PROT_READ,
2548 /*is_committed*/false);
2549 MemTracker::record_virtual_memory_type((void*)bad_address, mtInternal);
2550 }
2551 }
2552 return bad_address;
2553 }
2554
2555
2556
2557 #define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \
2558 , EntryProbe, ReturnProbe) \
2559 \
2560 JNI_ENTRY_NO_PRESERVE(ElementType*, \
2561 jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \
2562 JNIWrapper("Get" XSTR(Result) "ArrayElements"); \
2563 EntryProbe; \
2564 /* allocate an chunk of memory in c land */ \
2565 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2566 ElementType* result; \
2567 int len = a->length(); \
2568 if (len == 0) { \
2569 if (isCopy != NULL) { \
2570 *isCopy = JNI_FALSE; \
2571 } \
2572 /* Empty array: legal but useless, can't return NULL. \
2573 * Return a pointer to something useless. \
2574 * Avoid asserts in typeArrayOop. */ \
2575 result = (ElementType*)get_bad_address(); \
2576 } else { \
2577 /* JNI Specification states return NULL on OOM */ \
2578 result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
2579 if (result != NULL) { \
2580 /* copy the array to the c chunk */ \
2581 ArrayAccess<>::arraycopy_to_native(a, typeArrayOopDesc::element_offset<ElementType>(0), \
2582 result, len); \
2583 if (isCopy) { \
2584 *isCopy = JNI_TRUE; \
2585 } \
2586 } \
2587 } \
2588 ReturnProbe; \
2589 return result; \
2590 JNI_END
2591
2592 DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
2593 , HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2594 HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_RETURN((uintptr_t*)result))
2595 DEFINE_GETSCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte
2596 , HOTSPOT_JNI_GETBYTEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2597 HOTSPOT_JNI_GETBYTEARRAYELEMENTS_RETURN((char*)result))
2598 DEFINE_GETSCALARARRAYELEMENTS(T_SHORT, jshort, Short, short
2599 , HOTSPOT_JNI_GETSHORTARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),
2600 HOTSPOT_JNI_GETSHORTARRAYELEMENTS_RETURN((uint16_t*)result))
2601 DEFINE_GETSCALARARRAYELEMENTS(T_CHAR, jchar, Char, char
2602 , HOTSPOT_JNI_GETCHARARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),
2603 HOTSPOT_JNI_GETCHARARRAYELEMENTS_RETURN(result))
2604 DEFINE_GETSCALARARRAYELEMENTS(T_INT, jint, Int, int
2605 , HOTSPOT_JNI_GETINTARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2606 HOTSPOT_JNI_GETINTARRAYELEMENTS_RETURN((uint32_t*)result))
2607 DEFINE_GETSCALARARRAYELEMENTS(T_LONG, jlong, Long, long
2608 , HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2609 HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(((uintptr_t*)result)))
2610 // Float and double probes don't return value because dtrace doesn't currently support it
2611 DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float
2612 , HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2613 HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result))
2614 DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double
2615 , HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2616 HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(result))
2617
2618
2619 #define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \
2620 , EntryProbe, ReturnProbe);\
2621 \
2622 JNI_ENTRY_NO_PRESERVE(void, \
2623 jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \
2624 ElementType *buf, jint mode)) \
2625 JNIWrapper("Release" XSTR(Result) "ArrayElements"); \
2626 EntryProbe; \
2627 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2628 int len = a->length(); \
2629 if (len != 0) { /* Empty array: nothing to free or copy. */ \
2630 if ((mode == 0) || (mode == JNI_COMMIT)) { \
2631 ArrayAccess<>::arraycopy_from_native(buf, a, typeArrayOopDesc::element_offset<ElementType>(0), len); \
2632 } \
2633 if ((mode == 0) || (mode == JNI_ABORT)) { \
2634 FreeHeap(buf); \
2635 } \
2636 } \
2637 ReturnProbe; \
2638 JNI_END
2639
2640 DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
2641 , HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
2642 HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN())
2643 DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte
2644 , HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode),
2645 HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN())
2646 DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT, jshort, Short, short
2647 , HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
2648 HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_RETURN())
2649 DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR, jchar, Char, char
2650 , HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
2651 HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_RETURN())
2652 DEFINE_RELEASESCALARARRAYELEMENTS(T_INT, jint, Int, int
2653 , HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_ENTRY(env, array, (uint32_t *) buf, mode),
2654 HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_RETURN())
2655 DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG, jlong, Long, long
2656 , HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
2657 HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_RETURN())
2658 DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float
2659 , HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode),
2660 HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN())
2661 DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double
2662 , HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode),
2663 HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN())
2664
check_bounds(jsize start,jsize copy_len,jsize array_len,TRAPS)2665 static void check_bounds(jsize start, jsize copy_len, jsize array_len, TRAPS) {
2666 ResourceMark rm(THREAD);
2667 if (copy_len < 0) {
2668 stringStream ss;
2669 ss.print("Length %d is negative", copy_len);
2670 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2671 } else if (start < 0 || (start > array_len - copy_len)) {
2672 stringStream ss;
2673 ss.print("Array region %d.." INT64_FORMAT " out of bounds for length %d",
2674 start, (int64_t)start+(int64_t)copy_len, array_len);
2675 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2676 }
2677 }
2678
2679 #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
2680 , EntryProbe, ReturnProbe); \
2681 DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion \
2682 , ReturnProbe); \
2683 \
2684 JNI_ENTRY(void, \
2685 jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
2686 jsize len, ElementType *buf)) \
2687 JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \
2688 EntryProbe; \
2689 DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
2690 typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2691 check_bounds(start, len, src->length(), CHECK); \
2692 if (len > 0) { \
2693 ArrayAccess<>::arraycopy_to_native(src, typeArrayOopDesc::element_offset<ElementType>(start), buf, len); \
2694 } \
2695 JNI_END
2696
2697 DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool
2698 , HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
2699 HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN());
2700 DEFINE_GETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte
2701 , HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
2702 HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN());
2703 DEFINE_GETSCALARARRAYREGION(T_SHORT, jshort, Short, short
2704 , HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
2705 HOTSPOT_JNI_GETSHORTARRAYREGION_RETURN());
2706 DEFINE_GETSCALARARRAYREGION(T_CHAR, jchar, Char, char
2707 , HOTSPOT_JNI_GETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t*) buf),
2708 HOTSPOT_JNI_GETCHARARRAYREGION_RETURN());
2709 DEFINE_GETSCALARARRAYREGION(T_INT, jint, Int, int
2710 , HOTSPOT_JNI_GETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t*) buf),
2711 HOTSPOT_JNI_GETINTARRAYREGION_RETURN());
2712 DEFINE_GETSCALARARRAYREGION(T_LONG, jlong, Long, long
2713 , HOTSPOT_JNI_GETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
2714 HOTSPOT_JNI_GETLONGARRAYREGION_RETURN());
2715 DEFINE_GETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float
2716 , HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
2717 HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN());
2718 DEFINE_GETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double
2719 , HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
2720 HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN());
2721
2722
2723 #define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
2724 , EntryProbe, ReturnProbe); \
2725 DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion \
2726 ,ReturnProbe); \
2727 \
2728 JNI_ENTRY(void, \
2729 jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
2730 jsize len, const ElementType *buf)) \
2731 JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
2732 EntryProbe; \
2733 DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
2734 typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2735 check_bounds(start, len, dst->length(), CHECK); \
2736 if (len > 0) { \
2737 ArrayAccess<>::arraycopy_from_native(buf, dst, typeArrayOopDesc::element_offset<ElementType>(start), len); \
2738 } \
2739 JNI_END
2740
2741 DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool
2742 , HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf),
2743 HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN())
2744 DEFINE_SETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte
2745 , HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
2746 HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN())
2747 DEFINE_SETSCALARARRAYREGION(T_SHORT, jshort, Short, short
2748 , HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
2749 HOTSPOT_JNI_SETSHORTARRAYREGION_RETURN())
2750 DEFINE_SETSCALARARRAYREGION(T_CHAR, jchar, Char, char
2751 , HOTSPOT_JNI_SETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
2752 HOTSPOT_JNI_SETCHARARRAYREGION_RETURN())
2753 DEFINE_SETSCALARARRAYREGION(T_INT, jint, Int, int
2754 , HOTSPOT_JNI_SETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t *) buf),
2755 HOTSPOT_JNI_SETINTARRAYREGION_RETURN())
2756 DEFINE_SETSCALARARRAYREGION(T_LONG, jlong, Long, long
2757 , HOTSPOT_JNI_SETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
2758 HOTSPOT_JNI_SETLONGARRAYREGION_RETURN())
2759 DEFINE_SETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float
2760 , HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
2761 HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN())
2762 DEFINE_SETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double
2763 , HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
2764 HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN())
2765
2766
2767 DT_RETURN_MARK_DECL(RegisterNatives, jint
2768 , HOTSPOT_JNI_REGISTERNATIVES_RETURN(_ret_ref));
2769
2770 JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
2771 const JNINativeMethod *methods,
2772 jint nMethods))
2773 JNIWrapper("RegisterNatives");
2774 HOTSPOT_JNI_REGISTERNATIVES_ENTRY(env, clazz, (void *) methods, nMethods);
2775 jint ret = 0;
2776 DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);
2777
2778 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
2779
2780 // There are no restrictions on native code registering native methods,
2781 // which allows agents to redefine the bindings to native methods, however
2782 // we issue a warning if any code running outside of the boot/platform
2783 // loader is rebinding any native methods in classes loaded by the
2784 // boot/platform loader that are in named modules. That will catch changes
2785 // to platform classes while excluding classes added to the bootclasspath.
2786 bool do_warning = false;
2787
2788 // Only instanceKlasses can have native methods
2789 if (k->is_instance_klass()) {
2790 oop cl = k->class_loader();
2791 InstanceKlass* ik = InstanceKlass::cast(k);
2792 // Check for a platform class
2793 if ((cl == NULL || SystemDictionary::is_platform_class_loader(cl)) &&
2794 ik->module()->is_named()) {
2795 Klass* caller = thread->security_get_caller_class(1);
2796 // If no caller class, or caller class has a different loader, then
2797 // issue a warning below.
2798 do_warning = (caller == NULL) || caller->class_loader() != cl;
2799 }
2800 }
2801
2802
2803 for (int index = 0; index < nMethods; index++) {
2804 const char* meth_name = methods[index].name;
2805 const char* meth_sig = methods[index].signature;
2806 int meth_name_len = (int)strlen(meth_name);
2807
2808 // The class should have been loaded (we have an instance of the class
2809 // passed in) so the method and signature should already be in the symbol
2810 // table. If they're not there, the method doesn't exist.
2811 TempNewSymbol name = SymbolTable::probe(meth_name, meth_name_len);
2812 TempNewSymbol signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig));
2813
2814 if (name == NULL || signature == NULL) {
2815 ResourceMark rm(THREAD);
2816 stringStream st;
2817 st.print("Method %s.%s%s not found", k->external_name(), meth_name, meth_sig);
2818 // Must return negative value on failure
2819 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
2820 }
2821
2822 if (do_warning) {
2823 ResourceMark rm(THREAD);
2824 log_warning(jni, resolve)("Re-registering of platform native method: %s.%s%s "
2825 "from code in a different classloader", k->external_name(), meth_name, meth_sig);
2826 }
2827
2828 bool res = Method::register_native(k, name, signature,
2829 (address) methods[index].fnPtr, THREAD);
2830 if (!res) {
2831 ret = -1;
2832 break;
2833 }
2834 }
2835 return ret;
2836 JNI_END
2837
2838
2839 JNI_ENTRY(jint, jni_UnregisterNatives(JNIEnv *env, jclass clazz))
2840 JNIWrapper("UnregisterNatives");
2841 HOTSPOT_JNI_UNREGISTERNATIVES_ENTRY(env, clazz);
2842 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
2843 //%note jni_2
2844 if (k->is_instance_klass()) {
2845 for (int index = 0; index < InstanceKlass::cast(k)->methods()->length(); index++) {
2846 Method* m = InstanceKlass::cast(k)->methods()->at(index);
2847 if (m->is_native()) {
2848 m->clear_native_function();
2849 m->set_signature_handler(NULL);
2850 }
2851 }
2852 }
2853 HOTSPOT_JNI_UNREGISTERNATIVES_RETURN(0);
2854 return 0;
2855 JNI_END
2856
2857 //
2858 // Monitor functions
2859 //
2860
2861 DT_RETURN_MARK_DECL(MonitorEnter, jint
2862 , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
2863
2864 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
2865 HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
2866 jint ret = JNI_ERR;
2867 DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
2868
2869 // If the object is null, we can't do anything with it
2870 if (jobj == NULL) {
2871 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2872 }
2873
2874 Handle obj(thread, JNIHandles::resolve_non_null(jobj));
2875 ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
2876 ret = JNI_OK;
2877 return ret;
2878 JNI_END
2879
2880 DT_RETURN_MARK_DECL(MonitorExit, jint
2881 , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
2882
2883 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
2884 HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
2885 jint ret = JNI_ERR;
2886 DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
2887
2888 // Don't do anything with a null object
2889 if (jobj == NULL) {
2890 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2891 }
2892
2893 Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
2894 ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
2895
2896 ret = JNI_OK;
2897 return ret;
2898 JNI_END
2899
2900 //
2901 // Extensions
2902 //
2903
2904 DT_VOID_RETURN_MARK_DECL(GetStringRegion
2905 , HOTSPOT_JNI_GETSTRINGREGION_RETURN());
2906
2907 JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf))
2908 JNIWrapper("GetStringRegion");
2909 HOTSPOT_JNI_GETSTRINGREGION_ENTRY(env, string, start, len, buf);
2910 DT_VOID_RETURN_MARK(GetStringRegion);
2911 oop s = JNIHandles::resolve_non_null(string);
2912 typeArrayOop s_value = java_lang_String::value(s);
2913 int s_len = java_lang_String::length(s, s_value);
2914 if (start < 0 || len < 0 || start > s_len - len) {
2915 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
2916 } else {
2917 if (len > 0) {
2918 bool is_latin1 = java_lang_String::is_latin1(s);
2919 if (!is_latin1) {
2920 ArrayAccess<>::arraycopy_to_native(s_value, typeArrayOopDesc::element_offset<jchar>(start),
2921 buf, len);
2922 } else {
2923 for (int i = 0; i < len; i++) {
2924 buf[i] = ((jchar) s_value->byte_at(i + start)) & 0xff;
2925 }
2926 }
2927 }
2928 }
2929 JNI_END
2930
2931 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion
2932 , HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN());
2933
2934 JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf))
2935 JNIWrapper("GetStringUTFRegion");
2936 HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(env, string, start, len, buf);
2937 DT_VOID_RETURN_MARK(GetStringUTFRegion);
2938 oop s = JNIHandles::resolve_non_null(string);
2939 typeArrayOop s_value = java_lang_String::value(s);
2940 int s_len = java_lang_String::length(s, s_value);
2941 if (start < 0 || len < 0 || start > s_len - len) {
2942 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
2943 } else {
2944 //%note jni_7
2945 if (len > 0) {
2946 // Assume the buffer is large enough as the JNI spec. does not require user error checking
2947 java_lang_String::as_utf8_string(s, s_value, start, len, buf, INT_MAX);
2948 // as_utf8_string null-terminates the result string
2949 } else {
2950 // JDK null-terminates the buffer even in len is zero
2951 if (buf != NULL) {
2952 buf[0] = 0;
2953 }
2954 }
2955 }
2956 JNI_END
2957
lock_gc_or_pin_object(JavaThread * thread,jobject obj)2958 static oop lock_gc_or_pin_object(JavaThread* thread, jobject obj) {
2959 if (Universe::heap()->supports_object_pinning()) {
2960 const oop o = JNIHandles::resolve_non_null(obj);
2961 return Universe::heap()->pin_object(thread, o);
2962 } else {
2963 GCLocker::lock_critical(thread);
2964 return JNIHandles::resolve_non_null(obj);
2965 }
2966 }
2967
unlock_gc_or_unpin_object(JavaThread * thread,jobject obj)2968 static void unlock_gc_or_unpin_object(JavaThread* thread, jobject obj) {
2969 if (Universe::heap()->supports_object_pinning()) {
2970 const oop o = JNIHandles::resolve_non_null(obj);
2971 return Universe::heap()->unpin_object(thread, o);
2972 } else {
2973 GCLocker::unlock_critical(thread);
2974 }
2975 }
2976
2977 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
2978 JNIWrapper("GetPrimitiveArrayCritical");
2979 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(env, array, (uintptr_t *) isCopy);
2980 if (isCopy != NULL) {
2981 *isCopy = JNI_FALSE;
2982 }
2983 oop a = lock_gc_or_pin_object(thread, array);
2984 assert(a->is_array(), "just checking");
2985 BasicType type;
2986 if (a->is_objArray()) {
2987 type = T_OBJECT;
2988 } else {
2989 type = TypeArrayKlass::cast(a->klass())->element_type();
2990 }
2991 void* ret = arrayOop(a)->base(type);
2992 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(ret);
2993 return ret;
2994 JNI_END
2995
2996
2997 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
2998 JNIWrapper("ReleasePrimitiveArrayCritical");
2999 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(env, array, carray, mode);
3000 unlock_gc_or_unpin_object(thread, array);
3001 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN();
3002 JNI_END
3003
3004
3005 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
3006 JNIWrapper("GetStringCritical");
3007 HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(env, string, (uintptr_t *) isCopy);
3008 oop s = lock_gc_or_pin_object(thread, string);
3009 typeArrayOop s_value = java_lang_String::value(s);
3010 bool is_latin1 = java_lang_String::is_latin1(s);
3011 if (isCopy != NULL) {
3012 *isCopy = is_latin1 ? JNI_TRUE : JNI_FALSE;
3013 }
3014 jchar* ret;
3015 if (!is_latin1) {
3016 ret = (jchar*) s_value->base(T_CHAR);
3017 } else {
3018 // Inflate latin1 encoded string to UTF16
3019 int s_len = java_lang_String::length(s, s_value);
3020 ret = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination
3021 /* JNI Specification states return NULL on OOM */
3022 if (ret != NULL) {
3023 for (int i = 0; i < s_len; i++) {
3024 ret[i] = ((jchar) s_value->byte_at(i)) & 0xff;
3025 }
3026 ret[s_len] = 0;
3027 }
3028 }
3029 HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN((uint16_t *) ret);
3030 return ret;
3031 JNI_END
3032
3033
3034 JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
3035 JNIWrapper("ReleaseStringCritical");
3036 HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(env, str, (uint16_t *) chars);
3037 // The str and chars arguments are ignored for UTF16 strings
3038 oop s = JNIHandles::resolve_non_null(str);
3039 bool is_latin1 = java_lang_String::is_latin1(s);
3040 if (is_latin1) {
3041 // For latin1 string, free jchar array allocated by earlier call to GetStringCritical.
3042 // This assumes that ReleaseStringCritical bookends GetStringCritical.
3043 FREE_C_HEAP_ARRAY(jchar, chars);
3044 }
3045 unlock_gc_or_unpin_object(thread, str);
3046 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
3047 JNI_END
3048
3049
3050 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
3051 JNIWrapper("jni_NewWeakGlobalRef");
3052 HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(env, ref);
3053 Handle ref_handle(thread, JNIHandles::resolve(ref));
3054 jweak ret = JNIHandles::make_weak_global(ref_handle);
3055 HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(ret);
3056 return ret;
3057 JNI_END
3058
3059 // Must be JNI_ENTRY (with HandleMark)
3060 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
3061 JNIWrapper("jni_DeleteWeakGlobalRef");
3062 HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(env, ref);
3063 JNIHandles::destroy_weak_global(ref);
3064 HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN();
3065 JNI_END
3066
3067
3068 JNI_ENTRY_NO_PRESERVE(jboolean, jni_ExceptionCheck(JNIEnv *env))
3069 JNIWrapper("jni_ExceptionCheck");
3070 HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(env);
3071 jni_check_async_exceptions(thread);
3072 jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;
3073 HOTSPOT_JNI_EXCEPTIONCHECK_RETURN(ret);
3074 return ret;
3075 JNI_END
3076
3077
3078 // Initialization state for three routines below relating to
3079 // java.nio.DirectBuffers
3080 static int directBufferSupportInitializeStarted = 0;
3081 static volatile int directBufferSupportInitializeEnded = 0;
3082 static volatile int directBufferSupportInitializeFailed = 0;
3083 static jclass bufferClass = NULL;
3084 static jclass directBufferClass = NULL;
3085 static jclass directByteBufferClass = NULL;
3086 static jmethodID directByteBufferConstructor = NULL;
3087 static jfieldID directBufferAddressField = NULL;
3088 static jfieldID bufferCapacityField = NULL;
3089
lookupOne(JNIEnv * env,const char * name,TRAPS)3090 static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) {
3091 Handle loader; // null (bootstrap) loader
3092 Handle protection_domain; // null protection domain
3093
3094 TempNewSymbol sym = SymbolTable::new_symbol(name);
3095 jclass result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);
3096
3097 if (log_is_enabled(Debug, class, resolve) && result != NULL) {
3098 trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
3099 }
3100 return result;
3101 }
3102
3103 // These lookups are done with the NULL (bootstrap) ClassLoader to
3104 // circumvent any security checks that would be done by jni_FindClass.
JNI_ENTRY(bool,lookupDirectBufferClasses (JNIEnv * env))3105 JNI_ENTRY(bool, lookupDirectBufferClasses(JNIEnv* env))
3106 {
3107 if ((bufferClass = lookupOne(env, "java/nio/Buffer", thread)) == NULL) { return false; }
3108 if ((directBufferClass = lookupOne(env, "sun/nio/ch/DirectBuffer", thread)) == NULL) { return false; }
3109 if ((directByteBufferClass = lookupOne(env, "java/nio/DirectByteBuffer", thread)) == NULL) { return false; }
3110 return true;
3111 }
3112 JNI_END
3113
3114
initializeDirectBufferSupport(JNIEnv * env,JavaThread * thread)3115 static bool initializeDirectBufferSupport(JNIEnv* env, JavaThread* thread) {
3116 if (directBufferSupportInitializeFailed) {
3117 return false;
3118 }
3119
3120 if (Atomic::cmpxchg(&directBufferSupportInitializeStarted, 0, 1) == 0) {
3121 if (!lookupDirectBufferClasses(env)) {
3122 directBufferSupportInitializeFailed = 1;
3123 return false;
3124 }
3125
3126 // Make global references for these
3127 bufferClass = (jclass) env->NewGlobalRef(bufferClass);
3128 directBufferClass = (jclass) env->NewGlobalRef(directBufferClass);
3129 directByteBufferClass = (jclass) env->NewGlobalRef(directByteBufferClass);
3130
3131 // Get needed field and method IDs
3132 directByteBufferConstructor = env->GetMethodID(directByteBufferClass, "<init>", "(JI)V");
3133 if (env->ExceptionCheck()) {
3134 env->ExceptionClear();
3135 directBufferSupportInitializeFailed = 1;
3136 return false;
3137 }
3138 directBufferAddressField = env->GetFieldID(bufferClass, "address", "J");
3139 if (env->ExceptionCheck()) {
3140 env->ExceptionClear();
3141 directBufferSupportInitializeFailed = 1;
3142 return false;
3143 }
3144 bufferCapacityField = env->GetFieldID(bufferClass, "capacity", "I");
3145 if (env->ExceptionCheck()) {
3146 env->ExceptionClear();
3147 directBufferSupportInitializeFailed = 1;
3148 return false;
3149 }
3150
3151 if ((directByteBufferConstructor == NULL) ||
3152 (directBufferAddressField == NULL) ||
3153 (bufferCapacityField == NULL)) {
3154 directBufferSupportInitializeFailed = 1;
3155 return false;
3156 }
3157
3158 directBufferSupportInitializeEnded = 1;
3159 } else {
3160 while (!directBufferSupportInitializeEnded && !directBufferSupportInitializeFailed) {
3161 os::naked_yield();
3162 }
3163 }
3164
3165 return !directBufferSupportInitializeFailed;
3166 }
3167
jni_NewDirectByteBuffer(JNIEnv * env,void * address,jlong capacity)3168 extern "C" jobject JNICALL jni_NewDirectByteBuffer(JNIEnv *env, void* address, jlong capacity)
3169 {
3170 // thread_from_jni_environment() will block if VM is gone.
3171 JavaThread* thread = JavaThread::thread_from_jni_environment(env);
3172
3173 JNIWrapper("jni_NewDirectByteBuffer");
3174 HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_ENTRY(env, address, capacity);
3175
3176 if (!directBufferSupportInitializeEnded) {
3177 if (!initializeDirectBufferSupport(env, thread)) {
3178 HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(NULL);
3179 return NULL;
3180 }
3181 }
3182
3183 // Being paranoid about accidental sign extension on address
3184 jlong addr = (jlong) ((uintptr_t) address);
3185 // NOTE that package-private DirectByteBuffer constructor currently
3186 // takes int capacity
3187 jint cap = (jint) capacity;
3188 jobject ret = env->NewObject(directByteBufferClass, directByteBufferConstructor, addr, cap);
3189 HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(ret);
3190 return ret;
3191 }
3192
3193 DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*
3194 , HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_RETURN((void*) _ret_ref));
3195
jni_GetDirectBufferAddress(JNIEnv * env,jobject buf)3196 extern "C" void* JNICALL jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3197 {
3198 // thread_from_jni_environment() will block if VM is gone.
3199 JavaThread* thread = JavaThread::thread_from_jni_environment(env);
3200
3201 JNIWrapper("jni_GetDirectBufferAddress");
3202 HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_ENTRY(env, buf);
3203 void* ret = NULL;
3204 DT_RETURN_MARK(GetDirectBufferAddress, void*, (const void*&)ret);
3205
3206 if (!directBufferSupportInitializeEnded) {
3207 if (!initializeDirectBufferSupport(env, thread)) {
3208 return 0;
3209 }
3210 }
3211
3212 if ((buf != NULL) && (!env->IsInstanceOf(buf, directBufferClass))) {
3213 return 0;
3214 }
3215
3216 ret = (void*)(intptr_t)env->GetLongField(buf, directBufferAddressField);
3217 return ret;
3218 }
3219
3220 DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong
3221 , HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_RETURN(_ret_ref));
3222
jni_GetDirectBufferCapacity(JNIEnv * env,jobject buf)3223 extern "C" jlong JNICALL jni_GetDirectBufferCapacity(JNIEnv *env, jobject buf)
3224 {
3225 // thread_from_jni_environment() will block if VM is gone.
3226 JavaThread* thread = JavaThread::thread_from_jni_environment(env);
3227
3228 JNIWrapper("jni_GetDirectBufferCapacity");
3229 HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_ENTRY(env, buf);
3230 jlong ret = -1;
3231 DT_RETURN_MARK(GetDirectBufferCapacity, jlong, (const jlong&)ret);
3232
3233 if (!directBufferSupportInitializeEnded) {
3234 if (!initializeDirectBufferSupport(env, thread)) {
3235 ret = 0;
3236 return ret;
3237 }
3238 }
3239
3240 if (buf == NULL) {
3241 return -1;
3242 }
3243
3244 if (!env->IsInstanceOf(buf, directBufferClass)) {
3245 return -1;
3246 }
3247
3248 // NOTE that capacity is currently an int in the implementation
3249 ret = env->GetIntField(buf, bufferCapacityField);
3250 return ret;
3251 }
3252
3253
3254 JNI_LEAF(jint, jni_GetVersion(JNIEnv *env))
3255 JNIWrapper("GetVersion");
3256 HOTSPOT_JNI_GETVERSION_ENTRY(env);
3257 HOTSPOT_JNI_GETVERSION_RETURN(CurrentVersion);
3258 return CurrentVersion;
3259 JNI_END
3260
3261 extern struct JavaVM_ main_vm;
3262
3263 JNI_LEAF(jint, jni_GetJavaVM(JNIEnv *env, JavaVM **vm))
3264 JNIWrapper("jni_GetJavaVM");
3265 HOTSPOT_JNI_GETJAVAVM_ENTRY(env, (void **) vm);
3266 *vm = (JavaVM *)(&main_vm);
3267 HOTSPOT_JNI_GETJAVAVM_RETURN(JNI_OK);
3268 return JNI_OK;
3269 JNI_END
3270
3271
3272 JNI_ENTRY(jobject, jni_GetModule(JNIEnv* env, jclass clazz))
3273 JNIWrapper("GetModule");
3274 return Modules::get_module(clazz, THREAD);
3275 JNI_END
3276
3277
3278 // Structure containing all jni functions
3279 struct JNINativeInterface_ jni_NativeInterface = {
3280 NULL,
3281 NULL,
3282 NULL,
3283
3284 NULL,
3285
3286 jni_GetVersion,
3287
3288 jni_DefineClass,
3289 jni_FindClass,
3290
3291 jni_FromReflectedMethod,
3292 jni_FromReflectedField,
3293
3294 jni_ToReflectedMethod,
3295
3296 jni_GetSuperclass,
3297 jni_IsAssignableFrom,
3298
3299 jni_ToReflectedField,
3300
3301 jni_Throw,
3302 jni_ThrowNew,
3303 jni_ExceptionOccurred,
3304 jni_ExceptionDescribe,
3305 jni_ExceptionClear,
3306 jni_FatalError,
3307
3308 jni_PushLocalFrame,
3309 jni_PopLocalFrame,
3310
3311 jni_NewGlobalRef,
3312 jni_DeleteGlobalRef,
3313 jni_DeleteLocalRef,
3314 jni_IsSameObject,
3315
3316 jni_NewLocalRef,
3317 jni_EnsureLocalCapacity,
3318
3319 jni_AllocObject,
3320 jni_NewObject,
3321 jni_NewObjectV,
3322 jni_NewObjectA,
3323
3324 jni_GetObjectClass,
3325 jni_IsInstanceOf,
3326
3327 jni_GetMethodID,
3328
3329 jni_CallObjectMethod,
3330 jni_CallObjectMethodV,
3331 jni_CallObjectMethodA,
3332 jni_CallBooleanMethod,
3333 jni_CallBooleanMethodV,
3334 jni_CallBooleanMethodA,
3335 jni_CallByteMethod,
3336 jni_CallByteMethodV,
3337 jni_CallByteMethodA,
3338 jni_CallCharMethod,
3339 jni_CallCharMethodV,
3340 jni_CallCharMethodA,
3341 jni_CallShortMethod,
3342 jni_CallShortMethodV,
3343 jni_CallShortMethodA,
3344 jni_CallIntMethod,
3345 jni_CallIntMethodV,
3346 jni_CallIntMethodA,
3347 jni_CallLongMethod,
3348 jni_CallLongMethodV,
3349 jni_CallLongMethodA,
3350 jni_CallFloatMethod,
3351 jni_CallFloatMethodV,
3352 jni_CallFloatMethodA,
3353 jni_CallDoubleMethod,
3354 jni_CallDoubleMethodV,
3355 jni_CallDoubleMethodA,
3356 jni_CallVoidMethod,
3357 jni_CallVoidMethodV,
3358 jni_CallVoidMethodA,
3359
3360 jni_CallNonvirtualObjectMethod,
3361 jni_CallNonvirtualObjectMethodV,
3362 jni_CallNonvirtualObjectMethodA,
3363 jni_CallNonvirtualBooleanMethod,
3364 jni_CallNonvirtualBooleanMethodV,
3365 jni_CallNonvirtualBooleanMethodA,
3366 jni_CallNonvirtualByteMethod,
3367 jni_CallNonvirtualByteMethodV,
3368 jni_CallNonvirtualByteMethodA,
3369 jni_CallNonvirtualCharMethod,
3370 jni_CallNonvirtualCharMethodV,
3371 jni_CallNonvirtualCharMethodA,
3372 jni_CallNonvirtualShortMethod,
3373 jni_CallNonvirtualShortMethodV,
3374 jni_CallNonvirtualShortMethodA,
3375 jni_CallNonvirtualIntMethod,
3376 jni_CallNonvirtualIntMethodV,
3377 jni_CallNonvirtualIntMethodA,
3378 jni_CallNonvirtualLongMethod,
3379 jni_CallNonvirtualLongMethodV,
3380 jni_CallNonvirtualLongMethodA,
3381 jni_CallNonvirtualFloatMethod,
3382 jni_CallNonvirtualFloatMethodV,
3383 jni_CallNonvirtualFloatMethodA,
3384 jni_CallNonvirtualDoubleMethod,
3385 jni_CallNonvirtualDoubleMethodV,
3386 jni_CallNonvirtualDoubleMethodA,
3387 jni_CallNonvirtualVoidMethod,
3388 jni_CallNonvirtualVoidMethodV,
3389 jni_CallNonvirtualVoidMethodA,
3390
3391 jni_GetFieldID,
3392
3393 jni_GetObjectField,
3394 jni_GetBooleanField,
3395 jni_GetByteField,
3396 jni_GetCharField,
3397 jni_GetShortField,
3398 jni_GetIntField,
3399 jni_GetLongField,
3400 jni_GetFloatField,
3401 jni_GetDoubleField,
3402
3403 jni_SetObjectField,
3404 jni_SetBooleanField,
3405 jni_SetByteField,
3406 jni_SetCharField,
3407 jni_SetShortField,
3408 jni_SetIntField,
3409 jni_SetLongField,
3410 jni_SetFloatField,
3411 jni_SetDoubleField,
3412
3413 jni_GetStaticMethodID,
3414
3415 jni_CallStaticObjectMethod,
3416 jni_CallStaticObjectMethodV,
3417 jni_CallStaticObjectMethodA,
3418 jni_CallStaticBooleanMethod,
3419 jni_CallStaticBooleanMethodV,
3420 jni_CallStaticBooleanMethodA,
3421 jni_CallStaticByteMethod,
3422 jni_CallStaticByteMethodV,
3423 jni_CallStaticByteMethodA,
3424 jni_CallStaticCharMethod,
3425 jni_CallStaticCharMethodV,
3426 jni_CallStaticCharMethodA,
3427 jni_CallStaticShortMethod,
3428 jni_CallStaticShortMethodV,
3429 jni_CallStaticShortMethodA,
3430 jni_CallStaticIntMethod,
3431 jni_CallStaticIntMethodV,
3432 jni_CallStaticIntMethodA,
3433 jni_CallStaticLongMethod,
3434 jni_CallStaticLongMethodV,
3435 jni_CallStaticLongMethodA,
3436 jni_CallStaticFloatMethod,
3437 jni_CallStaticFloatMethodV,
3438 jni_CallStaticFloatMethodA,
3439 jni_CallStaticDoubleMethod,
3440 jni_CallStaticDoubleMethodV,
3441 jni_CallStaticDoubleMethodA,
3442 jni_CallStaticVoidMethod,
3443 jni_CallStaticVoidMethodV,
3444 jni_CallStaticVoidMethodA,
3445
3446 jni_GetStaticFieldID,
3447
3448 jni_GetStaticObjectField,
3449 jni_GetStaticBooleanField,
3450 jni_GetStaticByteField,
3451 jni_GetStaticCharField,
3452 jni_GetStaticShortField,
3453 jni_GetStaticIntField,
3454 jni_GetStaticLongField,
3455 jni_GetStaticFloatField,
3456 jni_GetStaticDoubleField,
3457
3458 jni_SetStaticObjectField,
3459 jni_SetStaticBooleanField,
3460 jni_SetStaticByteField,
3461 jni_SetStaticCharField,
3462 jni_SetStaticShortField,
3463 jni_SetStaticIntField,
3464 jni_SetStaticLongField,
3465 jni_SetStaticFloatField,
3466 jni_SetStaticDoubleField,
3467
3468 jni_NewString,
3469 jni_GetStringLength,
3470 jni_GetStringChars,
3471 jni_ReleaseStringChars,
3472
3473 jni_NewStringUTF,
3474 jni_GetStringUTFLength,
3475 jni_GetStringUTFChars,
3476 jni_ReleaseStringUTFChars,
3477
3478 jni_GetArrayLength,
3479
3480 jni_NewObjectArray,
3481 jni_GetObjectArrayElement,
3482 jni_SetObjectArrayElement,
3483
3484 jni_NewBooleanArray,
3485 jni_NewByteArray,
3486 jni_NewCharArray,
3487 jni_NewShortArray,
3488 jni_NewIntArray,
3489 jni_NewLongArray,
3490 jni_NewFloatArray,
3491 jni_NewDoubleArray,
3492
3493 jni_GetBooleanArrayElements,
3494 jni_GetByteArrayElements,
3495 jni_GetCharArrayElements,
3496 jni_GetShortArrayElements,
3497 jni_GetIntArrayElements,
3498 jni_GetLongArrayElements,
3499 jni_GetFloatArrayElements,
3500 jni_GetDoubleArrayElements,
3501
3502 jni_ReleaseBooleanArrayElements,
3503 jni_ReleaseByteArrayElements,
3504 jni_ReleaseCharArrayElements,
3505 jni_ReleaseShortArrayElements,
3506 jni_ReleaseIntArrayElements,
3507 jni_ReleaseLongArrayElements,
3508 jni_ReleaseFloatArrayElements,
3509 jni_ReleaseDoubleArrayElements,
3510
3511 jni_GetBooleanArrayRegion,
3512 jni_GetByteArrayRegion,
3513 jni_GetCharArrayRegion,
3514 jni_GetShortArrayRegion,
3515 jni_GetIntArrayRegion,
3516 jni_GetLongArrayRegion,
3517 jni_GetFloatArrayRegion,
3518 jni_GetDoubleArrayRegion,
3519
3520 jni_SetBooleanArrayRegion,
3521 jni_SetByteArrayRegion,
3522 jni_SetCharArrayRegion,
3523 jni_SetShortArrayRegion,
3524 jni_SetIntArrayRegion,
3525 jni_SetLongArrayRegion,
3526 jni_SetFloatArrayRegion,
3527 jni_SetDoubleArrayRegion,
3528
3529 jni_RegisterNatives,
3530 jni_UnregisterNatives,
3531
3532 jni_MonitorEnter,
3533 jni_MonitorExit,
3534
3535 jni_GetJavaVM,
3536
3537 jni_GetStringRegion,
3538 jni_GetStringUTFRegion,
3539
3540 jni_GetPrimitiveArrayCritical,
3541 jni_ReleasePrimitiveArrayCritical,
3542
3543 jni_GetStringCritical,
3544 jni_ReleaseStringCritical,
3545
3546 jni_NewWeakGlobalRef,
3547 jni_DeleteWeakGlobalRef,
3548
3549 jni_ExceptionCheck,
3550
3551 jni_NewDirectByteBuffer,
3552 jni_GetDirectBufferAddress,
3553 jni_GetDirectBufferCapacity,
3554
3555 // New 1_6 features
3556
3557 jni_GetObjectRefType,
3558
3559 // Module features
3560
3561 jni_GetModule
3562 };
3563
3564
3565 // For jvmti use to modify jni function table.
3566 // Java threads in native contiues to run until it is transitioned
3567 // to VM at safepoint. Before the transition or before it is blocked
3568 // for safepoint it may access jni function table. VM could crash if
3569 // any java thread access the jni function table in the middle of memcpy.
3570 // To avoid this each function pointers are copied automically.
copy_jni_function_table(const struct JNINativeInterface_ * new_jni_NativeInterface)3571 void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {
3572 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
3573 intptr_t *a = (intptr_t *) jni_functions();
3574 intptr_t *b = (intptr_t *) new_jni_NativeInterface;
3575 for (uint i=0; i < sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {
3576 Atomic::store(a++, *b++);
3577 }
3578 }
3579
quicken_jni_functions()3580 void quicken_jni_functions() {
3581 // Replace Get<Primitive>Field with fast versions
3582 if (UseFastJNIAccessors && !VerifyJNIFields && !CountJNICalls && !CheckJNICalls) {
3583 address func;
3584 func = JNI_FastGetField::generate_fast_get_boolean_field();
3585 if (func != (address)-1) {
3586 jni_NativeInterface.GetBooleanField = (GetBooleanField_t)func;
3587 }
3588 func = JNI_FastGetField::generate_fast_get_byte_field();
3589 if (func != (address)-1) {
3590 jni_NativeInterface.GetByteField = (GetByteField_t)func;
3591 }
3592 func = JNI_FastGetField::generate_fast_get_char_field();
3593 if (func != (address)-1) {
3594 jni_NativeInterface.GetCharField = (GetCharField_t)func;
3595 }
3596 func = JNI_FastGetField::generate_fast_get_short_field();
3597 if (func != (address)-1) {
3598 jni_NativeInterface.GetShortField = (GetShortField_t)func;
3599 }
3600 func = JNI_FastGetField::generate_fast_get_int_field();
3601 if (func != (address)-1) {
3602 jni_NativeInterface.GetIntField = (GetIntField_t)func;
3603 }
3604 func = JNI_FastGetField::generate_fast_get_long_field();
3605 if (func != (address)-1) {
3606 jni_NativeInterface.GetLongField = (GetLongField_t)func;
3607 }
3608 func = JNI_FastGetField::generate_fast_get_float_field();
3609 if (func != (address)-1) {
3610 jni_NativeInterface.GetFloatField = (GetFloatField_t)func;
3611 }
3612 func = JNI_FastGetField::generate_fast_get_double_field();
3613 if (func != (address)-1) {
3614 jni_NativeInterface.GetDoubleField = (GetDoubleField_t)func;
3615 }
3616 }
3617 }
3618
3619 // Returns the function structure
jni_functions()3620 struct JNINativeInterface_* jni_functions() {
3621 #if INCLUDE_JNI_CHECK
3622 if (CheckJNICalls) return jni_functions_check();
3623 #endif // INCLUDE_JNI_CHECK
3624 return &jni_NativeInterface;
3625 }
3626
3627 // Returns the function structure
jni_functions_nocheck()3628 struct JNINativeInterface_* jni_functions_nocheck() {
3629 return &jni_NativeInterface;
3630 }
3631
post_thread_start_event(const JavaThread * jt)3632 static void post_thread_start_event(const JavaThread* jt) {
3633 assert(jt != NULL, "invariant");
3634 EventThreadStart event;
3635 if (event.should_commit()) {
3636 event.set_thread(JFR_THREAD_ID(jt));
3637 event.set_parentThread((traceid)0);
3638 #if INCLUDE_JFR
3639 if (EventThreadStart::is_stacktrace_enabled()) {
3640 jt->jfr_thread_local()->set_cached_stack_trace_id((traceid)0);
3641 event.commit();
3642 jt->jfr_thread_local()->clear_cached_stack_trace();
3643 } else
3644 #endif
3645 {
3646 event.commit();
3647 }
3648 }
3649 }
3650
3651 // Invocation API
3652
3653
3654 // Forward declaration
3655 extern const struct JNIInvokeInterface_ jni_InvokeInterface;
3656
3657 // Global invocation API vars
3658 volatile int vm_created = 0;
3659 // Indicate whether it is safe to recreate VM. Recreation is only
3660 // possible after a failed initial creation attempt in some cases.
3661 volatile int safe_to_recreate_vm = 1;
3662 struct JavaVM_ main_vm = {&jni_InvokeInterface};
3663
3664
3665 #define JAVASTACKSIZE (400 * 1024) /* Default size of a thread java stack */
3666 enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL };
3667
3668 DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint
3669 , HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN(_ret_ref));
3670
JNI_GetDefaultJavaVMInitArgs(void * args_)3671 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
3672 HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY(args_);
3673 JDK1_1InitArgs *args = (JDK1_1InitArgs *)args_;
3674 jint ret = JNI_ERR;
3675 DT_RETURN_MARK(GetDefaultJavaVMInitArgs, jint, (const jint&)ret);
3676
3677 if (Threads::is_supported_jni_version(args->version)) {
3678 ret = JNI_OK;
3679 }
3680 // 1.1 style no longer supported in hotspot.
3681 // According the JNI spec, we should update args->version on return.
3682 // We also use the structure to communicate with launcher about default
3683 // stack size.
3684 if (args->version == JNI_VERSION_1_1) {
3685 args->version = JNI_VERSION_1_2;
3686 // javaStackSize is int in arguments structure
3687 assert(jlong(ThreadStackSize) * K < INT_MAX, "integer overflow");
3688 args->javaStackSize = (jint)(ThreadStackSize * K);
3689 }
3690 return ret;
3691 }
3692
3693 DT_RETURN_MARK_DECL(CreateJavaVM, jint
3694 , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
3695
JNI_CreateJavaVM_inner(JavaVM ** vm,void ** penv,void * args)3696 static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
3697 HOTSPOT_JNI_CREATEJAVAVM_ENTRY((void **) vm, penv, args);
3698
3699 jint result = JNI_ERR;
3700 DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);
3701
3702 // We're about to use Atomic::xchg for synchronization. Some Zero
3703 // platforms use the GCC builtin __sync_lock_test_and_set for this,
3704 // but __sync_lock_test_and_set is not guaranteed to do what we want
3705 // on all architectures. So we check it works before relying on it.
3706 #if defined(ZERO) && defined(ASSERT)
3707 {
3708 jint a = 0xcafebabe;
3709 jint b = Atomic::xchg(&a, (jint) 0xdeadbeef);
3710 void *c = &a;
3711 void *d = Atomic::xchg(&c, &b);
3712 assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
3713 assert(c == &b && d == &a, "Atomic::xchg() works");
3714 }
3715 #endif // ZERO && ASSERT
3716
3717 // At the moment it's only possible to have one Java VM,
3718 // since some of the runtime state is in global variables.
3719
3720 // We cannot use our mutex locks here, since they only work on
3721 // Threads. We do an atomic compare and exchange to ensure only
3722 // one thread can call this method at a time
3723
3724 // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
3725 // the add/dec implementations are dependent on whether we are running
3726 // on a multiprocessor Atomic::xchg does not have this problem.
3727 if (Atomic::xchg(&vm_created, 1) == 1) {
3728 return JNI_EEXIST; // already created, or create attempt in progress
3729 }
3730
3731 // If a previous creation attempt failed but can be retried safely,
3732 // then safe_to_recreate_vm will have been reset to 1 after being
3733 // cleared here. If a previous creation attempt succeeded and we then
3734 // destroyed that VM, we will be prevented from trying to recreate
3735 // the VM in the same process, as the value will still be 0.
3736 if (Atomic::xchg(&safe_to_recreate_vm, 0) == 0) {
3737 return JNI_ERR;
3738 }
3739
3740 assert(vm_created == 1, "vm_created is true during the creation");
3741
3742 /**
3743 * Certain errors during initialization are recoverable and do not
3744 * prevent this method from being called again at a later time
3745 * (perhaps with different arguments). However, at a certain
3746 * point during initialization if an error occurs we cannot allow
3747 * this function to be called again (or it will crash). In those
3748 * situations, the 'canTryAgain' flag is set to false, which atomically
3749 * sets safe_to_recreate_vm to 1, such that any new call to
3750 * JNI_CreateJavaVM will immediately fail using the above logic.
3751 */
3752 bool can_try_again = true;
3753
3754 result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again);
3755 if (result == JNI_OK) {
3756 JavaThread *thread = JavaThread::current();
3757 assert(!thread->has_pending_exception(), "should have returned not OK");
3758 /* thread is thread_in_vm here */
3759 *vm = (JavaVM *)(&main_vm);
3760 *(JNIEnv**)penv = thread->jni_environment();
3761
3762 #if INCLUDE_JVMCI
3763 if (EnableJVMCI) {
3764 if (UseJVMCICompiler) {
3765 // JVMCI is initialized on a CompilerThread
3766 if (BootstrapJVMCI) {
3767 JavaThread* THREAD = thread;
3768 JVMCICompiler* compiler = JVMCICompiler::instance(true, CATCH);
3769 compiler->bootstrap(THREAD);
3770 if (HAS_PENDING_EXCEPTION) {
3771 HandleMark hm;
3772 vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
3773 }
3774 }
3775 }
3776 }
3777 #endif
3778
3779 // Notify JVMTI
3780 if (JvmtiExport::should_post_thread_life()) {
3781 JvmtiExport::post_thread_start(thread);
3782 }
3783
3784 post_thread_start_event(thread);
3785
3786 #ifndef PRODUCT
3787 if (ReplayCompiles) ciReplay::replay(thread);
3788
3789 // Some platforms (like Win*) need a wrapper around these test
3790 // functions in order to properly handle error conditions.
3791 VMError::test_error_handler();
3792 #endif
3793
3794 // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.
3795 ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_native);
3796 } else {
3797 // If create_vm exits because of a pending exception, exit with that
3798 // exception. In the future when we figure out how to reclaim memory,
3799 // we may be able to exit with JNI_ERR and allow the calling application
3800 // to continue.
3801 if (Universe::is_fully_initialized()) {
3802 // otherwise no pending exception possible - VM will already have aborted
3803 JavaThread* THREAD = JavaThread::current();
3804 if (HAS_PENDING_EXCEPTION) {
3805 HandleMark hm;
3806 vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
3807 }
3808 }
3809
3810 if (can_try_again) {
3811 // reset safe_to_recreate_vm to 1 so that retrial would be possible
3812 safe_to_recreate_vm = 1;
3813 }
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
JNI_CreateJavaVM(JavaVM ** vm,void ** penv,void * args)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
JNI_GetCreatedJavaVMs(JavaVM ** vm_buf,jsize bufLen,jsize * numVMs)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);
3859 return JNI_OK;
3860 }
3861
3862 extern "C" {
3863
3864 DT_RETURN_MARK_DECL(DestroyJavaVM, jint
3865 , HOTSPOT_JNI_DESTROYJAVAVM_RETURN(_ret_ref));
3866
jni_DestroyJavaVM_inner(JavaVM * vm)3867 static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) {
3868 HOTSPOT_JNI_DESTROYJAVAVM_ENTRY(vm);
3869 jint res = JNI_ERR;
3870 DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res);
3871
3872 if (vm_created == 0) {
3873 res = JNI_ERR;
3874 return res;
3875 }
3876
3877 JNIWrapper("DestroyJavaVM");
3878 JNIEnv *env;
3879 JavaVMAttachArgs destroyargs;
3880 destroyargs.version = CurrentVersion;
3881 destroyargs.name = (char *)"DestroyJavaVM";
3882 destroyargs.group = NULL;
3883 res = vm->AttachCurrentThread((void **)&env, (void *)&destroyargs);
3884 if (res != JNI_OK) {
3885 return res;
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
jni_DestroyJavaVM(JavaVM * vm)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
attach_current_thread(JavaVM * vm,void ** penv,void * _args,bool daemon)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.
3931 if (t->is_Java_thread()) {
3932 // If the thread has been attached this operation is a no-op
3933 *(JNIEnv**)penv = ((JavaThread*) t)->jni_environment();
3934 return JNI_OK;
3935 } else {
3936 return JNI_ERR;
3937 }
3938 }
3939
3940 // Create a thread and mark it as attaching so it will be skipped by the
3941 // ThreadsListEnumerator - see CR 6404306
3942 JavaThread* thread = new JavaThread(true);
3943
3944 // Set correct safepoint info. The thread is going to call into Java when
3945 // initializing the Java level thread object. Hence, the correct state must
3946 // be set in order for the Safepoint code to deal with it correctly.
3947 thread->set_thread_state(_thread_in_vm);
3948 thread->record_stack_base_and_size();
3949 thread->register_thread_stack_with_NMT();
3950 thread->initialize_thread_current();
3951
3952 if (!os::create_attached_thread(thread)) {
3953 thread->smr_delete();
3954 return JNI_ERR;
3955 }
3956 // Enable stack overflow checks
3957 thread->create_stack_guard_pages();
3958
3959 thread->initialize_tlab();
3960
3961 thread->cache_global_variables();
3962
3963 // This thread will not do a safepoint check, since it has
3964 // not been added to the Thread list yet.
3965 { MutexLocker ml(Threads_lock);
3966 // This must be inside this lock in order to get FullGCALot to work properly, i.e., to
3967 // avoid this thread trying to do a GC before it is added to the thread-list
3968 thread->set_active_handles(JNIHandleBlock::allocate_block());
3969 Threads::add(thread, daemon);
3970 }
3971 // Create thread group and name info from attach arguments
3972 oop group = NULL;
3973 char* thread_name = NULL;
3974 if (args != NULL && Threads::is_supported_jni_version(args->version)) {
3975 group = JNIHandles::resolve(args->group);
3976 thread_name = args->name; // may be NULL
3977 }
3978 if (group == NULL) group = Universe::main_thread_group();
3979
3980 // Create Java level thread object and attach it to this thread
3981 bool attach_failed = false;
3982 {
3983 EXCEPTION_MARK;
3984 HandleMark hm(THREAD);
3985 Handle thread_group(THREAD, group);
3986 thread->allocate_threadObj(thread_group, thread_name, daemon, THREAD);
3987 if (HAS_PENDING_EXCEPTION) {
3988 CLEAR_PENDING_EXCEPTION;
3989 // cleanup outside the handle mark.
3990 attach_failed = true;
3991 }
3992 }
3993
3994 if (attach_failed) {
3995 // Added missing cleanup
3996 thread->cleanup_failed_attach_current_thread(daemon);
3997 return JNI_ERR;
3998 }
3999
4000 // mark the thread as no longer attaching
4001 // this uses a fence to push the change through so we don't have
4002 // to regrab the threads_lock
4003 thread->set_done_attaching_via_jni();
4004
4005 // Set java thread status.
4006 java_lang_Thread::set_thread_status(thread->threadObj(),
4007 java_lang_Thread::RUNNABLE);
4008
4009 // Notify the debugger
4010 if (JvmtiExport::should_post_thread_life()) {
4011 JvmtiExport::post_thread_start(thread);
4012 }
4013
4014 post_thread_start_event(thread);
4015
4016 *(JNIEnv**)penv = thread->jni_environment();
4017
4018 // Now leaving the VM, so change thread_state. This is normally automatically taken care
4019 // of in the JVM_ENTRY. But in this situation we have to do it manually. Notice, that by
4020 // using ThreadStateTransition::transition, we do a callback to the safepoint code if
4021 // needed.
4022
4023 ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_native);
4024
4025 // Perform any platform dependent FPU setup
4026 os::setup_fpu();
4027
4028 return JNI_OK;
4029 }
4030
4031
jni_AttachCurrentThread(JavaVM * vm,void ** penv,void * _args)4032 jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) {
4033 HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(vm, penv, _args);
4034 if (vm_created == 0) {
4035 HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR);
4036 return JNI_ERR;
4037 }
4038
4039 JNIWrapper("AttachCurrentThread");
4040 jint ret = attach_current_thread(vm, penv, _args, false);
4041 HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(ret);
4042 return ret;
4043 }
4044
4045
jni_DetachCurrentThread(JavaVM * vm)4046 jint JNICALL jni_DetachCurrentThread(JavaVM *vm) {
4047 HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY(vm);
4048 if (vm_created == 0) {
4049 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_ERR);
4050 return JNI_ERR;
4051 }
4052
4053 JNIWrapper("DetachCurrentThread");
4054
4055 Thread* current = Thread::current_or_null();
4056
4057 // If the thread has already been detached the operation is a no-op
4058 if (current == NULL) {
4059 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);
4060 return JNI_OK;
4061 }
4062
4063 // If executing from an atexit hook we may be in the VMThread.
4064 if (!current->is_Java_thread()) {
4065 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR);
4066 return JNI_ERR;
4067 }
4068
4069 VM_Exit::block_if_vm_exited();
4070
4071 JavaThread* thread = (JavaThread*) current;
4072 if (thread->has_last_Java_frame()) {
4073 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR);
4074 // Can't detach a thread that's running java, that can't work.
4075 return JNI_ERR;
4076 }
4077
4078 // Safepoint support. Have to do call-back to safepoint code, if in the
4079 // middle of a safepoint operation
4080 ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
4081
4082 // XXX: Note that JavaThread::exit() call below removes the guards on the
4083 // stack pages set up via enable_stack_{red,yellow}_zone() calls
4084 // above in jni_AttachCurrentThread. Unfortunately, while the setting
4085 // of the guards is visible in jni_AttachCurrentThread above,
4086 // the removal of the guards is buried below in JavaThread::exit()
4087 // here. The abstraction should be more symmetrically either exposed
4088 // or hidden (e.g. it could probably be hidden in the same
4089 // (platform-dependent) methods where we do alternate stack
4090 // maintenance work?)
4091 thread->exit(false, JavaThread::jni_detach);
4092 thread->smr_delete();
4093
4094 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);
4095 return JNI_OK;
4096 }
4097
4098 DT_RETURN_MARK_DECL(GetEnv, jint
4099 , HOTSPOT_JNI_GETENV_RETURN(_ret_ref));
4100
jni_GetEnv(JavaVM * vm,void ** penv,jint version)4101 jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {
4102 HOTSPOT_JNI_GETENV_ENTRY(vm, penv, version);
4103 jint ret = JNI_ERR;
4104 DT_RETURN_MARK(GetEnv, jint, (const jint&)ret);
4105
4106 if (vm_created == 0) {
4107 *penv = NULL;
4108 ret = JNI_EDETACHED;
4109 return ret;
4110 }
4111
4112 if (JniExportedInterface::GetExportedInterface(vm, penv, version, &ret)) {
4113 return ret;
4114 }
4115
4116 #ifndef JVMPI_VERSION_1
4117 // need these in order to be polite about older agents
4118 #define JVMPI_VERSION_1 ((jint)0x10000001)
4119 #define JVMPI_VERSION_1_1 ((jint)0x10000002)
4120 #define JVMPI_VERSION_1_2 ((jint)0x10000003)
4121 #endif // !JVMPI_VERSION_1
4122
4123 Thread* thread = Thread::current_or_null();
4124 if (thread != NULL && thread->is_Java_thread()) {
4125 if (Threads::is_supported_jni_version_including_1_1(version)) {
4126 *(JNIEnv**)penv = ((JavaThread*) thread)->jni_environment();
4127 ret = JNI_OK;
4128 return ret;
4129
4130 } else if (version == JVMPI_VERSION_1 ||
4131 version == JVMPI_VERSION_1_1 ||
4132 version == JVMPI_VERSION_1_2) {
4133 tty->print_cr("ERROR: JVMPI, an experimental interface, is no longer supported.");
4134 tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");
4135 ret = JNI_EVERSION;
4136 return ret;
4137 } else if (JvmtiExport::is_jvmdi_version(version)) {
4138 tty->print_cr("FATAL ERROR: JVMDI is no longer supported.");
4139 tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");
4140 ret = JNI_EVERSION;
4141 return ret;
4142 } else {
4143 *penv = NULL;
4144 ret = JNI_EVERSION;
4145 return ret;
4146 }
4147 } else {
4148 *penv = NULL;
4149 ret = JNI_EDETACHED;
4150 return ret;
4151 }
4152 }
4153
4154
jni_AttachCurrentThreadAsDaemon(JavaVM * vm,void ** penv,void * _args)4155 jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) {
4156 HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(vm, penv, _args);
4157 if (vm_created == 0) {
4158 HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN((uint32_t) JNI_ERR);
4159 return JNI_ERR;
4160 }
4161
4162 JNIWrapper("AttachCurrentThreadAsDaemon");
4163 jint ret = attach_current_thread(vm, penv, _args, true);
4164 HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(ret);
4165 return ret;
4166 }
4167
4168
4169 } // End extern "C"
4170
4171 const struct JNIInvokeInterface_ jni_InvokeInterface = {
4172 NULL,
4173 NULL,
4174 NULL,
4175
4176 jni_DestroyJavaVM,
4177 jni_AttachCurrentThread,
4178 jni_DetachCurrentThread,
4179 jni_GetEnv,
4180 jni_AttachCurrentThreadAsDaemon
4181 };
4182