319 HOTSPOT_JNI_DEFINECLASS_ENTRY(
320 env, (char*) name, loaderRef, (char*) buf, bufLen);
321
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());
558
559 // return mirror for superclass
560 Klass* super = k->java_super();
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));
800
801 HOTSPOT_JNI_DELETEGLOBALREF_RETURN();
802 JNI_END
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");
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
2450
2451 JNI_QUICK_ENTRY(jsize, jni_GetStringLength(JNIEnv *env, jstring string))
2452 JNIWrapper("GetStringLength");
2453 HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(env, string);
2454 jsize ret = 0;
2455 oop s = JNIHandles::resolve_non_null(string);
2456 if (java_lang_String::value(s) != NULL) {
2457 ret = java_lang_String::length(s);
2458 }
2459 HOTSPOT_JNI_GETSTRINGLENGTH_RETURN(ret);
2460 return ret;
2461 JNI_END
2462
2463
2464 JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars(
2465 JNIEnv *env, jstring string, jboolean *isCopy))
2466 JNIWrapper("GetStringChars");
2467 HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(env, string, (uintptr_t *) isCopy);
2468 jchar* buf = NULL;
2469 oop s = JNIHandles::resolve_non_null(string);
2470 typeArrayOop s_value = java_lang_String::value(s);
2471 if (s_value != NULL) {
2472 int s_len = java_lang_String::length(s);
2473 int s_offset = java_lang_String::offset(s);
2474 buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination
2475 /* JNI Specification states return NULL on OOM */
2476 if (buf != NULL) {
2477 if (s_len > 0) {
2478 memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
2479 }
2480 buf[s_len] = 0;
2481 //%note jni_5
2482 if (isCopy != NULL) {
2483 *isCopy = JNI_TRUE;
2484 }
2485 }
2486 }
2487 HOTSPOT_JNI_GETSTRINGCHARS_RETURN(buf);
2488 return buf;
2489 JNI_END
2490
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) {
3114 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
3115 } else {
3116 if (len > 0) {
3117 int s_offset = java_lang_String::offset(s);
3118 typeArrayOop s_value = java_lang_String::value(s);
3119 memcpy(buf, s_value->char_at_addr(s_offset+start), sizeof(jchar)*len);
3120 }
3121 }
3122 JNI_END
3123
3124 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion
3125 , HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN());
3126
3127 JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf))
3128 JNIWrapper("GetStringUTFRegion");
3129 HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(env, string, start, len, buf);
3130 DT_VOID_RETURN_MARK(GetStringUTFRegion);
3131 oop s = JNIHandles::resolve_non_null(string);
3132 int s_len = java_lang_String::length(s);
3133 if (start < 0 || len < 0 || start + len > s_len) {
3134 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
3135 } else {
3136 //%note jni_7
3137 if (len > 0) {
3138 // Assume the buffer is large enough as the JNI spec. does not require user error checking
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
3179
3180
3181 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
3182 JNIWrapper("GetStringCritical");
3183 HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(env, string, (uintptr_t *) isCopy);
3184 GC_locker::lock_critical(thread);
3185 if (isCopy != NULL) {
3186 *isCopy = JNI_FALSE;
3187 }
3188 oop s = JNIHandles::resolve_non_null(string);
3189 int s_len = java_lang_String::length(s);
3190 typeArrayOop s_value = java_lang_String::value(s);
3191 int s_offset = java_lang_String::offset(s);
3192 const jchar* ret;
3193 if (s_len > 0) {
3194 ret = s_value->char_at_addr(s_offset);
3195 } else {
3196 ret = (jchar*) s_value->base(T_CHAR);
3197 }
3198 HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN((uint16_t *) ret);
3199 return ret;
3200 JNI_END
3201
3202
3203 JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
3204 JNIWrapper("ReleaseStringCritical");
3205 HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(env, str, (uint16_t *) chars);
3206 // The str and chars arguments are ignored
3207 GC_locker::unlock_critical(thread);
3208 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
3209 JNI_END
3210
|
319 HOTSPOT_JNI_DEFINECLASS_ENTRY(
320 env, (char*) name, loaderRef, (char*) buf, bufLen);
321
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, oopDesc::bs()->write_barrier(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());
558
559 // return mirror for superclass
560 Klass* super = k->java_super();
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
579 sub_mirror = oopDesc::bs()->write_barrier(sub_mirror);
580 super_mirror = oopDesc::bs()->write_barrier(super_mirror);
581
582 if (java_lang_Class::is_primitive(sub_mirror) ||
583 java_lang_Class::is_primitive(super_mirror)) {
584 jboolean ret = (sub_mirror == super_mirror);
585
586 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
587 return ret;
588 }
589 Klass* sub_klass = java_lang_Class::as_Klass(sub_mirror);
590 Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
591 assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
592 jboolean ret = sub_klass->is_subtype_of(super_klass) ?
593 JNI_TRUE : JNI_FALSE;
594
595 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
596 return ret;
597 JNI_END
598
599
600 DT_RETURN_MARK_DECL(Throw, jint
601 , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
804
805 HOTSPOT_JNI_DELETEGLOBALREF_RETURN();
806 JNI_END
807
808 JNI_QUICK_ENTRY(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj))
809 JNIWrapper("DeleteLocalRef");
810
811 HOTSPOT_JNI_DELETELOCALREF_ENTRY(env, obj);
812
813 JNIHandles::destroy_local(obj);
814
815 HOTSPOT_JNI_DELETELOCALREF_RETURN();
816 JNI_END
817
818 JNI_QUICK_ENTRY(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))
819 JNIWrapper("IsSameObject");
820
821 HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(env, r1, r2);
822
823 oop a = JNIHandles::resolve(r1);
824 a = oopDesc::bs()->write_barrier(a);
825 oop b = JNIHandles::resolve(r2);
826 b = oopDesc::bs()->write_barrier(b);
827 jboolean ret = (a == b) ? JNI_TRUE : JNI_FALSE;
828
829 HOTSPOT_JNI_ISSAMEOBJECT_RETURN(ret);
830 return ret;
831 JNI_END
832
833
834 JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))
835 JNIWrapper("NewLocalRef");
836
837 HOTSPOT_JNI_NEWLOCALREF_ENTRY(env, ref);
838
839 jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));
840
841 HOTSPOT_JNI_NEWLOCALREF_RETURN(ret);
842 return ret;
843 JNI_END
844
845 JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))
846 JNIWrapper("EnsureLocalCapacity");
2051 return ret;
2052 JNI_END
2053
2054
2055 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
2056 JNIWrapper("GetObjectField");
2057 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
2058 oop o = JNIHandles::resolve_non_null(obj);
2059 Klass* k = o->klass();
2060 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2061 // Keep JVMTI addition small and only check enabled flag here.
2062 // jni_GetField_probe() assumes that is okay to create handles.
2063 if (JvmtiExport::should_post_field_access()) {
2064 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2065 }
2066 jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
2067 #if INCLUDE_ALL_GCS
2068 // If G1 is enabled and we are accessing the value of the referent
2069 // field in a reference object then we need to register a non-null
2070 // referent with the SATB barrier.
2071 if (UseG1GC || UseShenandoahGC) {
2072 bool needs_barrier = false;
2073
2074 if (ret != NULL &&
2075 offset == java_lang_ref_Reference::referent_offset &&
2076 InstanceKlass::cast(k)->reference_type() != REF_NONE) {
2077 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
2078 needs_barrier = true;
2079 }
2080
2081 if (needs_barrier) {
2082 oop referent = JNIHandles::resolve(ret);
2083 G1SATBCardTableModRefBS::enqueue(referent);
2084 }
2085 }
2086 #endif // INCLUDE_ALL_GCS
2087 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
2088 return ret;
2089 JNI_END
2090
2091
2456
2457 JNI_QUICK_ENTRY(jsize, jni_GetStringLength(JNIEnv *env, jstring string))
2458 JNIWrapper("GetStringLength");
2459 HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(env, string);
2460 jsize ret = 0;
2461 oop s = JNIHandles::resolve_non_null(string);
2462 if (java_lang_String::value(s) != NULL) {
2463 ret = java_lang_String::length(s);
2464 }
2465 HOTSPOT_JNI_GETSTRINGLENGTH_RETURN(ret);
2466 return ret;
2467 JNI_END
2468
2469
2470 JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars(
2471 JNIEnv *env, jstring string, jboolean *isCopy))
2472 JNIWrapper("GetStringChars");
2473 HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(env, string, (uintptr_t *) isCopy);
2474 jchar* buf = NULL;
2475 oop s = JNIHandles::resolve_non_null(string);
2476 typeArrayOop s_value = typeArrayOop(oopDesc::bs()->read_barrier(java_lang_String::value(s)));
2477 if (s_value != NULL) {
2478 int s_len = java_lang_String::length(s);
2479 int s_offset = java_lang_String::offset(s);
2480 buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination
2481 /* JNI Specification states return NULL on OOM */
2482 if (buf != NULL) {
2483 if (s_len > 0) {
2484 memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
2485 }
2486 buf[s_len] = 0;
2487 //%note jni_5
2488 if (isCopy != NULL) {
2489 *isCopy = JNI_TRUE;
2490 }
2491 }
2492 }
2493 HOTSPOT_JNI_GETSTRINGCHARS_RETURN(buf);
2494 return buf;
2495 JNI_END
2496
2704 if (bad_address != NULL) {
2705 os::protect_memory(bad_address, size, os::MEM_PROT_READ,
2706 /*is_committed*/false);
2707 MemTracker::record_virtual_memory_type((void*)bad_address, mtInternal);
2708 }
2709 }
2710 return bad_address;
2711 }
2712
2713
2714
2715 #define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \
2716 , EntryProbe, ReturnProbe) \
2717 \
2718 JNI_QUICK_ENTRY(ElementType*, \
2719 jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \
2720 JNIWrapper("Get" XSTR(Result) "ArrayElements"); \
2721 EntryProbe; \
2722 /* allocate an chunk of memory in c land */ \
2723 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2724 a = typeArrayOop(oopDesc::bs()->read_barrier(a)); \
2725 ElementType* result; \
2726 int len = a->length(); \
2727 if (len == 0) { \
2728 /* Empty array: legal but useless, can't return NULL. \
2729 * Return a pointer to something useless. \
2730 * Avoid asserts in typeArrayOop. */ \
2731 result = (ElementType*)get_bad_address(); \
2732 } else { \
2733 /* JNI Specification states return NULL on OOM */ \
2734 result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
2735 if (result != NULL) { \
2736 /* copy the array to the c chunk */ \
2737 memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
2738 if (isCopy) { \
2739 *isCopy = JNI_TRUE; \
2740 } \
2741 } \
2742 } \
2743 ReturnProbe; \
2744 return result; \
2763 , HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2764 HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(((uintptr_t*)result)))
2765 // Float and double probes don't return value because dtrace doesn't currently support it
2766 DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float
2767 , HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2768 HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result))
2769 DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double
2770 , HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2771 HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(result))
2772
2773
2774 #define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \
2775 , EntryProbe, ReturnProbe);\
2776 \
2777 JNI_QUICK_ENTRY(void, \
2778 jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \
2779 ElementType *buf, jint mode)) \
2780 JNIWrapper("Release" XSTR(Result) "ArrayElements"); \
2781 EntryProbe; \
2782 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2783 a = typeArrayOop(oopDesc::bs()->write_barrier(a)); \
2784 int len = a->length(); \
2785 if (len != 0) { /* Empty array: nothing to free or copy. */ \
2786 if ((mode == 0) || (mode == JNI_COMMIT)) { \
2787 memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \
2788 } \
2789 if ((mode == 0) || (mode == JNI_ABORT)) { \
2790 FreeHeap(buf); \
2791 } \
2792 } \
2793 ReturnProbe; \
2794 JNI_END
2795
2796 DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
2797 , HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
2798 HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN())
2799 DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte
2800 , HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode),
2801 HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN())
2802 DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT, jshort, Short, short
2803 , HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
2814 DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float
2815 , HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode),
2816 HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN())
2817 DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double
2818 , HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode),
2819 HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN())
2820
2821
2822 #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
2823 , EntryProbe, ReturnProbe); \
2824 DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion \
2825 , ReturnProbe); \
2826 \
2827 JNI_ENTRY(void, \
2828 jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
2829 jsize len, ElementType *buf)) \
2830 JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \
2831 EntryProbe; \
2832 DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
2833 typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2834 src = typeArrayOop(oopDesc::bs()->read_barrier(src)); \
2835 if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \
2836 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
2837 } else { \
2838 if (len > 0) { \
2839 int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \
2840 memcpy((u_char*) buf, \
2841 (u_char*) src->Tag##_at_addr(start), \
2842 len << sc); \
2843 } \
2844 } \
2845 JNI_END
2846
2847 DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool
2848 , HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
2849 HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN());
2850 DEFINE_GETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte
2851 , HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
2852 HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN());
2853 DEFINE_GETSCALARARRAYREGION(T_SHORT, jshort, Short, short
2854 , HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
2865 DEFINE_GETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float
2866 , HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
2867 HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN());
2868 DEFINE_GETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double
2869 , HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
2870 HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN());
2871
2872
2873 #define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
2874 , EntryProbe, ReturnProbe); \
2875 DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion \
2876 ,ReturnProbe); \
2877 \
2878 JNI_ENTRY(void, \
2879 jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
2880 jsize len, const ElementType *buf)) \
2881 JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
2882 EntryProbe; \
2883 DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
2884 typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2885 dst = typeArrayOop(oopDesc::bs()->write_barrier(dst)); \
2886 if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \
2887 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
2888 } else { \
2889 if (len > 0) { \
2890 int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \
2891 memcpy((u_char*) dst->Tag##_at_addr(start), \
2892 (u_char*) buf, \
2893 len << sc); \
2894 } \
2895 } \
2896 JNI_END
2897
2898 DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool
2899 , HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf),
2900 HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN())
2901 DEFINE_SETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte
2902 , HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
2903 HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN())
2904 DEFINE_SETSCALARARRAYREGION(T_SHORT, jshort, Short, short
2905 , HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
3064 return 0;
3065 JNI_END
3066
3067 //
3068 // Monitor functions
3069 //
3070
3071 DT_RETURN_MARK_DECL(MonitorEnter, jint
3072 , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
3073
3074 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
3075 HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
3076 jint ret = JNI_ERR;
3077 DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
3078
3079 // If the object is null, we can't do anything with it
3080 if (jobj == NULL) {
3081 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
3082 }
3083
3084 Handle obj(thread, oopDesc::bs()->write_barrier(JNIHandles::resolve_non_null(jobj)));
3085 ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
3086 ret = JNI_OK;
3087 return ret;
3088 JNI_END
3089
3090 DT_RETURN_MARK_DECL(MonitorExit, jint
3091 , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
3092
3093 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
3094 HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
3095 jint ret = JNI_ERR;
3096 DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
3097
3098 // Don't do anything with a null object
3099 if (jobj == NULL) {
3100 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
3101 }
3102
3103 Handle obj(THREAD, oopDesc::bs()->write_barrier(JNIHandles::resolve_non_null(jobj)));
3104 ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
3105
3106 ret = JNI_OK;
3107 return ret;
3108 JNI_END
3109
3110 //
3111 // Extensions
3112 //
3113
3114 DT_VOID_RETURN_MARK_DECL(GetStringRegion
3115 , HOTSPOT_JNI_GETSTRINGREGION_RETURN());
3116
3117 JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf))
3118 JNIWrapper("GetStringRegion");
3119 HOTSPOT_JNI_GETSTRINGREGION_ENTRY(env, string, start, len, buf);
3120 DT_VOID_RETURN_MARK(GetStringRegion);
3121 oop s = JNIHandles::resolve_non_null(string);
3122 int s_len = java_lang_String::length(s);
3123 if (start < 0 || len < 0 || start + len > s_len) {
3124 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
3125 } else {
3126 if (len > 0) {
3127 int s_offset = java_lang_String::offset(s);
3128 typeArrayOop s_value = java_lang_String::value(s);
3129 s_value = typeArrayOop(oopDesc::bs()->read_barrier(s_value));
3130 memcpy(buf, s_value->char_at_addr(s_offset+start), sizeof(jchar)*len);
3131 }
3132 }
3133 JNI_END
3134
3135 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion
3136 , HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN());
3137
3138 JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf))
3139 JNIWrapper("GetStringUTFRegion");
3140 HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(env, string, start, len, buf);
3141 DT_VOID_RETURN_MARK(GetStringUTFRegion);
3142 oop s = JNIHandles::resolve_non_null(string);
3143 int s_len = java_lang_String::length(s);
3144 if (start < 0 || len < 0 || start + len > s_len) {
3145 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
3146 } else {
3147 //%note jni_7
3148 if (len > 0) {
3149 // Assume the buffer is large enough as the JNI spec. does not require user error checking
3150 java_lang_String::as_utf8_string(s, start, len, buf, INT_MAX);
3151 // as_utf8_string null-terminates the result string
3152 } else {
3153 // JDK null-terminates the buffer even in len is zero
3154 if (buf != NULL) {
3155 buf[0] = 0;
3156 }
3157 }
3158 }
3159 JNI_END
3160
3161
3162 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
3163 JNIWrapper("GetPrimitiveArrayCritical");
3164 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(env, array, (uintptr_t *) isCopy);
3165 GC_locker::lock_critical(thread);
3166 if (isCopy != NULL) {
3167 *isCopy = JNI_FALSE;
3168 }
3169 oop a = JNIHandles::resolve_non_null(array);
3170 a = oopDesc::bs()->write_barrier(a);
3171 assert(a->is_array(), "just checking");
3172 BasicType type;
3173 if (a->is_objArray()) {
3174 type = T_OBJECT;
3175 } else {
3176 type = TypeArrayKlass::cast(a->klass())->element_type();
3177 }
3178 void* ret = arrayOop(a)->base(type);
3179 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(ret);
3180 return ret;
3181 JNI_END
3182
3183
3184 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
3185 JNIWrapper("ReleasePrimitiveArrayCritical");
3186 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(env, array, carray, mode);
3187 // The array, carray and mode arguments are ignored
3188 GC_locker::unlock_critical(thread);
3189 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN();
3190 JNI_END
3191
3192
3193 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
3194 JNIWrapper("GetStringCritical");
3195 HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(env, string, (uintptr_t *) isCopy);
3196 GC_locker::lock_critical(thread);
3197 if (isCopy != NULL) {
3198 *isCopy = JNI_FALSE;
3199 }
3200 oop s = JNIHandles::resolve_non_null(string);
3201 int s_len = java_lang_String::length(s);
3202 typeArrayOop s_value = java_lang_String::value(s);
3203 s_value = typeArrayOop(oopDesc::bs()->read_barrier(s_value));
3204 int s_offset = java_lang_String::offset(s);
3205 const jchar* ret;
3206 if (s_len > 0) {
3207 ret = s_value->char_at_addr(s_offset);
3208 } else {
3209 ret = (jchar*) s_value->base(T_CHAR);
3210 }
3211 HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN((uint16_t *) ret);
3212 return ret;
3213 JNI_END
3214
3215
3216 JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
3217 JNIWrapper("ReleaseStringCritical");
3218 HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(env, str, (uint16_t *) chars);
3219 // The str and chars arguments are ignored
3220 GC_locker::unlock_critical(thread);
3221 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
3222 JNI_END
3223
|