< prev index next >
src/share/vm/prims/jni.cpp
Print this page
*** 384,395 ****
//%note jni_3
Handle loader;
Handle protection_domain;
// Find calling class
! instanceKlassHandle k (THREAD, thread->security_get_caller_class(0));
! if (k.not_null()) {
loader = Handle(THREAD, k->class_loader());
// Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed
// in the correct class context.
if (loader.is_null() &&
k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) {
--- 384,395 ----
//%note jni_3
Handle loader;
Handle protection_domain;
// Find calling class
! Klass* k = thread->security_get_caller_class(0);
! if (k != NULL) {
loader = Handle(THREAD, k->class_loader());
// Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed
// in the correct class context.
if (loader.is_null() &&
k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) {
*** 453,468 ****
} else {
assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");
mirror = java_lang_reflect_Method::clazz(reflected);
slot = java_lang_reflect_Method::slot(reflected);
}
! Klass* k = java_lang_Class::as_Klass(mirror);
- KlassHandle k1(THREAD, k);
// Make sure class is initialized before handing id's out to methods
! k1()->initialize(CHECK_NULL);
! Method* m = InstanceKlass::cast(k1())->method_with_idnum(slot);
ret = m==NULL? NULL : m->jmethod_id(); // return NULL if reflected method deleted
return ret;
JNI_END
DT_RETURN_MARK_DECL(FromReflectedField, jfieldID
--- 453,467 ----
} else {
assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");
mirror = java_lang_reflect_Method::clazz(reflected);
slot = java_lang_reflect_Method::slot(reflected);
}
! Klass* k1 = java_lang_Class::as_Klass(mirror);
// Make sure class is initialized before handing id's out to methods
! k1->initialize(CHECK_NULL);
! Method* m = InstanceKlass::cast(k1)->method_with_idnum(slot);
ret = m==NULL? NULL : m->jmethod_id(); // return NULL if reflected method deleted
return ret;
JNI_END
DT_RETURN_MARK_DECL(FromReflectedField, jfieldID
*** 477,511 ****
DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret);
// field is a handle to a java.lang.reflect.Field object
oop reflected = JNIHandles::resolve_non_null(field);
oop mirror = java_lang_reflect_Field::clazz(reflected);
! Klass* k = java_lang_Class::as_Klass(mirror);
int slot = java_lang_reflect_Field::slot(reflected);
int modifiers = java_lang_reflect_Field::modifiers(reflected);
- KlassHandle k1(THREAD, k);
// Make sure class is initialized before handing id's out to fields
! k1()->initialize(CHECK_NULL);
// First check if this is a static field
if (modifiers & JVM_ACC_STATIC) {
! intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );
! JNIid* id = InstanceKlass::cast(k1())->jni_id_for(offset);
assert(id != NULL, "corrupt Field object");
debug_only(id->set_is_static_field_id();)
// A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
ret = jfieldIDWorkaround::to_static_jfieldID(id);
return ret;
}
// The slot is the index of the field description in the field-array
// The jfieldID is the offset of the field within the object
// It may also have hash bits for k, if VerifyJNIFields is turned on.
! intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );
! assert(InstanceKlass::cast(k1())->contains_field_offset(offset), "stay within object");
! ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset);
return ret;
JNI_END
DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
--- 476,509 ----
DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret);
// field is a handle to a java.lang.reflect.Field object
oop reflected = JNIHandles::resolve_non_null(field);
oop mirror = java_lang_reflect_Field::clazz(reflected);
! Klass* k1 = java_lang_Class::as_Klass(mirror);
int slot = java_lang_reflect_Field::slot(reflected);
int modifiers = java_lang_reflect_Field::modifiers(reflected);
// Make sure class is initialized before handing id's out to fields
! k1->initialize(CHECK_NULL);
// First check if this is a static field
if (modifiers & JVM_ACC_STATIC) {
! intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
! JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
assert(id != NULL, "corrupt Field object");
debug_only(id->set_is_static_field_id();)
// A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
ret = jfieldIDWorkaround::to_static_jfieldID(id);
return ret;
}
// The slot is the index of the field description in the field-array
// The jfieldID is the offset of the field within the object
// It may also have hash bits for k, if VerifyJNIFields is turned on.
! intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
! assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
! ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
return ret;
JNI_END
DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
*** 675,686 ****
}
if (ex->is_a(SystemDictionary::Throwable_klass())) {
JavaValue result(T_VOID);
JavaCalls::call_virtual(&result,
ex,
! KlassHandle(THREAD,
! SystemDictionary::Throwable_klass()),
vmSymbols::printStackTrace_name(),
vmSymbols::void_method_signature(),
THREAD);
// If an exception is thrown in the call it gets thrown away. Not much
// we can do with it. The native code that calls this, does not check
--- 673,683 ----
}
if (ex->is_a(SystemDictionary::Throwable_klass())) {
JavaValue result(T_VOID);
JavaCalls::call_virtual(&result,
ex,
! SystemDictionary::Throwable_klass(),
vmSymbols::printStackTrace_name(),
vmSymbols::void_method_signature(),
THREAD);
// If an exception is thrown in the call it gets thrown away. Not much
// we can do with it. The native code that calls this, does not check
*** 1154,1168 ****
// final method
selected_method = m;
}
} else {
// interface call
- KlassHandle h_holder(THREAD, holder);
-
int itbl_index = m->itable_index();
Klass* k = h_recv->klass();
! selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK);
}
}
methodHandle method(THREAD, selected_method);
--- 1151,1163 ----
// final method
selected_method = m;
}
} else {
// interface call
int itbl_index = m->itable_index();
Klass* k = h_recv->klass();
! selected_method = InstanceKlass::cast(k)->method_at_itable(holder, itbl_index, CHECK);
}
}
methodHandle method(THREAD, selected_method);
*** 1190,1207 ****
}
}
static instanceOop alloc_object(jclass clazz, TRAPS) {
! KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
if (k == NULL) {
ResourceMark rm(THREAD);
THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
}
! k()->check_valid_for_instantiation(false, CHECK_NULL);
! InstanceKlass::cast(k())->initialize(CHECK_NULL);
! instanceOop ih = InstanceKlass::cast(k())->allocate_instance(THREAD);
return ih;
}
DT_RETURN_MARK_DECL(AllocObject, jobject
, HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
--- 1185,1202 ----
}
}
static instanceOop alloc_object(jclass clazz, TRAPS) {
! Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
if (k == NULL) {
ResourceMark rm(THREAD);
THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
}
! k->check_valid_for_instantiation(false, CHECK_NULL);
! k->initialize(CHECK_NULL);
! instanceOop ih = InstanceKlass::cast(k)->allocate_instance(THREAD);
return ih;
}
DT_RETURN_MARK_DECL(AllocObject, jobject
, HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
*** 1336,1365 ****
// primitive java.lang.Class
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
}
! KlassHandle klass(THREAD,
! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
// Make sure class is linked and initialized before handing id's out to
// Method*s.
! klass()->initialize(CHECK_NULL);
Method* m;
if (name == vmSymbols::object_initializer_name() ||
name == vmSymbols::class_initializer_name()) {
// Never search superclasses for constructors
if (klass->is_instance_klass()) {
! m = InstanceKlass::cast(klass())->find_method(name, signature);
} else {
m = NULL;
}
} else {
m = klass->lookup_method(name, signature);
if (m == NULL && klass->is_instance_klass()) {
! m = InstanceKlass::cast(klass())->lookup_method_in_ordered_interfaces(name, signature);
}
}
if (m == NULL || (m->is_static() != is_static)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
}
--- 1331,1359 ----
// primitive java.lang.Class
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
}
! Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
// Make sure class is linked and initialized before handing id's out to
// Method*s.
! klass->initialize(CHECK_NULL);
Method* m;
if (name == vmSymbols::object_initializer_name() ||
name == vmSymbols::class_initializer_name()) {
// Never search superclasses for constructors
if (klass->is_instance_klass()) {
! m = InstanceKlass::cast(klass)->find_method(name, signature);
} else {
m = NULL;
}
} else {
m = klass->lookup_method(name, signature);
if (m == NULL && klass->is_instance_klass()) {
! m = InstanceKlass::cast(klass)->lookup_method_in_ordered_interfaces(name, signature);
}
}
if (m == NULL || (m->is_static() != is_static)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
}
*** 1877,1888 ****
(const ResultType&)ret);\
\
JavaValue jvalue(Tag); \
JNI_ArgumentPusherVaArg ap(methodID, args); \
/* Make sure class is initialized before trying to invoke its method */ \
! KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls))); \
! k()->initialize(CHECK_0); \
jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
va_end(args); \
ret = jvalue.get_##ResultType(); \
return ret;\
JNI_END
--- 1871,1882 ----
(const ResultType&)ret);\
\
JavaValue jvalue(Tag); \
JNI_ArgumentPusherVaArg ap(methodID, args); \
/* Make sure class is initialized before trying to invoke its method */ \
! Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); \
! k->initialize(CHECK_0); \
jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
va_end(args); \
ret = jvalue.get_##ResultType(); \
return ret;\
JNI_END
*** 2035,2058 ****
TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
if (fieldname == NULL || signame == NULL) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
! KlassHandle k(THREAD,
! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
// Make sure class is initialized before handing id's out to fields
! k()->initialize(CHECK_NULL);
fieldDescriptor fd;
! if (!k()->is_instance_klass() ||
! !InstanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
// A jfieldID for a non-static field is simply the offset of the field within the instanceOop
// It may also have hash bits for k, if VerifyJNIFields is turned on.
! ret = jfieldIDWorkaround::to_instance_jfieldID(k(), fd.offset());
return ret;
JNI_END
JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
--- 2029,2051 ----
TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
if (fieldname == NULL || signame == NULL) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
! Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
// Make sure class is initialized before handing id's out to fields
! k->initialize(CHECK_NULL);
fieldDescriptor fd;
! if (!k->is_instance_klass() ||
! !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
// A jfieldID for a non-static field is simply the offset of the field within the instanceOop
// It may also have hash bits for k, if VerifyJNIFields is turned on.
! ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset());
return ret;
JNI_END
JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
*** 2290,2307 ****
TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
if (fieldname == NULL || signame == NULL) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
! KlassHandle k(THREAD,
! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
// Make sure class is initialized before handing id's out to static fields
! k()->initialize(CHECK_NULL);
fieldDescriptor fd;
! if (!k()->is_instance_klass() ||
! !InstanceKlass::cast(k())->find_field(fieldname, signame, true, &fd)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
// A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
JNIid* id = fd.field_holder()->jni_id_for(fd.offset());
--- 2283,2299 ----
TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
if (fieldname == NULL || signame == NULL) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
! Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
// Make sure class is initialized before handing id's out to static fields
! k->initialize(CHECK_NULL);
fieldDescriptor fd;
! if (!k->is_instance_klass() ||
! !InstanceKlass::cast(k)->find_field(fieldname, signame, true, &fd)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
// A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
JNIid* id = fd.field_holder()->jni_id_for(fd.offset());
*** 2601,2615 ****
JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))
JNIWrapper("NewObjectArray");
HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(env, length, elementClass, initialElement);
jobjectArray ret = NULL;
DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
! KlassHandle ek(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass)));
! Klass* ako = ek()->array_klass(CHECK_NULL);
! KlassHandle ak = KlassHandle(THREAD, ako);
! ObjArrayKlass::cast(ak())->initialize(CHECK_NULL);
! objArrayOop result = ObjArrayKlass::cast(ak())->allocate(length, CHECK_NULL);
oop initial_value = JNIHandles::resolve(initialElement);
if (initial_value != NULL) { // array already initialized with NULL
for (int index = 0; index < length; index++) {
result->obj_at_put(index, initial_value);
}
--- 2593,2606 ----
JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))
JNIWrapper("NewObjectArray");
HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(env, length, elementClass, initialElement);
jobjectArray ret = NULL;
DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
! Klass* ek = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass));
! Klass* ak = ek->array_klass(CHECK_NULL);
! ObjArrayKlass::cast(ak)->initialize(CHECK_NULL);
! objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL);
oop initial_value = JNIHandles::resolve(initialElement);
if (initial_value != NULL) { // array already initialized with NULL
for (int index = 0; index < length; index++) {
result->obj_at_put(index, initial_value);
}
*** 2934,2945 ****
// The RegisterNatives call being attempted tried to register with a method that
// is not native. Ask JVM TI what prefixes have been specified. Then check
// to see if the native method is now wrapped with the prefixes. See the
// SetNativeMethodPrefix(es) functions in the JVM TI Spec for details.
! static Method* find_prefixed_native(KlassHandle k,
! Symbol* name, Symbol* signature, TRAPS) {
#if INCLUDE_JVMTI
ResourceMark rm(THREAD);
Method* method;
int name_len = name->utf8_length();
char* name_str = name->as_utf8();
--- 2925,2935 ----
// The RegisterNatives call being attempted tried to register with a method that
// is not native. Ask JVM TI what prefixes have been specified. Then check
// to see if the native method is now wrapped with the prefixes. See the
// SetNativeMethodPrefix(es) functions in the JVM TI Spec for details.
! static Method* find_prefixed_native(Klass* k, Symbol* name, Symbol* signature, TRAPS) {
#if INCLUDE_JVMTI
ResourceMark rm(THREAD);
Method* method;
int name_len = name->utf8_length();
char* name_str = name->as_utf8();
*** 2956,2966 ****
strcat(trial_name_str, name_str);
TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len);
if (trial_name == NULL) {
continue; // no such symbol, so this prefix wasn't used, try the next prefix
}
! method = k()->lookup_method(trial_name, signature);
if (method == NULL) {
continue; // signature doesn't match, try the next prefix
}
if (method->is_native()) {
method->set_is_prefixed_native();
--- 2946,2956 ----
strcat(trial_name_str, name_str);
TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len);
if (trial_name == NULL) {
continue; // no such symbol, so this prefix wasn't used, try the next prefix
}
! method = k->lookup_method(trial_name, signature);
if (method == NULL) {
continue; // signature doesn't match, try the next prefix
}
if (method->is_native()) {
method->set_is_prefixed_native();
*** 2972,2998 ****
}
#endif // INCLUDE_JVMTI
return NULL; // not found
}
! static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) {
! Method* method = k()->lookup_method(name, signature);
if (method == NULL) {
ResourceMark rm;
stringStream st;
st.print("Method %s name or signature does not match",
! Method::name_and_sig_as_C_string(k(), name, signature));
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
}
if (!method->is_native()) {
// trying to register to a non-native method, see if a JVM TI agent has added prefix(es)
method = find_prefixed_native(k, name, signature, THREAD);
if (method == NULL) {
ResourceMark rm;
stringStream st;
st.print("Method %s is not declared as native",
! Method::name_and_sig_as_C_string(k(), name, signature));
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
}
}
if (entry != NULL) {
--- 2962,2988 ----
}
#endif // INCLUDE_JVMTI
return NULL; // not found
}
! static bool register_native(Klass* k, Symbol* name, Symbol* signature, address entry, TRAPS) {
! Method* method = k->lookup_method(name, signature);
if (method == NULL) {
ResourceMark rm;
stringStream st;
st.print("Method %s name or signature does not match",
! Method::name_and_sig_as_C_string(k, name, signature));
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
}
if (!method->is_native()) {
// trying to register to a non-native method, see if a JVM TI agent has added prefix(es)
method = find_prefixed_native(k, name, signature, THREAD);
if (method == NULL) {
ResourceMark rm;
stringStream st;
st.print("Method %s is not declared as native",
! Method::name_and_sig_as_C_string(k, name, signature));
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
}
}
if (entry != NULL) {
*** 3019,3029 ****
JNIWrapper("RegisterNatives");
HOTSPOT_JNI_REGISTERNATIVES_ENTRY(env, clazz, (void *) methods, nMethods);
jint ret = 0;
DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);
! KlassHandle h_k(thread, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
for (int index = 0; index < nMethods; index++) {
const char* meth_name = methods[index].name;
const char* meth_sig = methods[index].signature;
int meth_name_len = (int)strlen(meth_name);
--- 3009,3019 ----
JNIWrapper("RegisterNatives");
HOTSPOT_JNI_REGISTERNATIVES_ENTRY(env, clazz, (void *) methods, nMethods);
jint ret = 0;
DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);
! Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
for (int index = 0; index < nMethods; index++) {
const char* meth_name = methods[index].name;
const char* meth_sig = methods[index].signature;
int meth_name_len = (int)strlen(meth_name);
*** 3035,3050 ****
TempNewSymbol signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig));
if (name == NULL || signature == NULL) {
ResourceMark rm;
stringStream st;
! st.print("Method %s.%s%s not found", h_k()->external_name(), meth_name, meth_sig);
// Must return negative value on failure
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
}
! bool res = register_native(h_k, name, signature,
(address) methods[index].fnPtr, THREAD);
if (!res) {
ret = -1;
break;
}
--- 3025,3040 ----
TempNewSymbol signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig));
if (name == NULL || signature == NULL) {
ResourceMark rm;
stringStream st;
! st.print("Method %s.%s%s not found", k->external_name(), meth_name, meth_sig);
// Must return negative value on failure
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
}
! bool res = register_native(k, name, signature,
(address) methods[index].fnPtr, THREAD);
if (!res) {
ret = -1;
break;
}
< prev index next >