33 #include "classfile/javaThreadStatus.hpp"
34 #include "classfile/moduleEntry.hpp"
35 #include "classfile/modules.hpp"
36 #include "classfile/symbolTable.hpp"
37 #include "classfile/systemDictionary.hpp"
38 #include "classfile/vmClasses.hpp"
39 #include "classfile/vmSymbols.hpp"
40 #include "compiler/compiler_globals.hpp"
41 #include "gc/shared/collectedHeap.hpp"
42 #include "gc/shared/stringdedup/stringDedup.hpp"
43 #include "interpreter/linkResolver.hpp"
44 #include "jni.h"
45 #include "jvm.h"
46 #include "logging/log.hpp"
47 #include "memory/allocation.inline.hpp"
48 #include "memory/oopFactory.hpp"
49 #include "memory/resourceArea.hpp"
50 #include "memory/universe.hpp"
51 #include "nmt/memTracker.hpp"
52 #include "oops/access.inline.hpp"
53 #include "oops/arrayOop.hpp"
54 #include "oops/instanceKlass.inline.hpp"
55 #include "oops/instanceOop.hpp"
56 #include "oops/klass.inline.hpp"
57 #include "oops/markWord.hpp"
58 #include "oops/method.hpp"
59 #include "oops/objArrayKlass.hpp"
60 #include "oops/objArrayOop.inline.hpp"
61 #include "oops/oop.inline.hpp"
62 #include "oops/symbol.hpp"
63 #include "oops/typeArrayKlass.hpp"
64 #include "oops/typeArrayOop.inline.hpp"
65 #include "prims/jniCheck.hpp"
66 #include "prims/jniExport.hpp"
67 #include "prims/jniFastGetField.hpp"
68 #include "prims/jvm_misc.hpp"
69 #include "prims/jvmtiExport.hpp"
70 #include "prims/jvmtiThreadState.hpp"
71 #include "runtime/arguments.hpp"
72 #include "runtime/atomicAccess.hpp"
73 #include "runtime/fieldDescriptor.inline.hpp"
74 #include "runtime/handles.inline.hpp"
75 #include "runtime/interfaceSupport.inline.hpp"
76 #include "runtime/java.hpp"
77 #include "runtime/javaCalls.hpp"
78 #include "runtime/javaThread.inline.hpp"
79 #include "runtime/jfieldIDWorkaround.hpp"
80 #include "runtime/jniHandles.inline.hpp"
81 #include "runtime/reflection.hpp"
82 #include "runtime/safepointVerifiers.hpp"
83 #include "runtime/sharedRuntime.hpp"
84 #include "runtime/signature.hpp"
401 int modifiers = java_lang_reflect_Field::modifiers(reflected);
402
403 // Make sure class is initialized before handing id's out to fields
404 k1->initialize(CHECK_NULL);
405
406 // First check if this is a static field
407 if (modifiers & JVM_ACC_STATIC) {
408 int offset = InstanceKlass::cast(k1)->field_offset( slot );
409 JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
410 assert(id != nullptr, "corrupt Field object");
411 DEBUG_ONLY(id->set_is_static_field_id();)
412 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
413 ret = jfieldIDWorkaround::to_static_jfieldID(id);
414 return ret;
415 }
416
417 // The slot is the index of the field description in the field-array
418 // The jfieldID is the offset of the field within the object
419 // It may also have hash bits for k, if VerifyJNIFields is turned on.
420 int offset = InstanceKlass::cast(k1)->field_offset( slot );
421 assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
422 ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
423 return ret;
424 JNI_END
425
426
427 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
428 , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
429
430 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
431 HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
432
433 jobject ret = nullptr;
434 DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
435
436 methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
437 assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
438 oop reflection_method;
439 if (m->is_object_initializer()) {
440 reflection_method = Reflection::new_constructor(m, CHECK_NULL);
441 } else {
442 // Note: Static initializers can theoretically be here, if JNI users manage
443 // to get their jmethodID. Record them as plain methods.
444 reflection_method = Reflection::new_method(m, false, CHECK_NULL);
445 }
446 ret = JNIHandles::make_local(THREAD, reflection_method);
447 return ret;
448 JNI_END
449
450 DT_RETURN_MARK_DECL(GetSuperclass, jclass
451 , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
452
453 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
454 HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
455
456 jclass obj = nullptr;
457 DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
458
459 oop mirror = JNIHandles::resolve_non_null(sub);
1753 // table. If they're not there, the field doesn't exist.
1754 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
1755 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
1756 if (fieldname == nullptr || signame == nullptr) {
1757 ResourceMark rm;
1758 THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1759 }
1760
1761 // Make sure class is initialized before handing id's out to fields
1762 k->initialize(CHECK_NULL);
1763
1764 fieldDescriptor fd;
1765 if (!k->is_instance_klass() ||
1766 !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
1767 ResourceMark rm;
1768 THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1769 }
1770
1771 // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
1772 // It may also have hash bits for k, if VerifyJNIFields is turned on.
1773 ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset());
1774 return ret;
1775 JNI_END
1776
1777
1778 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
1779 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
1780 oop o = JNIHandles::resolve_non_null(obj);
1781 Klass* k = o->klass();
1782 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1783 // Keep JVMTI addition small and only check enabled flag here.
1784 // jni_GetField_probe() assumes that is okay to create handles.
1785 if (JvmtiExport::should_post_field_access()) {
1786 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
1787 }
1788 oop loaded_obj = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
1789 jobject ret = JNIHandles::make_local(THREAD, loaded_obj);
1790 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
1791 return ret;
1792 JNI_END
1793
1794
1795
1796 #define DEFINE_GETFIELD(Return,Fieldname,Result \
1797 , EntryProbe, ReturnProbe) \
1798 \
1799 DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
1800 , ReturnProbe); \
1801 \
1802 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
1803 \
1804 EntryProbe; \
1805 Return ret = 0;\
1806 DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
1807 \
1808 oop o = JNIHandles::resolve_non_null(obj); \
1809 Klass* k = o->klass(); \
1887 assert(found, "bad field offset");
1888 assert(!fd.is_static(), "static/instance mismatch");
1889 if (fd.is_final()) {
1890 ResourceMark rm(current);
1891 log_debug(jni)("%s mutated final instance field %s.%s", func_name, ik->external_name(), fd.name()->as_C_string());
1892 }
1893 }
1894 }
1895
1896 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
1897 HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
1898 oop o = JNIHandles::resolve_non_null(obj);
1899 Klass* k = o->klass();
1900 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1901 // Keep JVMTI addition small and only check enabled flag here.
1902 if (JvmtiExport::should_post_field_modification()) {
1903 jvalue field_value;
1904 field_value.l = value;
1905 o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
1906 }
1907 HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));
1908 log_debug_if_final_instance_field(thread, "SetObjectField", InstanceKlass::cast(k), offset);
1909 HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
1910 JNI_END
1911
1912 // TODO: make this a template
1913
1914 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1915 , EntryProbe, ReturnProbe) \
1916 \
1917 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1918 \
1919 EntryProbe; \
1920 \
1921 oop o = JNIHandles::resolve_non_null(obj); \
1922 Klass* k = o->klass(); \
1923 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
1924 /* Keep JVMTI addition small and only check enabled flag here. */ \
1925 if (JvmtiExport::should_post_field_modification()) { \
1926 jvalue field_value; \
1927 field_value.unionType = value; \
2318 ek->initialize(CHECK_NULL);
2319 objArrayOop result = oopFactory::new_objArray(ek, length, CHECK_NULL);
2320
2321 oop initial_value = JNIHandles::resolve(initialElement);
2322 if (initial_value != nullptr) { // array already initialized with null
2323 for (int index = 0; index < length; index++) {
2324 result->obj_at_put(index, initial_value);
2325 }
2326 }
2327 ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2328 return ret;
2329 JNI_END
2330
2331 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2332 , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2333
2334 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2335 HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2336 jobject ret = nullptr;
2337 DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2338 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2339 if (a->is_within_bounds(index)) {
2340 ret = JNIHandles::make_local(THREAD, a->obj_at(index));
2341 return ret;
2342 } else {
2343 ResourceMark rm(THREAD);
2344 stringStream ss;
2345 ss.print("Index %d out of bounds for length %d", index, a->length());
2346 THROW_MSG_NULL(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2347 }
2348 JNI_END
2349
2350 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2351 , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2352
2353 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2354 HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2355 DT_VOID_RETURN_MARK(SetObjectArrayElement);
2356
2357 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2358 oop v = JNIHandles::resolve(value);
2359 if (a->is_within_bounds(index)) {
2360 if (v == nullptr || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2361 a->obj_at_put(index, v);
2362 } else {
2363 ResourceMark rm(THREAD);
2364 stringStream ss;
2365 Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2366 ss.print("type mismatch: can not store %s to %s[%d]",
2367 v->klass()->external_name(),
2368 bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2369 index);
2370 for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2371 ss.print("[]");
2372 }
2373 THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2374 }
2375 } else {
2376 ResourceMark rm(THREAD);
2377 stringStream ss;
2378 ss.print("Index %d out of bounds for length %d", index, a->length());
2379 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2380 }
2381 JNI_END
2736 JNI_END
2737
2738 //
2739 // Monitor functions
2740 //
2741
2742 DT_RETURN_MARK_DECL(MonitorEnter, jint
2743 , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
2744
2745 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
2746 HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
2747 jint ret = JNI_ERR;
2748 DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
2749
2750 // If the object is null, we can't do anything with it
2751 if (jobj == nullptr) {
2752 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2753 }
2754
2755 Handle obj(thread, JNIHandles::resolve_non_null(jobj));
2756 ObjectSynchronizer::jni_enter(obj, thread);
2757 return JNI_OK;
2758 JNI_END
2759
2760 DT_RETURN_MARK_DECL(MonitorExit, jint
2761 , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
2762
2763 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
2764 HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
2765 jint ret = JNI_ERR;
2766 DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
2767
2768 // Don't do anything with a null object
2769 if (jobj == nullptr) {
2770 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2771 }
2772
2773 Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
2774 ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
2775 return JNI_OK;
2776 JNI_END
2895
2896 if (is_latin1) {
2897 // For latin1 string, free jchar array allocated by earlier call to GetStringCritical.
2898 // This assumes that ReleaseStringCritical bookends GetStringCritical.
2899 FREE_C_HEAP_ARRAY(jchar, chars);
2900 } else {
2901 // StringDedup can have replaced the value array, so don't fetch the array from 's'.
2902 // Instead, we calculate the address based on the jchar array exposed with GetStringCritical.
2903 oop value = cast_to_oop((address)chars - arrayOopDesc::base_offset_in_bytes(T_CHAR));
2904
2905 // Unpin value array
2906 Universe::heap()->unpin_object(thread, value);
2907 }
2908 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
2909 JNI_END
2910
2911
2912 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
2913 HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(env, ref);
2914 Handle ref_handle(thread, JNIHandles::resolve(ref));
2915 jweak ret = JNIHandles::make_weak_global(ref_handle, AllocFailStrategy::RETURN_NULL);
2916 if (ret == nullptr && ref_handle.not_null()) {
2917 THROW_OOP_(Universe::out_of_memory_error_c_heap(), nullptr);
2918 }
2919 HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(ret);
2920 return ret;
2921 JNI_END
2922
2923 // Must be JNI_ENTRY (with HandleMark)
2924 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
2925 HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(env, ref);
2926 JNIHandles::destroy_weak_global(ref);
2927 HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN();
2928 JNI_END
2929
2930
2931 JNI_ENTRY_NO_PRESERVE(jboolean, jni_ExceptionCheck(JNIEnv *env))
2932 HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(env);
2933 jni_check_async_exceptions(thread);
2934 jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;
3129
3130
3131 JNI_ENTRY(jobject, jni_GetModule(JNIEnv* env, jclass clazz))
3132 HOTSPOT_JNI_GETMODULE_ENTRY(env, clazz);
3133 jobject ret = Modules::get_module(clazz, THREAD);
3134 HOTSPOT_JNI_GETMODULE_RETURN(ret);
3135 return ret;
3136 JNI_END
3137
3138 JNI_ENTRY(jboolean, jni_IsVirtualThread(JNIEnv* env, jobject obj))
3139 HOTSPOT_JNI_ISVIRTUALTHREAD_ENTRY(env, obj);
3140 jboolean ret = JNI_FALSE;
3141 oop thread_obj = JNIHandles::resolve_external_guard(obj);
3142 if (thread_obj != nullptr && thread_obj->is_a(vmClasses::BaseVirtualThread_klass())) {
3143 ret = JNI_TRUE;
3144 }
3145 HOTSPOT_JNI_ISVIRTUALTHREAD_RETURN(ret);
3146 return ret;
3147 JNI_END
3148
3149
3150 // Structure containing all jni functions
3151 struct JNINativeInterface_ jni_NativeInterface = {
3152 nullptr,
3153 nullptr,
3154 nullptr,
3155
3156 nullptr,
3157
3158 jni_GetVersion,
3159
3160 jni_DefineClass,
3161 jni_FindClass,
3162
3163 jni_FromReflectedMethod,
3164 jni_FromReflectedField,
3165
3166 jni_ToReflectedMethod,
3167
3168 jni_GetSuperclass,
3421 jni_ExceptionCheck,
3422
3423 jni_NewDirectByteBuffer,
3424 jni_GetDirectBufferAddress,
3425 jni_GetDirectBufferCapacity,
3426
3427 // New 1_6 features
3428
3429 jni_GetObjectRefType,
3430
3431 // Module features
3432
3433 jni_GetModule,
3434
3435 // Virtual threads
3436
3437 jni_IsVirtualThread,
3438
3439 // Large UTF8 support
3440
3441 jni_GetStringUTFLengthAsLong
3442 };
3443
3444
3445 // For jvmti use to modify jni function table.
3446 // Java threads in native contiues to run until it is transitioned
3447 // to VM at safepoint. Before the transition or before it is blocked
3448 // for safepoint it may access jni function table. VM could crash if
3449 // any java thread access the jni function table in the middle of memcpy.
3450 // To avoid this each function pointers are copied automically.
3451 void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {
3452 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
3453 intptr_t *a = (intptr_t *) jni_functions();
3454 intptr_t *b = (intptr_t *) new_jni_NativeInterface;
3455 for (uint i=0; i < sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {
3456 AtomicAccess::store(a++, *b++);
3457 }
3458 }
3459
3460 void quicken_jni_functions() {
3461 // Replace Get<Primitive>Field with fast versions
|
33 #include "classfile/javaThreadStatus.hpp"
34 #include "classfile/moduleEntry.hpp"
35 #include "classfile/modules.hpp"
36 #include "classfile/symbolTable.hpp"
37 #include "classfile/systemDictionary.hpp"
38 #include "classfile/vmClasses.hpp"
39 #include "classfile/vmSymbols.hpp"
40 #include "compiler/compiler_globals.hpp"
41 #include "gc/shared/collectedHeap.hpp"
42 #include "gc/shared/stringdedup/stringDedup.hpp"
43 #include "interpreter/linkResolver.hpp"
44 #include "jni.h"
45 #include "jvm.h"
46 #include "logging/log.hpp"
47 #include "memory/allocation.inline.hpp"
48 #include "memory/oopFactory.hpp"
49 #include "memory/resourceArea.hpp"
50 #include "memory/universe.hpp"
51 #include "nmt/memTracker.hpp"
52 #include "oops/access.inline.hpp"
53 #include "oops/arrayOop.inline.hpp"
54 #include "oops/flatArrayOop.inline.hpp"
55 #include "oops/inlineKlass.inline.hpp"
56 #include "oops/instanceKlass.inline.hpp"
57 #include "oops/instanceOop.hpp"
58 #include "oops/klass.inline.hpp"
59 #include "oops/markWord.hpp"
60 #include "oops/method.hpp"
61 #include "oops/objArrayKlass.hpp"
62 #include "oops/objArrayOop.inline.hpp"
63 #include "oops/oop.inline.hpp"
64 #include "oops/oopCast.inline.hpp"
65 #include "oops/symbol.hpp"
66 #include "oops/typeArrayKlass.hpp"
67 #include "oops/typeArrayOop.inline.hpp"
68 #include "oops/valuePayload.inline.hpp"
69 #include "prims/jniCheck.hpp"
70 #include "prims/jniExport.hpp"
71 #include "prims/jniFastGetField.hpp"
72 #include "prims/jvm_misc.hpp"
73 #include "prims/jvmtiExport.hpp"
74 #include "prims/jvmtiThreadState.hpp"
75 #include "runtime/arguments.hpp"
76 #include "runtime/atomicAccess.hpp"
77 #include "runtime/fieldDescriptor.inline.hpp"
78 #include "runtime/handles.inline.hpp"
79 #include "runtime/interfaceSupport.inline.hpp"
80 #include "runtime/java.hpp"
81 #include "runtime/javaCalls.hpp"
82 #include "runtime/javaThread.inline.hpp"
83 #include "runtime/jfieldIDWorkaround.hpp"
84 #include "runtime/jniHandles.inline.hpp"
85 #include "runtime/reflection.hpp"
86 #include "runtime/safepointVerifiers.hpp"
87 #include "runtime/sharedRuntime.hpp"
88 #include "runtime/signature.hpp"
405 int modifiers = java_lang_reflect_Field::modifiers(reflected);
406
407 // Make sure class is initialized before handing id's out to fields
408 k1->initialize(CHECK_NULL);
409
410 // First check if this is a static field
411 if (modifiers & JVM_ACC_STATIC) {
412 int offset = InstanceKlass::cast(k1)->field_offset( slot );
413 JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
414 assert(id != nullptr, "corrupt Field object");
415 DEBUG_ONLY(id->set_is_static_field_id();)
416 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
417 ret = jfieldIDWorkaround::to_static_jfieldID(id);
418 return ret;
419 }
420
421 // The slot is the index of the field description in the field-array
422 // The jfieldID is the offset of the field within the object
423 // It may also have hash bits for k, if VerifyJNIFields is turned on.
424 int offset = InstanceKlass::cast(k1)->field_offset( slot );
425 bool is_flat = InstanceKlass::cast(k1)->field_is_flat(slot);
426 assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
427 ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset, is_flat);
428 return ret;
429 JNI_END
430
431
432 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
433 , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
434
435 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
436 HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
437
438 jobject ret = nullptr;
439 DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
440
441 methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
442 assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
443 oop reflection_method;
444 if (m->is_object_constructor()) {
445 reflection_method = Reflection::new_constructor(m, CHECK_NULL);
446 } else {
447 // Note: Static initializers can theoretically be here, if JNI users manage
448 // to get their jmethodID. Record them as plain methods.
449 reflection_method = Reflection::new_method(m, false, CHECK_NULL);
450 }
451 ret = JNIHandles::make_local(THREAD, reflection_method);
452 return ret;
453 JNI_END
454
455 DT_RETURN_MARK_DECL(GetSuperclass, jclass
456 , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
457
458 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
459 HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
460
461 jclass obj = nullptr;
462 DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
463
464 oop mirror = JNIHandles::resolve_non_null(sub);
1758 // table. If they're not there, the field doesn't exist.
1759 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
1760 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
1761 if (fieldname == nullptr || signame == nullptr) {
1762 ResourceMark rm;
1763 THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1764 }
1765
1766 // Make sure class is initialized before handing id's out to fields
1767 k->initialize(CHECK_NULL);
1768
1769 fieldDescriptor fd;
1770 if (!k->is_instance_klass() ||
1771 !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
1772 ResourceMark rm;
1773 THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1774 }
1775
1776 // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
1777 // It may also have hash bits for k, if VerifyJNIFields is turned on.
1778 ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset(), fd.is_flat());
1779 return ret;
1780 JNI_END
1781
1782
1783 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
1784 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
1785 oop o = JNIHandles::resolve_non_null(obj);
1786 Klass* k = o->klass();
1787 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1788 oop res = nullptr;
1789 // Keep JVMTI addition small and only check enabled flag here.
1790 // jni_GetField_probe() assumes that is okay to create handles.
1791 if (JvmtiExport::should_post_field_access()) {
1792 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
1793 }
1794 if (!jfieldIDWorkaround::is_flat_jfieldID(fieldID)) {
1795 res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
1796 } else {
1797 InstanceKlass* ik = InstanceKlass::cast(k);
1798 fieldDescriptor fd;
1799 bool found = ik->find_field_from_offset(offset, false, &fd); // performance bottleneck
1800 assert(found, "Field not found");
1801 FlatFieldPayload payload(instanceOop(o), &fd);
1802 res = payload.read(CHECK_NULL);
1803 }
1804 jobject ret = JNIHandles::make_local(THREAD, res);
1805 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
1806 return ret;
1807 JNI_END
1808
1809
1810
1811 #define DEFINE_GETFIELD(Return,Fieldname,Result \
1812 , EntryProbe, ReturnProbe) \
1813 \
1814 DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
1815 , ReturnProbe); \
1816 \
1817 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
1818 \
1819 EntryProbe; \
1820 Return ret = 0;\
1821 DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
1822 \
1823 oop o = JNIHandles::resolve_non_null(obj); \
1824 Klass* k = o->klass(); \
1902 assert(found, "bad field offset");
1903 assert(!fd.is_static(), "static/instance mismatch");
1904 if (fd.is_final()) {
1905 ResourceMark rm(current);
1906 log_debug(jni)("%s mutated final instance field %s.%s", func_name, ik->external_name(), fd.name()->as_C_string());
1907 }
1908 }
1909 }
1910
1911 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
1912 HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
1913 oop o = JNIHandles::resolve_non_null(obj);
1914 Klass* k = o->klass();
1915 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1916 // Keep JVMTI addition small and only check enabled flag here.
1917 if (JvmtiExport::should_post_field_modification()) {
1918 jvalue field_value;
1919 field_value.l = value;
1920 o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
1921 }
1922 if (!jfieldIDWorkaround::is_flat_jfieldID(fieldID)) {
1923 oop v = JNIHandles::resolve(value);
1924 if (v == nullptr) {
1925 InstanceKlass *ik = InstanceKlass::cast(k);
1926 fieldDescriptor fd;
1927 ik->find_field_from_offset(offset, false, &fd);
1928 if (fd.is_null_free_inline_type()) {
1929 THROW_MSG(vmSymbols::java_lang_NullPointerException(), "Cannot store null in a null-restricted field");
1930 }
1931 }
1932 HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, v);
1933 } else {
1934 assert(k->is_instance_klass(), "Only instances can have flat fields");
1935 InstanceKlass* ik = InstanceKlass::cast(k);
1936 fieldDescriptor fd;
1937 bool found = ik->find_field_from_offset(offset, false, &fd);
1938 assert(found, "Field not found");
1939 FlatFieldPayload payload(instanceOop(o), &fd);
1940 payload.write(inlineOop(JNIHandles::resolve(value)), CHECK);
1941 }
1942 log_debug_if_final_instance_field(thread, "SetObjectField", InstanceKlass::cast(k), offset);
1943 HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
1944 JNI_END
1945
1946 // TODO: make this a template
1947
1948 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1949 , EntryProbe, ReturnProbe) \
1950 \
1951 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1952 \
1953 EntryProbe; \
1954 \
1955 oop o = JNIHandles::resolve_non_null(obj); \
1956 Klass* k = o->klass(); \
1957 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
1958 /* Keep JVMTI addition small and only check enabled flag here. */ \
1959 if (JvmtiExport::should_post_field_modification()) { \
1960 jvalue field_value; \
1961 field_value.unionType = value; \
2352 ek->initialize(CHECK_NULL);
2353 objArrayOop result = oopFactory::new_objArray(ek, length, CHECK_NULL);
2354
2355 oop initial_value = JNIHandles::resolve(initialElement);
2356 if (initial_value != nullptr) { // array already initialized with null
2357 for (int index = 0; index < length; index++) {
2358 result->obj_at_put(index, initial_value);
2359 }
2360 }
2361 ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2362 return ret;
2363 JNI_END
2364
2365 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2366 , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2367
2368 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2369 HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2370 jobject ret = nullptr;
2371 DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2372 objArrayOop a = oop_cast<objArrayOop>(JNIHandles::resolve_non_null(array));
2373 if (a->is_within_bounds(index)) {
2374 oop res = a->obj_at(index, CHECK_NULL);
2375 assert(res != nullptr || !a->is_null_free_array(), "Invalid value");
2376 ret = JNIHandles::make_local(THREAD, res);
2377 return ret;
2378 } else {
2379 ResourceMark rm(THREAD);
2380 stringStream ss;
2381 ss.print("Index %d out of bounds for length %d", index, a->length());
2382 THROW_MSG_NULL(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2383 }
2384 JNI_END
2385
2386 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2387 , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2388
2389 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2390 HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2391 DT_VOID_RETURN_MARK(SetObjectArrayElement);
2392
2393 objArrayOop a = oop_cast<objArrayOop>(JNIHandles::resolve_non_null(array));
2394 oop v = JNIHandles::resolve(value);
2395 if (a->is_within_bounds(index)) {
2396 assert(a->klass()->is_refined_objArray_klass(), "must be");
2397 if (v == nullptr || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2398 a->obj_at_put(index, v, THREAD);
2399 return;
2400 } else {
2401 ResourceMark rm(THREAD);
2402 stringStream ss;
2403 Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2404 ss.print("type mismatch: can not store %s to %s[%d]",
2405 v->klass()->external_name(),
2406 bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2407 index);
2408 for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2409 ss.print("[]");
2410 }
2411 THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2412 }
2413 } else {
2414 ResourceMark rm(THREAD);
2415 stringStream ss;
2416 ss.print("Index %d out of bounds for length %d", index, a->length());
2417 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2418 }
2419 JNI_END
2774 JNI_END
2775
2776 //
2777 // Monitor functions
2778 //
2779
2780 DT_RETURN_MARK_DECL(MonitorEnter, jint
2781 , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
2782
2783 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
2784 HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
2785 jint ret = JNI_ERR;
2786 DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
2787
2788 // If the object is null, we can't do anything with it
2789 if (jobj == nullptr) {
2790 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2791 }
2792
2793 Handle obj(thread, JNIHandles::resolve_non_null(jobj));
2794 ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
2795 return JNI_OK;
2796 JNI_END
2797
2798 DT_RETURN_MARK_DECL(MonitorExit, jint
2799 , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
2800
2801 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
2802 HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
2803 jint ret = JNI_ERR;
2804 DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
2805
2806 // Don't do anything with a null object
2807 if (jobj == nullptr) {
2808 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2809 }
2810
2811 Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
2812 ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
2813 return JNI_OK;
2814 JNI_END
2933
2934 if (is_latin1) {
2935 // For latin1 string, free jchar array allocated by earlier call to GetStringCritical.
2936 // This assumes that ReleaseStringCritical bookends GetStringCritical.
2937 FREE_C_HEAP_ARRAY(jchar, chars);
2938 } else {
2939 // StringDedup can have replaced the value array, so don't fetch the array from 's'.
2940 // Instead, we calculate the address based on the jchar array exposed with GetStringCritical.
2941 oop value = cast_to_oop((address)chars - arrayOopDesc::base_offset_in_bytes(T_CHAR));
2942
2943 // Unpin value array
2944 Universe::heap()->unpin_object(thread, value);
2945 }
2946 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
2947 JNI_END
2948
2949
2950 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
2951 HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(env, ref);
2952 Handle ref_handle(thread, JNIHandles::resolve(ref));
2953
2954 if (!ref_handle.is_null() && ref_handle->klass()->is_inline_klass()) {
2955 ResourceMark rm(THREAD);
2956 stringStream ss;
2957 ss.print("%s is not an identity class", ref_handle->klass()->external_name());
2958 THROW_MSG_(vmSymbols::java_lang_IdentityException(), ss.as_string(), nullptr);
2959 }
2960
2961 jweak ret = JNIHandles::make_weak_global(ref_handle, AllocFailStrategy::RETURN_NULL);
2962 if (ret == nullptr && ref_handle.not_null()) {
2963 THROW_OOP_(Universe::out_of_memory_error_c_heap(), nullptr);
2964 }
2965 HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(ret);
2966 return ret;
2967 JNI_END
2968
2969 // Must be JNI_ENTRY (with HandleMark)
2970 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
2971 HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(env, ref);
2972 JNIHandles::destroy_weak_global(ref);
2973 HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN();
2974 JNI_END
2975
2976
2977 JNI_ENTRY_NO_PRESERVE(jboolean, jni_ExceptionCheck(JNIEnv *env))
2978 HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(env);
2979 jni_check_async_exceptions(thread);
2980 jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;
3175
3176
3177 JNI_ENTRY(jobject, jni_GetModule(JNIEnv* env, jclass clazz))
3178 HOTSPOT_JNI_GETMODULE_ENTRY(env, clazz);
3179 jobject ret = Modules::get_module(clazz, THREAD);
3180 HOTSPOT_JNI_GETMODULE_RETURN(ret);
3181 return ret;
3182 JNI_END
3183
3184 JNI_ENTRY(jboolean, jni_IsVirtualThread(JNIEnv* env, jobject obj))
3185 HOTSPOT_JNI_ISVIRTUALTHREAD_ENTRY(env, obj);
3186 jboolean ret = JNI_FALSE;
3187 oop thread_obj = JNIHandles::resolve_external_guard(obj);
3188 if (thread_obj != nullptr && thread_obj->is_a(vmClasses::BaseVirtualThread_klass())) {
3189 ret = JNI_TRUE;
3190 }
3191 HOTSPOT_JNI_ISVIRTUALTHREAD_RETURN(ret);
3192 return ret;
3193 JNI_END
3194
3195 JNI_ENTRY(jboolean, jni_IsValueObject(JNIEnv* env, jobject obj))
3196 HOTSPOT_JNI_ISVALUEOBJECT_ENTRY(env, obj);
3197 oop o = JNIHandles::resolve(obj);
3198 if (o != nullptr && o->klass()->is_inline_klass()) {
3199 HOTSPOT_JNI_ISVALUEOBJECT_RETURN(JNI_TRUE);
3200 return JNI_TRUE;
3201 } else {
3202 HOTSPOT_JNI_ISVALUEOBJECT_RETURN(JNI_FALSE);
3203 return JNI_FALSE;
3204 }
3205 JNI_END
3206
3207 // Structure containing all jni functions
3208 struct JNINativeInterface_ jni_NativeInterface = {
3209 nullptr,
3210 nullptr,
3211 nullptr,
3212
3213 nullptr,
3214
3215 jni_GetVersion,
3216
3217 jni_DefineClass,
3218 jni_FindClass,
3219
3220 jni_FromReflectedMethod,
3221 jni_FromReflectedField,
3222
3223 jni_ToReflectedMethod,
3224
3225 jni_GetSuperclass,
3478 jni_ExceptionCheck,
3479
3480 jni_NewDirectByteBuffer,
3481 jni_GetDirectBufferAddress,
3482 jni_GetDirectBufferCapacity,
3483
3484 // New 1_6 features
3485
3486 jni_GetObjectRefType,
3487
3488 // Module features
3489
3490 jni_GetModule,
3491
3492 // Virtual threads
3493
3494 jni_IsVirtualThread,
3495
3496 // Large UTF8 support
3497
3498 jni_GetStringUTFLengthAsLong,
3499
3500 // Value classes
3501
3502 jni_IsValueObject
3503 };
3504
3505
3506 // For jvmti use to modify jni function table.
3507 // Java threads in native contiues to run until it is transitioned
3508 // to VM at safepoint. Before the transition or before it is blocked
3509 // for safepoint it may access jni function table. VM could crash if
3510 // any java thread access the jni function table in the middle of memcpy.
3511 // To avoid this each function pointers are copied automically.
3512 void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {
3513 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
3514 intptr_t *a = (intptr_t *) jni_functions();
3515 intptr_t *b = (intptr_t *) new_jni_NativeInterface;
3516 for (uint i=0; i < sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {
3517 AtomicAccess::store(a++, *b++);
3518 }
3519 }
3520
3521 void quicken_jni_functions() {
3522 // Replace Get<Primitive>Field with fast versions
|