< prev index next >

src/share/vm/prims/jni.cpp

Print this page
rev 8961 : [mq]: diff-shenandoah.patch


 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 


2549     }
2550   }
2551  HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN(result);
2552   return result;
2553 JNI_END
2554 
2555 
2556 JNI_LEAF(void, jni_ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars))
2557   JNIWrapper("ReleaseStringUTFChars");
2558  HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY(env, str, (char *) chars);
2559   if (chars != NULL) {
2560     FreeHeap((char*) chars);
2561   }
2562 HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN();
2563 JNI_END
2564 
2565 
2566 JNI_QUICK_ENTRY(jsize, jni_GetArrayLength(JNIEnv *env, jarray array))
2567   JNIWrapper("GetArrayLength");
2568  HOTSPOT_JNI_GETARRAYLENGTH_ENTRY(env, array);
2569   arrayOop a = arrayOop(JNIHandles::resolve_non_null(array));
2570   assert(a->is_array(), "must be array");
2571   jsize ret = a->length();
2572  HOTSPOT_JNI_GETARRAYLENGTH_RETURN(ret);
2573   return ret;
2574 JNI_END
2575 
2576 
2577 //
2578 // Object Array Operations
2579 //
2580 
2581 DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray
2582                     , HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(_ret_ref));
2583 
2584 JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))
2585   JNIWrapper("NewObjectArray");
2586  HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(env, length, elementClass, initialElement);
2587   jobjectArray ret = NULL;
2588   DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
2589   KlassHandle ek(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass)));


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()->resolve_and_maybe_copy_oop(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()->resolve_and_maybe_copy_oop(sub_mirror);
 580   super_mirror = oopDesc::bs()->resolve_and_maybe_copy_oop(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()->resolve_and_maybe_copy_oop(a);
 825   oop b = JNIHandles::resolve(r2);
 826   b = oopDesc::bs()->resolve_and_maybe_copy_oop(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()->resolve_oop(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 


2555     }
2556   }
2557  HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN(result);
2558   return result;
2559 JNI_END
2560 
2561 
2562 JNI_LEAF(void, jni_ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars))
2563   JNIWrapper("ReleaseStringUTFChars");
2564  HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY(env, str, (char *) chars);
2565   if (chars != NULL) {
2566     FreeHeap((char*) chars);
2567   }
2568 HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN();
2569 JNI_END
2570 
2571 
2572 JNI_QUICK_ENTRY(jsize, jni_GetArrayLength(JNIEnv *env, jarray array))
2573   JNIWrapper("GetArrayLength");
2574  HOTSPOT_JNI_GETARRAYLENGTH_ENTRY(env, array);
2575   arrayOop a = arrayOop(oopDesc::bs()->resolve_oop(JNIHandles::resolve_non_null(array)));
2576   assert(a->is_array(), "must be array");
2577   jsize ret = a->length();
2578  HOTSPOT_JNI_GETARRAYLENGTH_RETURN(ret);
2579   return ret;
2580 JNI_END
2581 
2582 
2583 //
2584 // Object Array Operations
2585 //
2586 
2587 DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray
2588                     , HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(_ret_ref));
2589 
2590 JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))
2591   JNIWrapper("NewObjectArray");
2592  HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(env, length, elementClass, initialElement);
2593   jobjectArray ret = NULL;
2594   DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
2595   KlassHandle ek(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass)));


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()->resolve_oop(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()->resolve_and_maybe_copy_oop(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()->resolve_oop(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()->resolve_and_maybe_copy_oop(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()->resolve_and_maybe_copy_oop(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()->resolve_and_maybe_copy_oop(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   s = oopDesc::bs()->resolve_oop(s);
3123   int s_len = java_lang_String::length(s);
3124   if (start < 0 || len < 0 || start + len > s_len) {
3125     THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
3126   } else {
3127     if (len > 0) {
3128       int s_offset = java_lang_String::offset(s);
3129       typeArrayOop s_value = java_lang_String::value(s);
3130       s_value = typeArrayOop(oopDesc::bs()->resolve_oop(s_value));
3131       memcpy(buf, s_value->char_at_addr(s_offset+start), sizeof(jchar)*len);
3132     }
3133   }
3134 JNI_END
3135 
3136 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion
3137                          , HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN());
3138 
3139 JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf))
3140   JNIWrapper("GetStringUTFRegion");
3141  HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(env, string, start, len, buf);
3142   DT_VOID_RETURN_MARK(GetStringUTFRegion);
3143   oop s = JNIHandles::resolve_non_null(string);
3144   int s_len = java_lang_String::length(s);
3145   if (start < 0 || len < 0 || start + len > s_len) {
3146     THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
3147   } else {
3148     //%note jni_7
3149     if (len > 0) {
3150       // Assume the buffer is large enough as the JNI spec. does not require user error checking
3151       java_lang_String::as_utf8_string(s, start, len, buf, INT_MAX);
3152       // as_utf8_string null-terminates the result string
3153     } else {
3154       // JDK null-terminates the buffer even in len is zero
3155       if (buf != NULL) {
3156         buf[0] = 0;
3157       }
3158     }
3159   }
3160 JNI_END
3161 
3162 
3163 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
3164   JNIWrapper("GetPrimitiveArrayCritical");
3165  HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(env, array, (uintptr_t *) isCopy);
3166   GC_locker::lock_critical(thread);
3167   if (isCopy != NULL) {
3168     *isCopy = JNI_FALSE;
3169   }
3170   oop a = JNIHandles::resolve_non_null(array);
3171   a = oopDesc::bs()->resolve_and_maybe_copy_oop(a);
3172   assert(a->is_array(), "just checking");
3173   BasicType type;
3174   if (a->is_objArray()) {
3175     type = T_OBJECT;
3176   } else {
3177     type = TypeArrayKlass::cast(a->klass())->element_type();
3178   }
3179   void* ret = arrayOop(a)->base(type);
3180  HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(ret);
3181   return ret;
3182 JNI_END
3183 
3184 
3185 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
3186   JNIWrapper("ReleasePrimitiveArrayCritical");
3187   HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(env, array, carray, mode);
3188   // The array, carray and mode arguments are ignored
3189   GC_locker::unlock_critical(thread);
3190 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN();
3191 JNI_END
3192 
3193 
3194 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
3195   JNIWrapper("GetStringCritical");
3196   HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(env, string, (uintptr_t *) isCopy);
3197   GC_locker::lock_critical(thread);
3198   if (isCopy != NULL) {
3199     *isCopy = JNI_FALSE;
3200   }
3201   oop s = JNIHandles::resolve_non_null(string);
3202   int s_len = java_lang_String::length(s);
3203   typeArrayOop s_value = java_lang_String::value(s);
3204   s_value = typeArrayOop(oopDesc::bs()->resolve_oop(s_value));
3205   int s_offset = java_lang_String::offset(s);
3206   const jchar* ret;
3207   if (s_len > 0) {
3208     ret = s_value->char_at_addr(s_offset);
3209   } else {
3210     ret = (jchar*) s_value->base(T_CHAR);
3211   }
3212  HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN((uint16_t *) ret);
3213   return ret;
3214 JNI_END
3215 
3216 
3217 JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
3218   JNIWrapper("ReleaseStringCritical");
3219   HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(env, str, (uint16_t *) chars);
3220   // The str and chars arguments are ignored
3221   GC_locker::unlock_critical(thread);
3222 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
3223 JNI_END
3224 


< prev index next >