< prev index next >

src/share/vm/prims/jni.cpp

Print this page




  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


< prev index next >