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