< prev index next >

src/share/vm/prims/jni.cpp

Print this page




 187 #ifdef ASSERT
 188     return result != NULL && result->is_static_field_id();
 189 #else
 190     return result != NULL;
 191 #endif
 192   }
 193 }
 194 
 195 
 196 intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) {
 197   if (offset <= small_offset_mask) {
 198     Klass* field_klass = k;
 199     Klass* super_klass = field_klass->super();
 200     // With compressed oops the most super class with nonstatic fields would
 201     // be the owner of fields embedded in the header.
 202     while (InstanceKlass::cast(super_klass)->has_nonstatic_fields() &&
 203            InstanceKlass::cast(super_klass)->contains_field_offset(offset)) {
 204       field_klass = super_klass;   // super contains the field also
 205       super_klass = field_klass->super();
 206     }
 207     debug_only(No_Safepoint_Verifier nosafepoint;)
 208     uintptr_t klass_hash = field_klass->identity_hash();
 209     return ((klass_hash & klass_mask) << klass_shift) | checked_mask_in_place;
 210   } else {
 211 #if 0
 212     #ifndef PRODUCT
 213     {
 214       ResourceMark rm;
 215       warning("VerifyJNIFields: long offset %d in %s", offset, k->external_name());
 216     }
 217     #endif
 218 #endif
 219     return 0;
 220   }
 221 }
 222 
 223 bool jfieldIDWorkaround::klass_hash_ok(Klass* k, jfieldID id) {
 224   uintptr_t as_uint = (uintptr_t) id;
 225   intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask;
 226   do {
 227     debug_only(No_Safepoint_Verifier nosafepoint;)
 228     // Could use a non-blocking query for identity_hash here...
 229     if ((k->identity_hash() & klass_mask) == klass_hash)
 230       return true;
 231     k = k->super();
 232   } while (k != NULL);
 233   return false;
 234 }
 235 
 236 void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) {
 237   guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" );
 238   uintptr_t as_uint = (uintptr_t) id;
 239   intptr_t offset = raw_instance_offset(id);
 240   if (VerifyJNIFields) {
 241     if (is_checked_jfieldID(id)) {
 242       guarantee(klass_hash_ok(k, id),
 243     "Bug in native code: jfieldID class must match object");
 244     } else {
 245 #if 0
 246       #ifndef PRODUCT
 247       if (Verbose) {


1107 }
1108 
1109 
1110 static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
1111   oop recv = JNIHandles::resolve(receiver);
1112   if (recv == NULL) {
1113     THROW(vmSymbols::java_lang_NullPointerException());
1114   }
1115   Handle h_recv(THREAD, recv);
1116 
1117   int number_of_parameters;
1118   Method* selected_method;
1119   {
1120     Method* m = Method::resolve_jmethod_id(method_id);
1121     number_of_parameters = m->size_of_parameters();
1122     Klass* holder = m->method_holder();
1123     if (call_type != JNI_VIRTUAL) {
1124         selected_method = m;
1125     } else if (!m->has_itable_index()) {
1126       // non-interface call -- for that little speed boost, don't handlize
1127       debug_only(No_Safepoint_Verifier nosafepoint;)
1128       // jni_GetMethodID makes sure class is linked and initialized
1129       // so m should have a valid vtable index.
1130       assert(m->valid_vtable_index(), "no valid vtable index");
1131       int vtbl_index = m->vtable_index();
1132       if (vtbl_index != Method::nonvirtual_vtable_index) {
1133         Klass* k = h_recv->klass();
1134         // k might be an arrayKlassOop but all vtables start at
1135         // the same place. The cast is to avoid virtual call and assertion.
1136         InstanceKlass *ik = (InstanceKlass*)k;
1137         selected_method = ik->method_at_vtable(vtbl_index);
1138       } else {
1139         // final method
1140         selected_method = m;
1141       }
1142     } else {
1143       // interface call
1144       KlassHandle h_holder(THREAD, holder);
1145 
1146       int itbl_index = m->itable_index();
1147       Klass* k = h_recv->klass();


3140     THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
3141   } else {
3142     //%note jni_7
3143     if (len > 0) {
3144       // Assume the buffer is large enough as the JNI spec. does not require user error checking
3145       java_lang_String::as_utf8_string(s, start, len, buf, INT_MAX);
3146       // as_utf8_string null-terminates the result string
3147     } else {
3148       // JDK null-terminates the buffer even in len is zero
3149       if (buf != NULL) {
3150         buf[0] = 0;
3151       }
3152     }
3153   }
3154 JNI_END
3155 
3156 
3157 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
3158   JNIWrapper("GetPrimitiveArrayCritical");
3159  HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(env, array, (uintptr_t *) isCopy);
3160   GC_locker::lock_critical(thread);
3161   if (isCopy != NULL) {
3162     *isCopy = JNI_FALSE;
3163   }
3164   oop a = JNIHandles::resolve_non_null(array);
3165   assert(a->is_array(), "just checking");
3166   BasicType type;
3167   if (a->is_objArray()) {
3168     type = T_OBJECT;
3169   } else {
3170     type = TypeArrayKlass::cast(a->klass())->element_type();
3171   }
3172   void* ret = arrayOop(a)->base(type);
3173  HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(ret);
3174   return ret;
3175 JNI_END
3176 
3177 
3178 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
3179   JNIWrapper("ReleasePrimitiveArrayCritical");
3180   HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(env, array, carray, mode);
3181   // The array, carray and mode arguments are ignored
3182   GC_locker::unlock_critical(thread);
3183 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN();
3184 JNI_END
3185 
3186 
3187 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
3188   JNIWrapper("GetStringCritical");
3189   HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(env, string, (uintptr_t *) isCopy);
3190   GC_locker::lock_critical(thread);
3191   oop s = JNIHandles::resolve_non_null(string);
3192   typeArrayOop s_value = java_lang_String::value(s);
3193   bool is_latin1 = java_lang_String::is_latin1(s);
3194   if (isCopy != NULL) {
3195     *isCopy = is_latin1 ? JNI_TRUE : JNI_FALSE;
3196   }
3197   jchar* ret;
3198   if (!is_latin1) {
3199     ret = (jchar*) s_value->base(T_CHAR);
3200   } else {
3201     // Inflate latin1 encoded string to UTF16
3202     int s_len = java_lang_String::length(s);
3203     ret = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal);  // add one for zero termination
3204     /* JNI Specification states return NULL on OOM */
3205     if (ret != NULL) {
3206       for (int i = 0; i < s_len; i++) {
3207         ret[i] = ((jchar) s_value->byte_at(i)) & 0xff;
3208       }
3209       ret[s_len] = 0;
3210     }
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 for UTF16 strings
3221   oop s = JNIHandles::resolve_non_null(str);
3222   bool is_latin1 = java_lang_String::is_latin1(s);
3223   if (is_latin1) {
3224     // For latin1 string, free jchar array allocated by earlier call to GetStringCritical.
3225     // This assumes that ReleaseStringCritical bookends GetStringCritical.
3226     FREE_C_HEAP_ARRAY(jchar, chars);
3227   }
3228   GC_locker::unlock_critical(thread);
3229 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
3230 JNI_END
3231 
3232 
3233 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
3234   JNIWrapper("jni_NewWeakGlobalRef");
3235  HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(env, ref);
3236   Handle ref_handle(thread, JNIHandles::resolve(ref));
3237   jweak ret = JNIHandles::make_weak_global(ref_handle);
3238  HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(ret);
3239   return ret;
3240 JNI_END
3241 
3242 // Must be JNI_ENTRY (with HandleMark)
3243 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
3244   JNIWrapper("jni_DeleteWeakGlobalRef");
3245   HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(env, ref);
3246   JNIHandles::destroy_weak_global(ref);
3247   HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN();
3248 JNI_END




 187 #ifdef ASSERT
 188     return result != NULL && result->is_static_field_id();
 189 #else
 190     return result != NULL;
 191 #endif
 192   }
 193 }
 194 
 195 
 196 intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) {
 197   if (offset <= small_offset_mask) {
 198     Klass* field_klass = k;
 199     Klass* super_klass = field_klass->super();
 200     // With compressed oops the most super class with nonstatic fields would
 201     // be the owner of fields embedded in the header.
 202     while (InstanceKlass::cast(super_klass)->has_nonstatic_fields() &&
 203            InstanceKlass::cast(super_klass)->contains_field_offset(offset)) {
 204       field_klass = super_klass;   // super contains the field also
 205       super_klass = field_klass->super();
 206     }
 207     debug_only(NoSafepointVerifier nosafepoint;)
 208     uintptr_t klass_hash = field_klass->identity_hash();
 209     return ((klass_hash & klass_mask) << klass_shift) | checked_mask_in_place;
 210   } else {
 211 #if 0
 212     #ifndef PRODUCT
 213     {
 214       ResourceMark rm;
 215       warning("VerifyJNIFields: long offset %d in %s", offset, k->external_name());
 216     }
 217     #endif
 218 #endif
 219     return 0;
 220   }
 221 }
 222 
 223 bool jfieldIDWorkaround::klass_hash_ok(Klass* k, jfieldID id) {
 224   uintptr_t as_uint = (uintptr_t) id;
 225   intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask;
 226   do {
 227     debug_only(NoSafepointVerifier nosafepoint;)
 228     // Could use a non-blocking query for identity_hash here...
 229     if ((k->identity_hash() & klass_mask) == klass_hash)
 230       return true;
 231     k = k->super();
 232   } while (k != NULL);
 233   return false;
 234 }
 235 
 236 void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) {
 237   guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" );
 238   uintptr_t as_uint = (uintptr_t) id;
 239   intptr_t offset = raw_instance_offset(id);
 240   if (VerifyJNIFields) {
 241     if (is_checked_jfieldID(id)) {
 242       guarantee(klass_hash_ok(k, id),
 243     "Bug in native code: jfieldID class must match object");
 244     } else {
 245 #if 0
 246       #ifndef PRODUCT
 247       if (Verbose) {


1107 }
1108 
1109 
1110 static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
1111   oop recv = JNIHandles::resolve(receiver);
1112   if (recv == NULL) {
1113     THROW(vmSymbols::java_lang_NullPointerException());
1114   }
1115   Handle h_recv(THREAD, recv);
1116 
1117   int number_of_parameters;
1118   Method* selected_method;
1119   {
1120     Method* m = Method::resolve_jmethod_id(method_id);
1121     number_of_parameters = m->size_of_parameters();
1122     Klass* holder = m->method_holder();
1123     if (call_type != JNI_VIRTUAL) {
1124         selected_method = m;
1125     } else if (!m->has_itable_index()) {
1126       // non-interface call -- for that little speed boost, don't handlize
1127       debug_only(NoSafepointVerifier nosafepoint;)
1128       // jni_GetMethodID makes sure class is linked and initialized
1129       // so m should have a valid vtable index.
1130       assert(m->valid_vtable_index(), "no valid vtable index");
1131       int vtbl_index = m->vtable_index();
1132       if (vtbl_index != Method::nonvirtual_vtable_index) {
1133         Klass* k = h_recv->klass();
1134         // k might be an arrayKlassOop but all vtables start at
1135         // the same place. The cast is to avoid virtual call and assertion.
1136         InstanceKlass *ik = (InstanceKlass*)k;
1137         selected_method = ik->method_at_vtable(vtbl_index);
1138       } else {
1139         // final method
1140         selected_method = m;
1141       }
1142     } else {
1143       // interface call
1144       KlassHandle h_holder(THREAD, holder);
1145 
1146       int itbl_index = m->itable_index();
1147       Klass* k = h_recv->klass();


3140     THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
3141   } else {
3142     //%note jni_7
3143     if (len > 0) {
3144       // Assume the buffer is large enough as the JNI spec. does not require user error checking
3145       java_lang_String::as_utf8_string(s, start, len, buf, INT_MAX);
3146       // as_utf8_string null-terminates the result string
3147     } else {
3148       // JDK null-terminates the buffer even in len is zero
3149       if (buf != NULL) {
3150         buf[0] = 0;
3151       }
3152     }
3153   }
3154 JNI_END
3155 
3156 
3157 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
3158   JNIWrapper("GetPrimitiveArrayCritical");
3159  HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(env, array, (uintptr_t *) isCopy);
3160   GCLocker::lock_critical(thread);
3161   if (isCopy != NULL) {
3162     *isCopy = JNI_FALSE;
3163   }
3164   oop a = JNIHandles::resolve_non_null(array);
3165   assert(a->is_array(), "just checking");
3166   BasicType type;
3167   if (a->is_objArray()) {
3168     type = T_OBJECT;
3169   } else {
3170     type = TypeArrayKlass::cast(a->klass())->element_type();
3171   }
3172   void* ret = arrayOop(a)->base(type);
3173  HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(ret);
3174   return ret;
3175 JNI_END
3176 
3177 
3178 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
3179   JNIWrapper("ReleasePrimitiveArrayCritical");
3180   HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(env, array, carray, mode);
3181   // The array, carray and mode arguments are ignored
3182   GCLocker::unlock_critical(thread);
3183 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN();
3184 JNI_END
3185 
3186 
3187 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
3188   JNIWrapper("GetStringCritical");
3189   HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(env, string, (uintptr_t *) isCopy);
3190   GCLocker::lock_critical(thread);
3191   oop s = JNIHandles::resolve_non_null(string);
3192   typeArrayOop s_value = java_lang_String::value(s);
3193   bool is_latin1 = java_lang_String::is_latin1(s);
3194   if (isCopy != NULL) {
3195     *isCopy = is_latin1 ? JNI_TRUE : JNI_FALSE;
3196   }
3197   jchar* ret;
3198   if (!is_latin1) {
3199     ret = (jchar*) s_value->base(T_CHAR);
3200   } else {
3201     // Inflate latin1 encoded string to UTF16
3202     int s_len = java_lang_String::length(s);
3203     ret = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal);  // add one for zero termination
3204     /* JNI Specification states return NULL on OOM */
3205     if (ret != NULL) {
3206       for (int i = 0; i < s_len; i++) {
3207         ret[i] = ((jchar) s_value->byte_at(i)) & 0xff;
3208       }
3209       ret[s_len] = 0;
3210     }
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 for UTF16 strings
3221   oop s = JNIHandles::resolve_non_null(str);
3222   bool is_latin1 = java_lang_String::is_latin1(s);
3223   if (is_latin1) {
3224     // For latin1 string, free jchar array allocated by earlier call to GetStringCritical.
3225     // This assumes that ReleaseStringCritical bookends GetStringCritical.
3226     FREE_C_HEAP_ARRAY(jchar, chars);
3227   }
3228   GCLocker::unlock_critical(thread);
3229 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
3230 JNI_END
3231 
3232 
3233 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
3234   JNIWrapper("jni_NewWeakGlobalRef");
3235  HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(env, ref);
3236   Handle ref_handle(thread, JNIHandles::resolve(ref));
3237   jweak ret = JNIHandles::make_weak_global(ref_handle);
3238  HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(ret);
3239   return ret;
3240 JNI_END
3241 
3242 // Must be JNI_ENTRY (with HandleMark)
3243 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
3244   JNIWrapper("jni_DeleteWeakGlobalRef");
3245   HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(env, ref);
3246   JNIHandles::destroy_weak_global(ref);
3247   HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN();
3248 JNI_END


< prev index next >