1 /* |
1 /* |
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. |
3 * Copyright (c) 2012 Red Hat, Inc. |
3 * Copyright (c) 2012 Red Hat, Inc. |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5 * |
5 * |
6 * This code is free software; you can redistribute it and/or modify it |
6 * This code is free software; you can redistribute it and/or modify it |
7 * under the terms of the GNU General Public License version 2 only, as |
7 * under the terms of the GNU General Public License version 2 only, as |
384 |
384 |
385 //%note jni_3 |
385 //%note jni_3 |
386 Handle loader; |
386 Handle loader; |
387 Handle protection_domain; |
387 Handle protection_domain; |
388 // Find calling class |
388 // Find calling class |
389 instanceKlassHandle k (THREAD, thread->security_get_caller_class(0)); |
389 Klass* k = thread->security_get_caller_class(0); |
390 if (k.not_null()) { |
390 if (k != NULL) { |
391 loader = Handle(THREAD, k->class_loader()); |
391 loader = Handle(THREAD, k->class_loader()); |
392 // Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed |
392 // Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed |
393 // in the correct class context. |
393 // in the correct class context. |
394 if (loader.is_null() && |
394 if (loader.is_null() && |
395 k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) { |
395 k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) { |
396 JavaValue result(T_OBJECT); |
396 JavaValue result(T_OBJECT); |
397 JavaCalls::call_static(&result, k, |
397 JavaCalls::call_static(&result, k, |
398 vmSymbols::getFromClass_name(), |
398 vmSymbols::getFromClass_name(), |
399 vmSymbols::void_class_signature(), |
399 vmSymbols::void_class_signature(), |
400 thread); |
400 thread); |
401 if (HAS_PENDING_EXCEPTION) { |
401 if (HAS_PENDING_EXCEPTION) { |
402 Handle ex(thread, thread->pending_exception()); |
402 Handle ex(thread, thread->pending_exception()); |
403 CLEAR_PENDING_EXCEPTION; |
403 CLEAR_PENDING_EXCEPTION; |
404 THROW_HANDLE_0(ex); |
404 THROW_HANDLE_0(ex); |
405 } |
405 } |
453 } else { |
453 } else { |
454 assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type"); |
454 assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type"); |
455 mirror = java_lang_reflect_Method::clazz(reflected); |
455 mirror = java_lang_reflect_Method::clazz(reflected); |
456 slot = java_lang_reflect_Method::slot(reflected); |
456 slot = java_lang_reflect_Method::slot(reflected); |
457 } |
457 } |
458 Klass* k = java_lang_Class::as_Klass(mirror); |
458 Klass* k1 = java_lang_Class::as_Klass(mirror); |
459 |
459 |
460 KlassHandle k1(THREAD, k); |
|
461 // Make sure class is initialized before handing id's out to methods |
460 // Make sure class is initialized before handing id's out to methods |
462 k1()->initialize(CHECK_NULL); |
461 k1->initialize(CHECK_NULL); |
463 Method* m = InstanceKlass::cast(k1())->method_with_idnum(slot); |
462 Method* m = InstanceKlass::cast(k1)->method_with_idnum(slot); |
464 ret = m==NULL? NULL : m->jmethod_id(); // return NULL if reflected method deleted |
463 ret = m==NULL? NULL : m->jmethod_id(); // return NULL if reflected method deleted |
465 return ret; |
464 return ret; |
466 JNI_END |
465 JNI_END |
467 |
466 |
468 DT_RETURN_MARK_DECL(FromReflectedField, jfieldID |
467 DT_RETURN_MARK_DECL(FromReflectedField, jfieldID |
477 DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret); |
476 DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret); |
478 |
477 |
479 // field is a handle to a java.lang.reflect.Field object |
478 // field is a handle to a java.lang.reflect.Field object |
480 oop reflected = JNIHandles::resolve_non_null(field); |
479 oop reflected = JNIHandles::resolve_non_null(field); |
481 oop mirror = java_lang_reflect_Field::clazz(reflected); |
480 oop mirror = java_lang_reflect_Field::clazz(reflected); |
482 Klass* k = java_lang_Class::as_Klass(mirror); |
481 Klass* k1 = java_lang_Class::as_Klass(mirror); |
483 int slot = java_lang_reflect_Field::slot(reflected); |
482 int slot = java_lang_reflect_Field::slot(reflected); |
484 int modifiers = java_lang_reflect_Field::modifiers(reflected); |
483 int modifiers = java_lang_reflect_Field::modifiers(reflected); |
485 |
484 |
486 KlassHandle k1(THREAD, k); |
|
487 // Make sure class is initialized before handing id's out to fields |
485 // Make sure class is initialized before handing id's out to fields |
488 k1()->initialize(CHECK_NULL); |
486 k1->initialize(CHECK_NULL); |
489 |
487 |
490 // First check if this is a static field |
488 // First check if this is a static field |
491 if (modifiers & JVM_ACC_STATIC) { |
489 if (modifiers & JVM_ACC_STATIC) { |
492 intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot ); |
490 intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot ); |
493 JNIid* id = InstanceKlass::cast(k1())->jni_id_for(offset); |
491 JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset); |
494 assert(id != NULL, "corrupt Field object"); |
492 assert(id != NULL, "corrupt Field object"); |
495 debug_only(id->set_is_static_field_id();) |
493 debug_only(id->set_is_static_field_id();) |
496 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass* |
494 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass* |
497 ret = jfieldIDWorkaround::to_static_jfieldID(id); |
495 ret = jfieldIDWorkaround::to_static_jfieldID(id); |
498 return ret; |
496 return ret; |
499 } |
497 } |
500 |
498 |
501 // The slot is the index of the field description in the field-array |
499 // The slot is the index of the field description in the field-array |
502 // The jfieldID is the offset of the field within the object |
500 // The jfieldID is the offset of the field within the object |
503 // It may also have hash bits for k, if VerifyJNIFields is turned on. |
501 // It may also have hash bits for k, if VerifyJNIFields is turned on. |
504 intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot ); |
502 intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot ); |
505 assert(InstanceKlass::cast(k1())->contains_field_offset(offset), "stay within object"); |
503 assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object"); |
506 ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset); |
504 ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset); |
507 return ret; |
505 return ret; |
508 JNI_END |
506 JNI_END |
509 |
507 |
510 |
508 |
511 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject |
509 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject |
675 } |
673 } |
676 if (ex->is_a(SystemDictionary::Throwable_klass())) { |
674 if (ex->is_a(SystemDictionary::Throwable_klass())) { |
677 JavaValue result(T_VOID); |
675 JavaValue result(T_VOID); |
678 JavaCalls::call_virtual(&result, |
676 JavaCalls::call_virtual(&result, |
679 ex, |
677 ex, |
680 KlassHandle(THREAD, |
678 SystemDictionary::Throwable_klass(), |
681 SystemDictionary::Throwable_klass()), |
|
682 vmSymbols::printStackTrace_name(), |
679 vmSymbols::printStackTrace_name(), |
683 vmSymbols::void_method_signature(), |
680 vmSymbols::void_method_signature(), |
684 THREAD); |
681 THREAD); |
685 // If an exception is thrown in the call it gets thrown away. Not much |
682 // If an exception is thrown in the call it gets thrown away. Not much |
686 // we can do with it. The native code that calls this, does not check |
683 // we can do with it. The native code that calls this, does not check |
1154 // final method |
1151 // final method |
1155 selected_method = m; |
1152 selected_method = m; |
1156 } |
1153 } |
1157 } else { |
1154 } else { |
1158 // interface call |
1155 // interface call |
1159 KlassHandle h_holder(THREAD, holder); |
|
1160 |
|
1161 int itbl_index = m->itable_index(); |
1156 int itbl_index = m->itable_index(); |
1162 Klass* k = h_recv->klass(); |
1157 Klass* k = h_recv->klass(); |
1163 selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK); |
1158 selected_method = InstanceKlass::cast(k)->method_at_itable(holder, itbl_index, CHECK); |
1164 } |
1159 } |
1165 } |
1160 } |
1166 |
1161 |
1167 methodHandle method(THREAD, selected_method); |
1162 methodHandle method(THREAD, selected_method); |
1168 |
1163 |
1190 } |
1185 } |
1191 } |
1186 } |
1192 |
1187 |
1193 |
1188 |
1194 static instanceOop alloc_object(jclass clazz, TRAPS) { |
1189 static instanceOop alloc_object(jclass clazz, TRAPS) { |
1195 KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
1190 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); |
1196 if (k == NULL) { |
1191 if (k == NULL) { |
1197 ResourceMark rm(THREAD); |
1192 ResourceMark rm(THREAD); |
1198 THROW_(vmSymbols::java_lang_InstantiationException(), NULL); |
1193 THROW_(vmSymbols::java_lang_InstantiationException(), NULL); |
1199 } |
1194 } |
1200 k()->check_valid_for_instantiation(false, CHECK_NULL); |
1195 k->check_valid_for_instantiation(false, CHECK_NULL); |
1201 InstanceKlass::cast(k())->initialize(CHECK_NULL); |
1196 k->initialize(CHECK_NULL); |
1202 instanceOop ih = InstanceKlass::cast(k())->allocate_instance(THREAD); |
1197 instanceOop ih = InstanceKlass::cast(k)->allocate_instance(THREAD); |
1203 return ih; |
1198 return ih; |
1204 } |
1199 } |
1205 |
1200 |
1206 DT_RETURN_MARK_DECL(AllocObject, jobject |
1201 DT_RETURN_MARK_DECL(AllocObject, jobject |
1207 , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref)); |
1202 , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref)); |
1336 // primitive java.lang.Class |
1331 // primitive java.lang.Class |
1337 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) { |
1332 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) { |
1338 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str); |
1333 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str); |
1339 } |
1334 } |
1340 |
1335 |
1341 KlassHandle klass(THREAD, |
1336 Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); |
1342 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
|
1343 |
1337 |
1344 // Make sure class is linked and initialized before handing id's out to |
1338 // Make sure class is linked and initialized before handing id's out to |
1345 // Method*s. |
1339 // Method*s. |
1346 klass()->initialize(CHECK_NULL); |
1340 klass->initialize(CHECK_NULL); |
1347 |
1341 |
1348 Method* m; |
1342 Method* m; |
1349 if (name == vmSymbols::object_initializer_name() || |
1343 if (name == vmSymbols::object_initializer_name() || |
1350 name == vmSymbols::class_initializer_name()) { |
1344 name == vmSymbols::class_initializer_name()) { |
1351 // Never search superclasses for constructors |
1345 // Never search superclasses for constructors |
1352 if (klass->is_instance_klass()) { |
1346 if (klass->is_instance_klass()) { |
1353 m = InstanceKlass::cast(klass())->find_method(name, signature); |
1347 m = InstanceKlass::cast(klass)->find_method(name, signature); |
1354 } else { |
1348 } else { |
1355 m = NULL; |
1349 m = NULL; |
1356 } |
1350 } |
1357 } else { |
1351 } else { |
1358 m = klass->lookup_method(name, signature); |
1352 m = klass->lookup_method(name, signature); |
1359 if (m == NULL && klass->is_instance_klass()) { |
1353 if (m == NULL && klass->is_instance_klass()) { |
1360 m = InstanceKlass::cast(klass())->lookup_method_in_ordered_interfaces(name, signature); |
1354 m = InstanceKlass::cast(klass)->lookup_method_in_ordered_interfaces(name, signature); |
1361 } |
1355 } |
1362 } |
1356 } |
1363 if (m == NULL || (m->is_static() != is_static)) { |
1357 if (m == NULL || (m->is_static() != is_static)) { |
1364 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str); |
1358 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str); |
1365 } |
1359 } |
1877 (const ResultType&)ret);\ |
1871 (const ResultType&)ret);\ |
1878 \ |
1872 \ |
1879 JavaValue jvalue(Tag); \ |
1873 JavaValue jvalue(Tag); \ |
1880 JNI_ArgumentPusherVaArg ap(methodID, args); \ |
1874 JNI_ArgumentPusherVaArg ap(methodID, args); \ |
1881 /* Make sure class is initialized before trying to invoke its method */ \ |
1875 /* Make sure class is initialized before trying to invoke its method */ \ |
1882 KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls))); \ |
1876 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); \ |
1883 k()->initialize(CHECK_0); \ |
1877 k->initialize(CHECK_0); \ |
1884 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ |
1878 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ |
1885 va_end(args); \ |
1879 va_end(args); \ |
1886 ret = jvalue.get_##ResultType(); \ |
1880 ret = jvalue.get_##ResultType(); \ |
1887 return ret;\ |
1881 return ret;\ |
1888 JNI_END |
1882 JNI_END |
2035 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name)); |
2029 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name)); |
2036 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig)); |
2030 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig)); |
2037 if (fieldname == NULL || signame == NULL) { |
2031 if (fieldname == NULL || signame == NULL) { |
2038 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2032 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2039 } |
2033 } |
2040 KlassHandle k(THREAD, |
2034 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); |
2041 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
|
2042 // Make sure class is initialized before handing id's out to fields |
2035 // Make sure class is initialized before handing id's out to fields |
2043 k()->initialize(CHECK_NULL); |
2036 k->initialize(CHECK_NULL); |
2044 |
2037 |
2045 fieldDescriptor fd; |
2038 fieldDescriptor fd; |
2046 if (!k()->is_instance_klass() || |
2039 if (!k->is_instance_klass() || |
2047 !InstanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) { |
2040 !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) { |
2048 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2041 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2049 } |
2042 } |
2050 |
2043 |
2051 // A jfieldID for a non-static field is simply the offset of the field within the instanceOop |
2044 // A jfieldID for a non-static field is simply the offset of the field within the instanceOop |
2052 // It may also have hash bits for k, if VerifyJNIFields is turned on. |
2045 // It may also have hash bits for k, if VerifyJNIFields is turned on. |
2053 ret = jfieldIDWorkaround::to_instance_jfieldID(k(), fd.offset()); |
2046 ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset()); |
2054 return ret; |
2047 return ret; |
2055 JNI_END |
2048 JNI_END |
2056 |
2049 |
2057 |
2050 |
2058 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)) |
2051 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)) |
2290 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name)); |
2283 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name)); |
2291 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig)); |
2284 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig)); |
2292 if (fieldname == NULL || signame == NULL) { |
2285 if (fieldname == NULL || signame == NULL) { |
2293 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2286 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2294 } |
2287 } |
2295 KlassHandle k(THREAD, |
2288 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); |
2296 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
|
2297 // Make sure class is initialized before handing id's out to static fields |
2289 // Make sure class is initialized before handing id's out to static fields |
2298 k()->initialize(CHECK_NULL); |
2290 k->initialize(CHECK_NULL); |
2299 |
2291 |
2300 fieldDescriptor fd; |
2292 fieldDescriptor fd; |
2301 if (!k()->is_instance_klass() || |
2293 if (!k->is_instance_klass() || |
2302 !InstanceKlass::cast(k())->find_field(fieldname, signame, true, &fd)) { |
2294 !InstanceKlass::cast(k)->find_field(fieldname, signame, true, &fd)) { |
2303 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2295 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); |
2304 } |
2296 } |
2305 |
2297 |
2306 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass* |
2298 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass* |
2307 JNIid* id = fd.field_holder()->jni_id_for(fd.offset()); |
2299 JNIid* id = fd.field_holder()->jni_id_for(fd.offset()); |
2601 JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)) |
2593 JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)) |
2602 JNIWrapper("NewObjectArray"); |
2594 JNIWrapper("NewObjectArray"); |
2603 HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(env, length, elementClass, initialElement); |
2595 HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(env, length, elementClass, initialElement); |
2604 jobjectArray ret = NULL; |
2596 jobjectArray ret = NULL; |
2605 DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret); |
2597 DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret); |
2606 KlassHandle ek(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass))); |
2598 Klass* ek = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass)); |
2607 Klass* ako = ek()->array_klass(CHECK_NULL); |
2599 Klass* ak = ek->array_klass(CHECK_NULL); |
2608 KlassHandle ak = KlassHandle(THREAD, ako); |
2600 ObjArrayKlass::cast(ak)->initialize(CHECK_NULL); |
2609 ObjArrayKlass::cast(ak())->initialize(CHECK_NULL); |
2601 objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL); |
2610 objArrayOop result = ObjArrayKlass::cast(ak())->allocate(length, CHECK_NULL); |
|
2611 oop initial_value = JNIHandles::resolve(initialElement); |
2602 oop initial_value = JNIHandles::resolve(initialElement); |
2612 if (initial_value != NULL) { // array already initialized with NULL |
2603 if (initial_value != NULL) { // array already initialized with NULL |
2613 for (int index = 0; index < length; index++) { |
2604 for (int index = 0; index < length; index++) { |
2614 result->obj_at_put(index, initial_value); |
2605 result->obj_at_put(index, initial_value); |
2615 } |
2606 } |
2934 |
2925 |
2935 // The RegisterNatives call being attempted tried to register with a method that |
2926 // The RegisterNatives call being attempted tried to register with a method that |
2936 // is not native. Ask JVM TI what prefixes have been specified. Then check |
2927 // is not native. Ask JVM TI what prefixes have been specified. Then check |
2937 // to see if the native method is now wrapped with the prefixes. See the |
2928 // to see if the native method is now wrapped with the prefixes. See the |
2938 // SetNativeMethodPrefix(es) functions in the JVM TI Spec for details. |
2929 // SetNativeMethodPrefix(es) functions in the JVM TI Spec for details. |
2939 static Method* find_prefixed_native(KlassHandle k, |
2930 static Method* find_prefixed_native(Klass* k, Symbol* name, Symbol* signature, TRAPS) { |
2940 Symbol* name, Symbol* signature, TRAPS) { |
|
2941 #if INCLUDE_JVMTI |
2931 #if INCLUDE_JVMTI |
2942 ResourceMark rm(THREAD); |
2932 ResourceMark rm(THREAD); |
2943 Method* method; |
2933 Method* method; |
2944 int name_len = name->utf8_length(); |
2934 int name_len = name->utf8_length(); |
2945 char* name_str = name->as_utf8(); |
2935 char* name_str = name->as_utf8(); |
2956 strcat(trial_name_str, name_str); |
2946 strcat(trial_name_str, name_str); |
2957 TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len); |
2947 TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len); |
2958 if (trial_name == NULL) { |
2948 if (trial_name == NULL) { |
2959 continue; // no such symbol, so this prefix wasn't used, try the next prefix |
2949 continue; // no such symbol, so this prefix wasn't used, try the next prefix |
2960 } |
2950 } |
2961 method = k()->lookup_method(trial_name, signature); |
2951 method = k->lookup_method(trial_name, signature); |
2962 if (method == NULL) { |
2952 if (method == NULL) { |
2963 continue; // signature doesn't match, try the next prefix |
2953 continue; // signature doesn't match, try the next prefix |
2964 } |
2954 } |
2965 if (method->is_native()) { |
2955 if (method->is_native()) { |
2966 method->set_is_prefixed_native(); |
2956 method->set_is_prefixed_native(); |
2972 } |
2962 } |
2973 #endif // INCLUDE_JVMTI |
2963 #endif // INCLUDE_JVMTI |
2974 return NULL; // not found |
2964 return NULL; // not found |
2975 } |
2965 } |
2976 |
2966 |
2977 static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) { |
2967 static bool register_native(Klass* k, Symbol* name, Symbol* signature, address entry, TRAPS) { |
2978 Method* method = k()->lookup_method(name, signature); |
2968 Method* method = k->lookup_method(name, signature); |
2979 if (method == NULL) { |
2969 if (method == NULL) { |
2980 ResourceMark rm; |
2970 ResourceMark rm; |
2981 stringStream st; |
2971 stringStream st; |
2982 st.print("Method %s name or signature does not match", |
2972 st.print("Method %s name or signature does not match", |
2983 Method::name_and_sig_as_C_string(k(), name, signature)); |
2973 Method::name_and_sig_as_C_string(k, name, signature)); |
2984 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); |
2974 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); |
2985 } |
2975 } |
2986 if (!method->is_native()) { |
2976 if (!method->is_native()) { |
2987 // trying to register to a non-native method, see if a JVM TI agent has added prefix(es) |
2977 // trying to register to a non-native method, see if a JVM TI agent has added prefix(es) |
2988 method = find_prefixed_native(k, name, signature, THREAD); |
2978 method = find_prefixed_native(k, name, signature, THREAD); |
2989 if (method == NULL) { |
2979 if (method == NULL) { |
2990 ResourceMark rm; |
2980 ResourceMark rm; |
2991 stringStream st; |
2981 stringStream st; |
2992 st.print("Method %s is not declared as native", |
2982 st.print("Method %s is not declared as native", |
2993 Method::name_and_sig_as_C_string(k(), name, signature)); |
2983 Method::name_and_sig_as_C_string(k, name, signature)); |
2994 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); |
2984 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); |
2995 } |
2985 } |
2996 } |
2986 } |
2997 |
2987 |
2998 if (entry != NULL) { |
2988 if (entry != NULL) { |
3019 JNIWrapper("RegisterNatives"); |
3009 JNIWrapper("RegisterNatives"); |
3020 HOTSPOT_JNI_REGISTERNATIVES_ENTRY(env, clazz, (void *) methods, nMethods); |
3010 HOTSPOT_JNI_REGISTERNATIVES_ENTRY(env, clazz, (void *) methods, nMethods); |
3021 jint ret = 0; |
3011 jint ret = 0; |
3022 DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret); |
3012 DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret); |
3023 |
3013 |
3024 KlassHandle h_k(thread, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); |
3014 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); |
3025 |
3015 |
3026 for (int index = 0; index < nMethods; index++) { |
3016 for (int index = 0; index < nMethods; index++) { |
3027 const char* meth_name = methods[index].name; |
3017 const char* meth_name = methods[index].name; |
3028 const char* meth_sig = methods[index].signature; |
3018 const char* meth_sig = methods[index].signature; |
3029 int meth_name_len = (int)strlen(meth_name); |
3019 int meth_name_len = (int)strlen(meth_name); |
3035 TempNewSymbol signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig)); |
3025 TempNewSymbol signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig)); |
3036 |
3026 |
3037 if (name == NULL || signature == NULL) { |
3027 if (name == NULL || signature == NULL) { |
3038 ResourceMark rm; |
3028 ResourceMark rm; |
3039 stringStream st; |
3029 stringStream st; |
3040 st.print("Method %s.%s%s not found", h_k()->external_name(), meth_name, meth_sig); |
3030 st.print("Method %s.%s%s not found", k->external_name(), meth_name, meth_sig); |
3041 // Must return negative value on failure |
3031 // Must return negative value on failure |
3042 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1); |
3032 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1); |
3043 } |
3033 } |
3044 |
3034 |
3045 bool res = register_native(h_k, name, signature, |
3035 bool res = register_native(k, name, signature, |
3046 (address) methods[index].fnPtr, THREAD); |
3036 (address) methods[index].fnPtr, THREAD); |
3047 if (!res) { |
3037 if (!res) { |
3048 ret = -1; |
3038 ret = -1; |
3049 break; |
3039 break; |
3050 } |
3040 } |