322 jclass cls = NULL;
323 DT_RETURN_MARK(DefineClass, jclass, (const jclass&)cls);
324
325 TempNewSymbol class_name = NULL;
326 // Since exceptions can be thrown, class initialization can take place
327 // if name is NULL no check for class name in .class stream has to be made.
328 if (name != NULL) {
329 const int str_len = (int)strlen(name);
330 if (str_len > Symbol::max_length()) {
331 // It's impossible to create this class; the name cannot fit
332 // into the constant pool.
333 THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
334 }
335 class_name = SymbolTable::new_symbol(name, CHECK_NULL);
336 }
337 ResourceMark rm(THREAD);
338 ClassFileStream st((u1*) buf, bufLen, NULL);
339 Handle class_loader (THREAD, JNIHandles::resolve(loaderRef));
340
341 if (UsePerfData && !class_loader.is_null()) {
342 // check whether the current caller thread holds the lock or not.
343 // If not, increment the corresponding counter
344 if (ObjectSynchronizer::
345 query_lock_ownership((JavaThread*)THREAD, class_loader) !=
346 ObjectSynchronizer::owner_self) {
347 ClassLoader::sync_JNIDefineClassLockFreeCounter()->inc();
348 }
349 }
350 Klass* k = SystemDictionary::resolve_from_stream(class_name, class_loader,
351 Handle(), &st, true,
352 CHECK_NULL);
353
354 if (TraceClassResolution && k != NULL) {
355 trace_class_resolution(k);
356 }
357
358 cls = (jclass)JNIHandles::make_local(
359 env, k->java_mirror());
360 return cls;
361 JNI_END
362
363
364
365 static bool first_time_FindClass = true;
561 // super2 is the value computed by the compiler's getSuperClass intrinsic:
562 debug_only(Klass* super2 = ( k->oop_is_array()
563 ? SystemDictionary::Object_klass()
564 : k->super() ) );
565 assert(super == super2,
566 "java_super computation depends on interface, array, other super");
567 obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(super->java_mirror());
568 return obj;
569 JNI_END
570
571 JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
572 JNIWrapper("IsSubclassOf");
573
574 HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
575
576 oop sub_mirror = JNIHandles::resolve_non_null(sub);
577 oop super_mirror = JNIHandles::resolve_non_null(super);
578 if (java_lang_Class::is_primitive(sub_mirror) ||
579 java_lang_Class::is_primitive(super_mirror)) {
580 jboolean ret = (sub_mirror == super_mirror);
581
582 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
583 return ret;
584 }
585 Klass* sub_klass = java_lang_Class::as_Klass(sub_mirror);
586 Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
587 assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
588 jboolean ret = sub_klass->is_subtype_of(super_klass) ?
589 JNI_TRUE : JNI_FALSE;
590
591 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
592 return ret;
593 JNI_END
594
595
596 DT_RETURN_MARK_DECL(Throw, jint
597 , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
598
599 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
600 JNIWrapper("Throw");
601
803
804 JNI_QUICK_ENTRY(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj))
805 JNIWrapper("DeleteLocalRef");
806
807 HOTSPOT_JNI_DELETELOCALREF_ENTRY(env, obj);
808
809 JNIHandles::destroy_local(obj);
810
811 HOTSPOT_JNI_DELETELOCALREF_RETURN();
812 JNI_END
813
814 JNI_QUICK_ENTRY(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))
815 JNIWrapper("IsSameObject");
816
817 HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(env, r1, r2);
818
819 oop a = JNIHandles::resolve(r1);
820 oop b = JNIHandles::resolve(r2);
821 jboolean ret = (a == b) ? JNI_TRUE : JNI_FALSE;
822
823 HOTSPOT_JNI_ISSAMEOBJECT_RETURN(ret);
824 return ret;
825 JNI_END
826
827
828 JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))
829 JNIWrapper("NewLocalRef");
830
831 HOTSPOT_JNI_NEWLOCALREF_ENTRY(env, ref);
832
833 jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));
834
835 HOTSPOT_JNI_NEWLOCALREF_RETURN(ret);
836 return ret;
837 JNI_END
838
839 JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))
840 JNIWrapper("EnsureLocalCapacity");
841
842 HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY(env, capacity);
2045 return ret;
2046 JNI_END
2047
2048
2049 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
2050 JNIWrapper("GetObjectField");
2051 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
2052 oop o = JNIHandles::resolve_non_null(obj);
2053 Klass* k = o->klass();
2054 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2055 // Keep JVMTI addition small and only check enabled flag here.
2056 // jni_GetField_probe() assumes that is okay to create handles.
2057 if (JvmtiExport::should_post_field_access()) {
2058 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2059 }
2060 jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
2061 #if INCLUDE_ALL_GCS
2062 // If G1 is enabled and we are accessing the value of the referent
2063 // field in a reference object then we need to register a non-null
2064 // referent with the SATB barrier.
2065 if (UseG1GC) {
2066 bool needs_barrier = false;
2067
2068 if (ret != NULL &&
2069 offset == java_lang_ref_Reference::referent_offset &&
2070 InstanceKlass::cast(k)->reference_type() != REF_NONE) {
2071 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
2072 needs_barrier = true;
2073 }
2074
2075 if (needs_barrier) {
2076 oop referent = JNIHandles::resolve(ret);
2077 G1SATBCardTableModRefBS::enqueue(referent);
2078 }
2079 }
2080 #endif // INCLUDE_ALL_GCS
2081 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
2082 return ret;
2083 JNI_END
2084
2085
2698 if (bad_address != NULL) {
2699 os::protect_memory(bad_address, size, os::MEM_PROT_READ,
2700 /*is_committed*/false);
2701 MemTracker::record_virtual_memory_type((void*)bad_address, mtInternal);
2702 }
2703 }
2704 return bad_address;
2705 }
2706
2707
2708
2709 #define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \
2710 , EntryProbe, ReturnProbe) \
2711 \
2712 JNI_QUICK_ENTRY(ElementType*, \
2713 jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \
2714 JNIWrapper("Get" XSTR(Result) "ArrayElements"); \
2715 EntryProbe; \
2716 /* allocate an chunk of memory in c land */ \
2717 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2718 ElementType* result; \
2719 int len = a->length(); \
2720 if (len == 0) { \
2721 /* Empty array: legal but useless, can't return NULL. \
2722 * Return a pointer to something useless. \
2723 * Avoid asserts in typeArrayOop. */ \
2724 result = (ElementType*)get_bad_address(); \
2725 } else { \
2726 /* JNI Specification states return NULL on OOM */ \
2727 result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
2728 if (result != NULL) { \
2729 /* copy the array to the c chunk */ \
2730 memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
2731 if (isCopy) { \
2732 *isCopy = JNI_TRUE; \
2733 } \
2734 } \
2735 } \
2736 ReturnProbe; \
2737 return result; \
2756 , HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2757 HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(((uintptr_t*)result)))
2758 // Float and double probes don't return value because dtrace doesn't currently support it
2759 DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float
2760 , HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2761 HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result))
2762 DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double
2763 , HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2764 HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(result))
2765
2766
2767 #define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \
2768 , EntryProbe, ReturnProbe);\
2769 \
2770 JNI_QUICK_ENTRY(void, \
2771 jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \
2772 ElementType *buf, jint mode)) \
2773 JNIWrapper("Release" XSTR(Result) "ArrayElements"); \
2774 EntryProbe; \
2775 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2776 int len = a->length(); \
2777 if (len != 0) { /* Empty array: nothing to free or copy. */ \
2778 if ((mode == 0) || (mode == JNI_COMMIT)) { \
2779 memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \
2780 } \
2781 if ((mode == 0) || (mode == JNI_ABORT)) { \
2782 FreeHeap(buf); \
2783 } \
2784 } \
2785 ReturnProbe; \
2786 JNI_END
2787
2788 DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
2789 , HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
2790 HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN())
2791 DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte
2792 , HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode),
2793 HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN())
2794 DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT, jshort, Short, short
2795 , HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
2806 DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float
2807 , HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode),
2808 HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN())
2809 DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double
2810 , HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode),
2811 HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN())
2812
2813
2814 #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
2815 , EntryProbe, ReturnProbe); \
2816 DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion \
2817 , ReturnProbe); \
2818 \
2819 JNI_ENTRY(void, \
2820 jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
2821 jsize len, ElementType *buf)) \
2822 JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \
2823 EntryProbe; \
2824 DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
2825 typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2826 if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \
2827 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
2828 } else { \
2829 if (len > 0) { \
2830 int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \
2831 memcpy((u_char*) buf, \
2832 (u_char*) src->Tag##_at_addr(start), \
2833 len << sc); \
2834 } \
2835 } \
2836 JNI_END
2837
2838 DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool
2839 , HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
2840 HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN());
2841 DEFINE_GETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte
2842 , HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
2843 HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN());
2844 DEFINE_GETSCALARARRAYREGION(T_SHORT, jshort, Short, short
2845 , HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
2856 DEFINE_GETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float
2857 , HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
2858 HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN());
2859 DEFINE_GETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double
2860 , HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
2861 HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN());
2862
2863
2864 #define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
2865 , EntryProbe, ReturnProbe); \
2866 DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion \
2867 ,ReturnProbe); \
2868 \
2869 JNI_ENTRY(void, \
2870 jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
2871 jsize len, const ElementType *buf)) \
2872 JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
2873 EntryProbe; \
2874 DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
2875 typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2876 if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \
2877 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
2878 } else { \
2879 if (len > 0) { \
2880 int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \
2881 memcpy((u_char*) dst->Tag##_at_addr(start), \
2882 (u_char*) buf, \
2883 len << sc); \
2884 } \
2885 } \
2886 JNI_END
2887
2888 DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool
2889 , HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf),
2890 HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN())
2891 DEFINE_SETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte
2892 , HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
2893 HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN())
2894 DEFINE_SETSCALARARRAYREGION(T_SHORT, jshort, Short, short
2895 , HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
3054 return 0;
3055 JNI_END
3056
3057 //
3058 // Monitor functions
3059 //
3060
3061 DT_RETURN_MARK_DECL(MonitorEnter, jint
3062 , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
3063
3064 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
3065 HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
3066 jint ret = JNI_ERR;
3067 DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
3068
3069 // If the object is null, we can't do anything with it
3070 if (jobj == NULL) {
3071 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
3072 }
3073
3074 Handle obj(thread, JNIHandles::resolve_non_null(jobj));
3075 ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
3076 ret = JNI_OK;
3077 return ret;
3078 JNI_END
3079
3080 DT_RETURN_MARK_DECL(MonitorExit, jint
3081 , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
3082
3083 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
3084 HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
3085 jint ret = JNI_ERR;
3086 DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
3087
3088 // Don't do anything with a null object
3089 if (jobj == NULL) {
3090 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
3091 }
3092
3093 Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
3094 ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
3095
3096 ret = JNI_OK;
3097 return ret;
3098 JNI_END
3099
3100 //
3101 // Extensions
3102 //
3103
3104 DT_VOID_RETURN_MARK_DECL(GetStringRegion
3105 , HOTSPOT_JNI_GETSTRINGREGION_RETURN());
3106
3107 JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf))
3108 JNIWrapper("GetStringRegion");
3109 HOTSPOT_JNI_GETSTRINGREGION_ENTRY(env, string, start, len, buf);
3110 DT_VOID_RETURN_MARK(GetStringRegion);
3111 oop s = JNIHandles::resolve_non_null(string);
3112 int s_len = java_lang_String::length(s);
3113 if (start < 0 || len < 0 || start + len > s_len) {
3139 java_lang_String::as_utf8_string(s, start, len, buf, INT_MAX);
3140 // as_utf8_string null-terminates the result string
3141 } else {
3142 // JDK null-terminates the buffer even in len is zero
3143 if (buf != NULL) {
3144 buf[0] = 0;
3145 }
3146 }
3147 }
3148 JNI_END
3149
3150
3151 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
3152 JNIWrapper("GetPrimitiveArrayCritical");
3153 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(env, array, (uintptr_t *) isCopy);
3154 GC_locker::lock_critical(thread);
3155 if (isCopy != NULL) {
3156 *isCopy = JNI_FALSE;
3157 }
3158 oop a = JNIHandles::resolve_non_null(array);
3159 assert(a->is_array(), "just checking");
3160 BasicType type;
3161 if (a->is_objArray()) {
3162 type = T_OBJECT;
3163 } else {
3164 type = TypeArrayKlass::cast(a->klass())->element_type();
3165 }
3166 void* ret = arrayOop(a)->base(type);
3167 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(ret);
3168 return ret;
3169 JNI_END
3170
3171
3172 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
3173 JNIWrapper("ReleasePrimitiveArrayCritical");
3174 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(env, array, carray, mode);
3175 // The array, carray and mode arguments are ignored
3176 GC_locker::unlock_critical(thread);
3177 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN();
3178 JNI_END
|
322 jclass cls = NULL;
323 DT_RETURN_MARK(DefineClass, jclass, (const jclass&)cls);
324
325 TempNewSymbol class_name = NULL;
326 // Since exceptions can be thrown, class initialization can take place
327 // if name is NULL no check for class name in .class stream has to be made.
328 if (name != NULL) {
329 const int str_len = (int)strlen(name);
330 if (str_len > Symbol::max_length()) {
331 // It's impossible to create this class; the name cannot fit
332 // into the constant pool.
333 THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
334 }
335 class_name = SymbolTable::new_symbol(name, CHECK_NULL);
336 }
337 ResourceMark rm(THREAD);
338 ClassFileStream st((u1*) buf, bufLen, NULL);
339 Handle class_loader (THREAD, JNIHandles::resolve(loaderRef));
340
341 if (UsePerfData && !class_loader.is_null()) {
342 Handle class_loader1 (THREAD, oopDesc::bs()->write_barrier(class_loader()));
343 // check whether the current caller thread holds the lock or not.
344 // If not, increment the corresponding counter
345 if (ObjectSynchronizer::
346 query_lock_ownership((JavaThread*)THREAD, class_loader1) !=
347 ObjectSynchronizer::owner_self) {
348 ClassLoader::sync_JNIDefineClassLockFreeCounter()->inc();
349 }
350 }
351 Klass* k = SystemDictionary::resolve_from_stream(class_name, class_loader,
352 Handle(), &st, true,
353 CHECK_NULL);
354
355 if (TraceClassResolution && k != NULL) {
356 trace_class_resolution(k);
357 }
358
359 cls = (jclass)JNIHandles::make_local(
360 env, k->java_mirror());
361 return cls;
362 JNI_END
363
364
365
366 static bool first_time_FindClass = true;
562 // super2 is the value computed by the compiler's getSuperClass intrinsic:
563 debug_only(Klass* super2 = ( k->oop_is_array()
564 ? SystemDictionary::Object_klass()
565 : k->super() ) );
566 assert(super == super2,
567 "java_super computation depends on interface, array, other super");
568 obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(super->java_mirror());
569 return obj;
570 JNI_END
571
572 JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
573 JNIWrapper("IsSubclassOf");
574
575 HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
576
577 oop sub_mirror = JNIHandles::resolve_non_null(sub);
578 oop super_mirror = JNIHandles::resolve_non_null(super);
579 if (java_lang_Class::is_primitive(sub_mirror) ||
580 java_lang_Class::is_primitive(super_mirror)) {
581 jboolean ret = (sub_mirror == super_mirror);
582 if (UseShenandoahGC && ret == JNI_FALSE) {
583 sub_mirror = oopDesc::bs()->read_barrier(sub_mirror);
584 super_mirror = oopDesc::bs()->read_barrier(super_mirror);
585 ret = (sub_mirror == super_mirror);
586 }
587 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
588 return ret;
589 }
590 Klass* sub_klass = java_lang_Class::as_Klass(sub_mirror);
591 Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
592 assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
593 jboolean ret = sub_klass->is_subtype_of(super_klass) ?
594 JNI_TRUE : JNI_FALSE;
595
596 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
597 return ret;
598 JNI_END
599
600
601 DT_RETURN_MARK_DECL(Throw, jint
602 , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
603
604 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
605 JNIWrapper("Throw");
606
808
809 JNI_QUICK_ENTRY(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj))
810 JNIWrapper("DeleteLocalRef");
811
812 HOTSPOT_JNI_DELETELOCALREF_ENTRY(env, obj);
813
814 JNIHandles::destroy_local(obj);
815
816 HOTSPOT_JNI_DELETELOCALREF_RETURN();
817 JNI_END
818
819 JNI_QUICK_ENTRY(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))
820 JNIWrapper("IsSameObject");
821
822 HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(env, r1, r2);
823
824 oop a = JNIHandles::resolve(r1);
825 oop b = JNIHandles::resolve(r2);
826 jboolean ret = (a == b) ? JNI_TRUE : JNI_FALSE;
827
828 if (UseShenandoahGC && ret == JNI_FALSE) {
829 a = oopDesc::bs()->read_barrier(a);
830 b = oopDesc::bs()->read_barrier(b);
831 ret = (a == b) ? JNI_TRUE : JNI_FALSE;
832 }
833 HOTSPOT_JNI_ISSAMEOBJECT_RETURN(ret);
834 return ret;
835 JNI_END
836
837
838 JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))
839 JNIWrapper("NewLocalRef");
840
841 HOTSPOT_JNI_NEWLOCALREF_ENTRY(env, ref);
842
843 jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));
844
845 HOTSPOT_JNI_NEWLOCALREF_RETURN(ret);
846 return ret;
847 JNI_END
848
849 JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))
850 JNIWrapper("EnsureLocalCapacity");
851
852 HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY(env, capacity);
2055 return ret;
2056 JNI_END
2057
2058
2059 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
2060 JNIWrapper("GetObjectField");
2061 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
2062 oop o = JNIHandles::resolve_non_null(obj);
2063 Klass* k = o->klass();
2064 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2065 // Keep JVMTI addition small and only check enabled flag here.
2066 // jni_GetField_probe() assumes that is okay to create handles.
2067 if (JvmtiExport::should_post_field_access()) {
2068 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2069 }
2070 jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
2071 #if INCLUDE_ALL_GCS
2072 // If G1 is enabled and we are accessing the value of the referent
2073 // field in a reference object then we need to register a non-null
2074 // referent with the SATB barrier.
2075 if (UseG1GC || UseShenandoahGC) {
2076 bool needs_barrier = false;
2077
2078 if (ret != NULL &&
2079 offset == java_lang_ref_Reference::referent_offset &&
2080 InstanceKlass::cast(k)->reference_type() != REF_NONE) {
2081 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
2082 needs_barrier = true;
2083 }
2084
2085 if (needs_barrier) {
2086 oop referent = JNIHandles::resolve(ret);
2087 G1SATBCardTableModRefBS::enqueue(referent);
2088 }
2089 }
2090 #endif // INCLUDE_ALL_GCS
2091 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
2092 return ret;
2093 JNI_END
2094
2095
2708 if (bad_address != NULL) {
2709 os::protect_memory(bad_address, size, os::MEM_PROT_READ,
2710 /*is_committed*/false);
2711 MemTracker::record_virtual_memory_type((void*)bad_address, mtInternal);
2712 }
2713 }
2714 return bad_address;
2715 }
2716
2717
2718
2719 #define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \
2720 , EntryProbe, ReturnProbe) \
2721 \
2722 JNI_QUICK_ENTRY(ElementType*, \
2723 jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \
2724 JNIWrapper("Get" XSTR(Result) "ArrayElements"); \
2725 EntryProbe; \
2726 /* allocate an chunk of memory in c land */ \
2727 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2728 a = typeArrayOop(oopDesc::bs()->read_barrier(a)); \
2729 ElementType* result; \
2730 int len = a->length(); \
2731 if (len == 0) { \
2732 /* Empty array: legal but useless, can't return NULL. \
2733 * Return a pointer to something useless. \
2734 * Avoid asserts in typeArrayOop. */ \
2735 result = (ElementType*)get_bad_address(); \
2736 } else { \
2737 /* JNI Specification states return NULL on OOM */ \
2738 result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
2739 if (result != NULL) { \
2740 /* copy the array to the c chunk */ \
2741 memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
2742 if (isCopy) { \
2743 *isCopy = JNI_TRUE; \
2744 } \
2745 } \
2746 } \
2747 ReturnProbe; \
2748 return result; \
2767 , HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2768 HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(((uintptr_t*)result)))
2769 // Float and double probes don't return value because dtrace doesn't currently support it
2770 DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float
2771 , HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2772 HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result))
2773 DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double
2774 , HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2775 HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(result))
2776
2777
2778 #define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \
2779 , EntryProbe, ReturnProbe);\
2780 \
2781 JNI_QUICK_ENTRY(void, \
2782 jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \
2783 ElementType *buf, jint mode)) \
2784 JNIWrapper("Release" XSTR(Result) "ArrayElements"); \
2785 EntryProbe; \
2786 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2787 a = typeArrayOop(oopDesc::bs()->write_barrier(a)); \
2788 int len = a->length(); \
2789 if (len != 0) { /* Empty array: nothing to free or copy. */ \
2790 if ((mode == 0) || (mode == JNI_COMMIT)) { \
2791 memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \
2792 } \
2793 if ((mode == 0) || (mode == JNI_ABORT)) { \
2794 FreeHeap(buf); \
2795 } \
2796 } \
2797 ReturnProbe; \
2798 JNI_END
2799
2800 DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
2801 , HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
2802 HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN())
2803 DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte
2804 , HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode),
2805 HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN())
2806 DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT, jshort, Short, short
2807 , HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
2818 DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float
2819 , HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode),
2820 HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN())
2821 DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double
2822 , HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode),
2823 HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN())
2824
2825
2826 #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
2827 , EntryProbe, ReturnProbe); \
2828 DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion \
2829 , ReturnProbe); \
2830 \
2831 JNI_ENTRY(void, \
2832 jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
2833 jsize len, ElementType *buf)) \
2834 JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \
2835 EntryProbe; \
2836 DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
2837 typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2838 src = typeArrayOop(oopDesc::bs()->read_barrier(src)); \
2839 if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \
2840 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
2841 } else { \
2842 if (len > 0) { \
2843 int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \
2844 memcpy((u_char*) buf, \
2845 (u_char*) src->Tag##_at_addr(start), \
2846 len << sc); \
2847 } \
2848 } \
2849 JNI_END
2850
2851 DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool
2852 , HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
2853 HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN());
2854 DEFINE_GETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte
2855 , HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
2856 HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN());
2857 DEFINE_GETSCALARARRAYREGION(T_SHORT, jshort, Short, short
2858 , HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
2869 DEFINE_GETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float
2870 , HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
2871 HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN());
2872 DEFINE_GETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double
2873 , HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
2874 HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN());
2875
2876
2877 #define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
2878 , EntryProbe, ReturnProbe); \
2879 DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion \
2880 ,ReturnProbe); \
2881 \
2882 JNI_ENTRY(void, \
2883 jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
2884 jsize len, const ElementType *buf)) \
2885 JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
2886 EntryProbe; \
2887 DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
2888 typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2889 dst = typeArrayOop(oopDesc::bs()->write_barrier(dst)); \
2890 if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \
2891 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
2892 } else { \
2893 if (len > 0) { \
2894 int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \
2895 memcpy((u_char*) dst->Tag##_at_addr(start), \
2896 (u_char*) buf, \
2897 len << sc); \
2898 } \
2899 } \
2900 JNI_END
2901
2902 DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool
2903 , HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf),
2904 HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN())
2905 DEFINE_SETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte
2906 , HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
2907 HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN())
2908 DEFINE_SETSCALARARRAYREGION(T_SHORT, jshort, Short, short
2909 , HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
3068 return 0;
3069 JNI_END
3070
3071 //
3072 // Monitor functions
3073 //
3074
3075 DT_RETURN_MARK_DECL(MonitorEnter, jint
3076 , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
3077
3078 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
3079 HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
3080 jint ret = JNI_ERR;
3081 DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
3082
3083 // If the object is null, we can't do anything with it
3084 if (jobj == NULL) {
3085 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
3086 }
3087
3088 Handle obj(thread, oopDesc::bs()->write_barrier(JNIHandles::resolve_non_null(jobj)));
3089 ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
3090 ret = JNI_OK;
3091 return ret;
3092 JNI_END
3093
3094 DT_RETURN_MARK_DECL(MonitorExit, jint
3095 , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
3096
3097 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
3098 HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
3099 jint ret = JNI_ERR;
3100 DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
3101
3102 // Don't do anything with a null object
3103 if (jobj == NULL) {
3104 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
3105 }
3106
3107 Handle obj(THREAD, oopDesc::bs()->write_barrier(JNIHandles::resolve_non_null(jobj)));
3108 ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
3109
3110 ret = JNI_OK;
3111 return ret;
3112 JNI_END
3113
3114 //
3115 // Extensions
3116 //
3117
3118 DT_VOID_RETURN_MARK_DECL(GetStringRegion
3119 , HOTSPOT_JNI_GETSTRINGREGION_RETURN());
3120
3121 JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf))
3122 JNIWrapper("GetStringRegion");
3123 HOTSPOT_JNI_GETSTRINGREGION_ENTRY(env, string, start, len, buf);
3124 DT_VOID_RETURN_MARK(GetStringRegion);
3125 oop s = JNIHandles::resolve_non_null(string);
3126 int s_len = java_lang_String::length(s);
3127 if (start < 0 || len < 0 || start + len > s_len) {
3153 java_lang_String::as_utf8_string(s, start, len, buf, INT_MAX);
3154 // as_utf8_string null-terminates the result string
3155 } else {
3156 // JDK null-terminates the buffer even in len is zero
3157 if (buf != NULL) {
3158 buf[0] = 0;
3159 }
3160 }
3161 }
3162 JNI_END
3163
3164
3165 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
3166 JNIWrapper("GetPrimitiveArrayCritical");
3167 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(env, array, (uintptr_t *) isCopy);
3168 GC_locker::lock_critical(thread);
3169 if (isCopy != NULL) {
3170 *isCopy = JNI_FALSE;
3171 }
3172 oop a = JNIHandles::resolve_non_null(array);
3173 a = oopDesc::bs()->write_barrier(a);
3174 assert(a->is_array(), "just checking");
3175 BasicType type;
3176 if (a->is_objArray()) {
3177 type = T_OBJECT;
3178 } else {
3179 type = TypeArrayKlass::cast(a->klass())->element_type();
3180 }
3181 void* ret = arrayOop(a)->base(type);
3182 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(ret);
3183 return ret;
3184 JNI_END
3185
3186
3187 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
3188 JNIWrapper("ReleasePrimitiveArrayCritical");
3189 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(env, array, carray, mode);
3190 // The array, carray and mode arguments are ignored
3191 GC_locker::unlock_critical(thread);
3192 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN();
3193 JNI_END
|