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
|