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 "ci/ciReplay.hpp"
28 #include "classfile/altHashing.hpp"
29 #include "classfile/classLoader.hpp"
30 #include "classfile/javaClasses.hpp"
31 #include "classfile/symbolTable.hpp"
32 #include "classfile/systemDictionary.hpp"
33 #include "classfile/vmSymbols.hpp"
34 #include "interpreter/linkResolver.hpp"
35 #include "jfr/jfrEvents.hpp"
36 #include "jfr/support/jfrThreadId.hpp"
37 #include "utilities/macros.hpp"
38 #include "utilities/ostream.hpp"
39 #if INCLUDE_ALL_GCS
40 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
41 #endif // INCLUDE_ALL_GCS
42 #include "memory/allocation.hpp"
43 #include "memory/allocation.inline.hpp"
44 #include "memory/gcLocker.inline.hpp"
45 #include "memory/oopFactory.hpp"
46 #include "memory/universe.inline.hpp"
47 #include "oops/instanceKlass.hpp"
48 #include "oops/instanceOop.hpp"
49 #include "oops/markOop.hpp"
50 #include "oops/method.hpp"
51 #include "oops/objArrayKlass.hpp"
52 #include "oops/objArrayOop.hpp"
53 #include "oops/oop.inline.hpp"
54 #include "oops/symbol.hpp"
55 #include "oops/typeArrayKlass.hpp"
56 #include "oops/typeArrayOop.hpp"
57 #include "prims/jni.h"
58 #include "prims/jniCheck.hpp"
59 #include "prims/jniExport.hpp"
60 #include "prims/jniFastGetField.hpp"
2613 JNIWrapper("GetObjectField");
2614 #ifndef USDT2
2615 DTRACE_PROBE3(hotspot_jni, GetObjectField__entry, env, obj, fieldID);
2616 #else /* USDT2 */
2617 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(
2618 env, obj, (uintptr_t) fieldID);
2619 #endif /* USDT2 */
2620 oop o = JNIHandles::resolve_non_null(obj);
2621 Klass* k = o->klass();
2622 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2623 // Keep JVMTI addition small and only check enabled flag here.
2624 // jni_GetField_probe() assumes that is okay to create handles.
2625 if (JvmtiExport::should_post_field_access()) {
2626 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2627 }
2628 jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
2629 #if INCLUDE_ALL_GCS
2630 // If G1 is enabled and we are accessing the value of the referent
2631 // field in a reference object then we need to register a non-null
2632 // referent with the SATB barrier.
2633 if (UseG1GC) {
2634 bool needs_barrier = false;
2635
2636 if (ret != NULL &&
2637 offset == java_lang_ref_Reference::referent_offset &&
2638 InstanceKlass::cast(k)->reference_type() != REF_NONE) {
2639 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
2640 needs_barrier = true;
2641 }
2642
2643 if (needs_barrier) {
2644 oop referent = JNIHandles::resolve(ret);
2645 G1SATBCardTableModRefBS::enqueue(referent);
2646 }
2647 }
2648 #endif // INCLUDE_ALL_GCS
2649 #ifndef USDT2
2650 DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret);
2651 #else /* USDT2 */
2652 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(
2653 ret);
4234 int s_len = java_lang_String::length(s);
4235 if (start < 0 || len < 0 || start > s_len - len) {
4236 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
4237 } else {
4238 //%note jni_7
4239 if (len > 0) {
4240 ResourceMark rm(THREAD);
4241 char *utf_region = java_lang_String::as_utf8_string(s, start, len);
4242 int utf_len = (int)strlen(utf_region);
4243 memcpy(buf, utf_region, utf_len);
4244 buf[utf_len] = 0;
4245 } else {
4246 // JDK null-terminates the buffer even in len is zero
4247 if (buf != NULL) {
4248 buf[0] = 0;
4249 }
4250 }
4251 }
4252 JNI_END
4253
4254
4255 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
4256 JNIWrapper("GetPrimitiveArrayCritical");
4257 #ifndef USDT2
4258 DTRACE_PROBE3(hotspot_jni, GetPrimitiveArrayCritical__entry, env, array, isCopy);
4259 #else /* USDT2 */
4260 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(
4261 env, array, (uintptr_t *) isCopy);
4262 #endif /* USDT2 */
4263 GC_locker::lock_critical(thread);
4264 if (isCopy != NULL) {
4265 *isCopy = JNI_FALSE;
4266 }
4267 oop a = JNIHandles::resolve_non_null(array);
4268 assert(a->is_array(), "just checking");
4269 BasicType type;
4270 if (a->is_objArray()) {
4271 type = T_OBJECT;
4272 } else {
4273 type = TypeArrayKlass::cast(a->klass())->element_type();
4274 }
4275 void* ret = arrayOop(a)->base(type);
4276 #ifndef USDT2
4277 DTRACE_PROBE1(hotspot_jni, GetPrimitiveArrayCritical__return, ret);
4278 #else /* USDT2 */
4279 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(
4280 ret);
4281 #endif /* USDT2 */
4282 return ret;
4283 JNI_END
4284
4285
4286 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
4287 JNIWrapper("ReleasePrimitiveArrayCritical");
4288 #ifndef USDT2
4289 DTRACE_PROBE4(hotspot_jni, ReleasePrimitiveArrayCritical__entry, env, array, carray, mode);
4290 #else /* USDT2 */
4291 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(
4292 env, array, carray, mode);
4293 #endif /* USDT2 */
4294 // The array, carray and mode arguments are ignored
4295 GC_locker::unlock_critical(thread);
4296 #ifndef USDT2
4297 DTRACE_PROBE(hotspot_jni, ReleasePrimitiveArrayCritical__return);
4298 #else /* USDT2 */
4299 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN(
4300 );
4301 #endif /* USDT2 */
4302 JNI_END
4303
4304
4305 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
4306 JNIWrapper("GetStringCritical");
4307 #ifndef USDT2
4308 DTRACE_PROBE3(hotspot_jni, GetStringCritical__entry, env, string, isCopy);
4309 #else /* USDT2 */
4310 HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(
4311 env, string, (uintptr_t *) isCopy);
4312 #endif /* USDT2 */
4313 GC_locker::lock_critical(thread);
4314 if (isCopy != NULL) {
4315 *isCopy = JNI_FALSE;
4316 }
4317 oop s = JNIHandles::resolve_non_null(string);
4318 int s_len = java_lang_String::length(s);
4319 typeArrayOop s_value = java_lang_String::value(s);
4320 int s_offset = java_lang_String::offset(s);
4321 const jchar* ret;
4322 if (s_len > 0) {
4323 ret = s_value->char_at_addr(s_offset);
4324 } else {
4325 ret = (jchar*) s_value->base(T_CHAR);
4326 }
4327 #ifndef USDT2
4328 DTRACE_PROBE1(hotspot_jni, GetStringCritical__return, ret);
4329 #else /* USDT2 */
4330 HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN(
4331 (uint16_t *) ret);
4332 #endif /* USDT2 */
4333 return ret;
4334 JNI_END
4335
4336
4337 JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
4338 JNIWrapper("ReleaseStringCritical");
4339 #ifndef USDT2
4340 DTRACE_PROBE3(hotspot_jni, ReleaseStringCritical__entry, env, str, chars);
4341 #else /* USDT2 */
4342 HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(
4343 env, str, (uint16_t *) chars);
4344 #endif /* USDT2 */
4345 // The str and chars arguments are ignored
4346 GC_locker::unlock_critical(thread);
4347 #ifndef USDT2
4348 DTRACE_PROBE(hotspot_jni, ReleaseStringCritical__return);
4349 #else /* USDT2 */
4350 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN(
4351 );
4352 #endif /* USDT2 */
4353 JNI_END
4354
4355
4356 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
4357 JNIWrapper("jni_NewWeakGlobalRef");
4358 #ifndef USDT2
4359 DTRACE_PROBE2(hotspot_jni, NewWeakGlobalRef__entry, env, ref);
4360 #else /* USDT2 */
4361 HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(
4362 env, ref);
4363 #endif /* USDT2 */
4364 Handle ref_handle(thread, JNIHandles::resolve(ref));
4365 jweak ret = JNIHandles::make_weak_global(ref_handle);
4366 #ifndef USDT2
|
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 "ci/ciReplay.hpp"
28 #include "classfile/altHashing.hpp"
29 #include "classfile/classLoader.hpp"
30 #include "classfile/javaClasses.hpp"
31 #include "classfile/symbolTable.hpp"
32 #include "classfile/systemDictionary.hpp"
33 #include "classfile/vmSymbols.hpp"
34 #include "interpreter/linkResolver.hpp"
35 #include "jfr/jfrEvents.hpp"
36 #include "jfr/support/jfrThreadId.hpp"
37 #include "utilities/macros.hpp"
38 #include "utilities/ostream.hpp"
39 #if INCLUDE_ALL_GCS
40 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
41 #include "gc_implementation/shenandoah/shenandoahStringDedup.hpp"
42 #endif // INCLUDE_ALL_GCS
43 #include "memory/allocation.hpp"
44 #include "memory/allocation.inline.hpp"
45 #include "memory/gcLocker.inline.hpp"
46 #include "memory/oopFactory.hpp"
47 #include "memory/universe.inline.hpp"
48 #include "oops/instanceKlass.hpp"
49 #include "oops/instanceOop.hpp"
50 #include "oops/markOop.hpp"
51 #include "oops/method.hpp"
52 #include "oops/objArrayKlass.hpp"
53 #include "oops/objArrayOop.hpp"
54 #include "oops/oop.inline.hpp"
55 #include "oops/symbol.hpp"
56 #include "oops/typeArrayKlass.hpp"
57 #include "oops/typeArrayOop.hpp"
58 #include "prims/jni.h"
59 #include "prims/jniCheck.hpp"
60 #include "prims/jniExport.hpp"
61 #include "prims/jniFastGetField.hpp"
2614 JNIWrapper("GetObjectField");
2615 #ifndef USDT2
2616 DTRACE_PROBE3(hotspot_jni, GetObjectField__entry, env, obj, fieldID);
2617 #else /* USDT2 */
2618 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(
2619 env, obj, (uintptr_t) fieldID);
2620 #endif /* USDT2 */
2621 oop o = JNIHandles::resolve_non_null(obj);
2622 Klass* k = o->klass();
2623 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2624 // Keep JVMTI addition small and only check enabled flag here.
2625 // jni_GetField_probe() assumes that is okay to create handles.
2626 if (JvmtiExport::should_post_field_access()) {
2627 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2628 }
2629 jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
2630 #if INCLUDE_ALL_GCS
2631 // If G1 is enabled and we are accessing the value of the referent
2632 // field in a reference object then we need to register a non-null
2633 // referent with the SATB barrier.
2634 if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) {
2635 bool needs_barrier = false;
2636
2637 if (ret != NULL &&
2638 offset == java_lang_ref_Reference::referent_offset &&
2639 InstanceKlass::cast(k)->reference_type() != REF_NONE) {
2640 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
2641 needs_barrier = true;
2642 }
2643
2644 if (needs_barrier) {
2645 oop referent = JNIHandles::resolve(ret);
2646 G1SATBCardTableModRefBS::enqueue(referent);
2647 }
2648 }
2649 #endif // INCLUDE_ALL_GCS
2650 #ifndef USDT2
2651 DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret);
2652 #else /* USDT2 */
2653 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(
2654 ret);
4235 int s_len = java_lang_String::length(s);
4236 if (start < 0 || len < 0 || start > s_len - len) {
4237 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
4238 } else {
4239 //%note jni_7
4240 if (len > 0) {
4241 ResourceMark rm(THREAD);
4242 char *utf_region = java_lang_String::as_utf8_string(s, start, len);
4243 int utf_len = (int)strlen(utf_region);
4244 memcpy(buf, utf_region, utf_len);
4245 buf[utf_len] = 0;
4246 } else {
4247 // JDK null-terminates the buffer even in len is zero
4248 if (buf != NULL) {
4249 buf[0] = 0;
4250 }
4251 }
4252 }
4253 JNI_END
4254
4255 static oop lock_gc_or_pin_object(JavaThread* thread, jobject obj) {
4256 if (Universe::heap()->supports_object_pinning()) {
4257 const oop o = JNIHandles::resolve_non_null(obj);
4258 return Universe::heap()->pin_object(thread, o);
4259 } else {
4260 GC_locker::lock_critical(thread);
4261 return JNIHandles::resolve_non_null(obj);
4262 }
4263 }
4264
4265 static void unlock_gc_or_unpin_object(JavaThread* thread, jobject obj) {
4266 if (Universe::heap()->supports_object_pinning()) {
4267 const oop o = JNIHandles::resolve_non_null(obj);
4268 return Universe::heap()->unpin_object(thread, o);
4269 } else {
4270 GC_locker::unlock_critical(thread);
4271 }
4272 }
4273
4274 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
4275 JNIWrapper("GetPrimitiveArrayCritical");
4276 #ifndef USDT2
4277 DTRACE_PROBE3(hotspot_jni, GetPrimitiveArrayCritical__entry, env, array, isCopy);
4278 #else /* USDT2 */
4279 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(
4280 env, array, (uintptr_t *) isCopy);
4281 #endif /* USDT2 */
4282 if (isCopy != NULL) {
4283 *isCopy = JNI_FALSE;
4284 }
4285 oop a = lock_gc_or_pin_object(thread, array);
4286 assert(a->is_array(), "just checking");
4287 BasicType type;
4288 if (a->is_objArray()) {
4289 type = T_OBJECT;
4290 } else {
4291 type = TypeArrayKlass::cast(a->klass())->element_type();
4292 }
4293 void* ret = arrayOop(a)->base(type);
4294 #ifndef USDT2
4295 DTRACE_PROBE1(hotspot_jni, GetPrimitiveArrayCritical__return, ret);
4296 #else /* USDT2 */
4297 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(
4298 ret);
4299 #endif /* USDT2 */
4300 return ret;
4301 JNI_END
4302
4303
4304 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
4305 JNIWrapper("ReleasePrimitiveArrayCritical");
4306 #ifndef USDT2
4307 DTRACE_PROBE4(hotspot_jni, ReleasePrimitiveArrayCritical__entry, env, array, carray, mode);
4308 #else /* USDT2 */
4309 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(
4310 env, array, carray, mode);
4311 #endif /* USDT2 */
4312 // The array, carray and mode arguments are ignored
4313 unlock_gc_or_unpin_object(thread, array);
4314 #ifndef USDT2
4315 DTRACE_PROBE(hotspot_jni, ReleasePrimitiveArrayCritical__return);
4316 #else /* USDT2 */
4317 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN(
4318 );
4319 #endif /* USDT2 */
4320 JNI_END
4321
4322
4323 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
4324 JNIWrapper("GetStringCritical");
4325 #ifndef USDT2
4326 DTRACE_PROBE3(hotspot_jni, GetStringCritical__entry, env, string, isCopy);
4327 #else /* USDT2 */
4328 HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(
4329 env, string, (uintptr_t *) isCopy);
4330 #endif /* USDT2 */
4331 jchar* ret;
4332 if (!UseShenandoahGC) {
4333 GC_locker::lock_critical(thread);
4334 if (isCopy != NULL) {
4335 *isCopy = JNI_FALSE;
4336 }
4337 oop s = JNIHandles::resolve_non_null(string);
4338 int s_len = java_lang_String::length(s);
4339 typeArrayOop s_value = java_lang_String::value(s);
4340 int s_offset = java_lang_String::offset(s);
4341 if (s_len > 0) {
4342 ret = s_value->char_at_addr(s_offset);
4343 } else {
4344 ret = (jchar*) s_value->base(T_CHAR);
4345 }
4346 }
4347 #if INCLUDE_ALL_GCS
4348 else {
4349 assert(UseShenandoahGC, "This path should only be taken with Shenandoah");
4350 oop s = JNIHandles::resolve_non_null(string);
4351 if (ShenandoahStringDedup::is_enabled()) {
4352 typeArrayOop s_value = java_lang_String::value(s);
4353 int s_len = java_lang_String::length(s);
4354 ret = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination
4355 /* JNI Specification states return NULL on OOM */
4356 if (ret != NULL) {
4357 memcpy(ret, s_value->char_at_addr(0), s_len * sizeof(jchar));
4358 ret[s_len] = 0;
4359 }
4360 if (isCopy != NULL) *isCopy = JNI_TRUE;
4361 } else {
4362 typeArrayOop s_value = java_lang_String::value(s);
4363 s_value = (typeArrayOop) Universe::heap()->pin_object(thread, s_value);
4364 ret = (jchar *) s_value->base(T_CHAR);
4365 if (isCopy != NULL) *isCopy = JNI_FALSE;
4366 }
4367 }
4368 #else
4369 else {
4370 ShouldNotReachHere();
4371 }
4372 #endif
4373 #ifndef USDT2
4374 DTRACE_PROBE1(hotspot_jni, GetStringCritical__return, ret);
4375 #else /* USDT2 */
4376 HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN(
4377 (uint16_t *) ret);
4378 #endif /* USDT2 */
4379 return ret;
4380 JNI_END
4381
4382
4383 JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
4384 JNIWrapper("ReleaseStringCritical");
4385 #ifndef USDT2
4386 DTRACE_PROBE3(hotspot_jni, ReleaseStringCritical__entry, env, str, chars);
4387 #else /* USDT2 */
4388 HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(
4389 env, str, (uint16_t *) chars);
4390 #endif /* USDT2 */
4391 if (!UseShenandoahGC) {
4392 // The str and chars arguments are ignored
4393 GC_locker::unlock_critical(thread);
4394 }
4395 #if INCLUDE_ALL_GCS
4396 else if (ShenandoahStringDedup::is_enabled()) {
4397 assert(UseShenandoahGC, "This path should only be taken with Shenandoah");
4398 // For copied string value, free jchar array allocated by earlier call to GetStringCritical.
4399 // This assumes that ReleaseStringCritical bookends GetStringCritical.
4400 FREE_C_HEAP_ARRAY(jchar, chars, mtInternal);
4401 } else {
4402 assert(UseShenandoahGC, "This path should only be taken with Shenandoah");
4403 oop s = JNIHandles::resolve_non_null(str);
4404 // For not copied string value, drop the associated gc-locker/pin.
4405 typeArrayOop s_value = java_lang_String::value(s);
4406 Universe::heap()->unpin_object(thread, s_value);
4407 }
4408 #else
4409 else {
4410 ShouldNotReachHere();
4411 }
4412 #endif
4413 #ifndef USDT2
4414 DTRACE_PROBE(hotspot_jni, ReleaseStringCritical__return);
4415 #else /* USDT2 */
4416 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN(
4417 );
4418 #endif /* USDT2 */
4419 JNI_END
4420
4421
4422 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
4423 JNIWrapper("jni_NewWeakGlobalRef");
4424 #ifndef USDT2
4425 DTRACE_PROBE2(hotspot_jni, NewWeakGlobalRef__entry, env, ref);
4426 #else /* USDT2 */
4427 HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(
4428 env, ref);
4429 #endif /* USDT2 */
4430 Handle ref_handle(thread, JNIHandles::resolve(ref));
4431 jweak ret = JNIHandles::make_weak_global(ref_handle);
4432 #ifndef USDT2
|