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