diff options
Diffstat (limited to 'src/share/vm/prims/jni.cpp')
-rw-r--r-- | src/share/vm/prims/jni.cpp | 122 |
1 files changed, 63 insertions, 59 deletions
diff --git a/src/share/vm/prims/jni.cpp b/src/share/vm/prims/jni.cpp index c9450e9dc..ddbde753f 100644 --- a/src/share/vm/prims/jni.cpp +++ b/src/share/vm/prims/jni.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +24,7 @@ */ #include "precompiled.hpp" +#include "ci/ciReplay.hpp" #include "classfile/altHashing.hpp" #include "classfile/classLoader.hpp" #include "classfile/javaClasses.hpp" @@ -67,6 +69,7 @@ #include "runtime/reflection.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/signature.hpp" +#include "runtime/thread.inline.hpp" #include "runtime/vm_operations.hpp" #include "services/runtimeService.hpp" #include "trace/tracing.hpp" @@ -77,19 +80,15 @@ #include "utilities/histogram.hpp" #ifdef TARGET_OS_FAMILY_linux # include "os_linux.inline.hpp" -# include "thread_linux.inline.hpp" #endif #ifdef TARGET_OS_FAMILY_solaris # include "os_solaris.inline.hpp" -# include "thread_solaris.inline.hpp" #endif #ifdef TARGET_OS_FAMILY_windows # include "os_windows.inline.hpp" -# include "thread_windows.inline.hpp" #endif #ifdef TARGET_OS_FAMILY_bsd # include "os_bsd.inline.hpp" -# include "thread_bsd.inline.hpp" #endif static jint CurrentVersion = JNI_VERSION_1_6; @@ -232,13 +231,13 @@ bool jfieldIDWorkaround::is_valid_jfieldID(Klass* k, jfieldID id) { intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) { if (offset <= small_offset_mask) { Klass* field_klass = k; - Klass* super_klass = Klass::cast(field_klass)->super(); + Klass* super_klass = field_klass->super(); // With compressed oops the most super class with nonstatic fields would // be the owner of fields embedded in the header. while (InstanceKlass::cast(super_klass)->has_nonstatic_fields() && InstanceKlass::cast(super_klass)->contains_field_offset(offset)) { field_klass = super_klass; // super contains the field also - super_klass = Klass::cast(field_klass)->super(); + super_klass = field_klass->super(); } debug_only(No_Safepoint_Verifier nosafepoint;) uintptr_t klass_hash = field_klass->identity_hash(); @@ -248,7 +247,7 @@ intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) { #ifndef PRODUCT { ResourceMark rm; - warning("VerifyJNIFields: long offset %d in %s", offset, Klass::cast(k)->external_name()); + warning("VerifyJNIFields: long offset %d in %s", offset, k->external_name()); } #endif #endif @@ -264,7 +263,7 @@ bool jfieldIDWorkaround::klass_hash_ok(Klass* k, jfieldID id) { // Could use a non-blocking query for identity_hash here... if ((k->identity_hash() & klass_mask) == klass_hash) return true; - k = Klass::cast(k)->super(); + k = k->super(); } while (k != NULL); return false; } @@ -282,7 +281,7 @@ void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) { #ifndef PRODUCT if (Verbose) { ResourceMark rm; - warning("VerifyJNIFields: unverified offset %d for %s", offset, Klass::cast(k)->external_name()); + warning("VerifyJNIFields: unverified offset %d for %s", offset, k->external_name()); } #endif #endif @@ -414,7 +413,7 @@ JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderR } cls = (jclass)JNIHandles::make_local( - env, Klass::cast(k)->java_mirror()); + env, k->java_mirror()); return cls; JNI_END @@ -535,7 +534,7 @@ JNI_ENTRY(jmethodID, jni_FromReflectedMethod(JNIEnv *env, jobject method)) KlassHandle k1(THREAD, k); // Make sure class is initialized before handing id's out to methods - Klass::cast(k1())->initialize(CHECK_NULL); + 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; @@ -568,7 +567,7 @@ JNI_ENTRY(jfieldID, jni_FromReflectedField(JNIEnv *env, jobject field)) KlassHandle k1(THREAD, k); // Make sure class is initialized before handing id's out to fields - Klass::cast(k1())->initialize(CHECK_NULL); + k1()->initialize(CHECK_NULL); // First check if this is a static field if (modifiers & JVM_ACC_STATIC) { @@ -647,17 +646,17 @@ JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub)) // interfaces return NULL // proper classes return Klass::super() Klass* k = java_lang_Class::as_Klass(mirror); - if (Klass::cast(k)->is_interface()) return NULL; + if (k->is_interface()) return NULL; // return mirror for superclass - Klass* super = Klass::cast(k)->java_super(); + Klass* super = k->java_super(); // super2 is the value computed by the compiler's getSuperClass intrinsic: - debug_only(Klass* super2 = ( Klass::cast(k)->oop_is_array() + debug_only(Klass* super2 = ( k->oop_is_array() ? SystemDictionary::Object_klass() - : Klass::cast(k)->super() ) ); + : k->super() ) ); assert(super == super2, "java_super computation depends on interface, array, other super"); - obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(Klass::cast(super)->java_mirror()); + obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(super->java_mirror()); return obj; JNI_END @@ -685,7 +684,7 @@ JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass s Klass* sub_klass = java_lang_Class::as_Klass(sub_mirror); Klass* super_klass = java_lang_Class::as_Klass(super_mirror); assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom"); - jboolean ret = Klass::cast(sub_klass)->is_subtype_of(super_klass) ? + jboolean ret = sub_klass->is_subtype_of(super_klass) ? JNI_TRUE : JNI_FALSE; #ifndef USDT2 DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret); @@ -819,7 +818,7 @@ JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionDescribe(JNIEnv *env)) ResourceMark rm(THREAD); jio_fprintf(defaultStream::error_stream(), ". Uncaught exception of type %s.", - Klass::cast(ex->klass())->external_name()); + ex->klass()->external_name()); } } } @@ -1357,7 +1356,7 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive Method* m = Method::resolve_jmethod_id(method_id); number_of_parameters = m->size_of_parameters(); Klass* holder = m->method_holder(); - if (!(Klass::cast(holder))->is_interface()) { + if (!(holder)->is_interface()) { // non-interface call -- for that little speed boost, don't handlize debug_only(No_Safepoint_Verifier nosafepoint;) if (call_type == JNI_VIRTUAL) { @@ -1422,7 +1421,7 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive static instanceOop alloc_object(jclass clazz, TRAPS) { KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); - Klass::cast(k())->check_valid_for_instantiation(false, CHECK_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; @@ -1544,7 +1543,7 @@ JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj)) #endif /* USDT2 */ Klass* k = JNIHandles::resolve_non_null(obj)->klass(); jclass ret = - (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror()); + (jclass) JNIHandles::make_local(env, k->java_mirror()); #ifndef USDT2 DTRACE_PROBE1(hotspot_jni, GetObjectClass__return, ret); #else /* USDT2 */ @@ -1609,7 +1608,7 @@ static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str, // Make sure class is linked and initialized before handing id's out to // Method*s. - Klass::cast(klass())->initialize(CHECK_NULL); + klass()->initialize(CHECK_NULL); Method* m; if (name == vmSymbols::object_initializer_name() || @@ -2425,7 +2424,7 @@ JNI_ENTRY(ResultType, \ 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))); \ - Klass::cast(k())->initialize(CHECK_0); \ + k()->initialize(CHECK_0); \ jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \ va_end(args); \ ret = jvalue.get_##ResultType(); \ @@ -2610,10 +2609,10 @@ JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz, 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 - Klass::cast(k())->initialize(CHECK_NULL); + k()->initialize(CHECK_NULL); fieldDescriptor fd; - if (!Klass::cast(k())->oop_is_instance() || + if (!k()->oop_is_instance() || !InstanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) { THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name); } @@ -2820,10 +2819,9 @@ JNI_END JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \ JNIWrapper("Set" XSTR(Result) "Field"); \ \ - HS_DTRACE_PROBE_CDECL_N(hotspot_jni, Set##Result##Field__entry, \ - ( JNIEnv*, jobject, jfieldID FP_SELECT_##Result(COMMA Argument,/*empty*/) ) ); \ - HS_DTRACE_PROBE_N(hotspot_jni, Set##Result##Field__entry, \ - ( env, obj, fieldID FP_SELECT_##Result(COMMA value,/*empty*/) ) ); \ + FP_SELECT_##Result( \ + DTRACE_PROBE4(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID, value), \ + DTRACE_PROBE3(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID)); \ \ oop o = JNIHandles::resolve_non_null(obj); \ Klass* k = o->klass(); \ @@ -2976,16 +2974,16 @@ JNI_ENTRY(jfieldID, jni_GetStaticFieldID(JNIEnv *env, jclass clazz, 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 - Klass::cast(k())->initialize(CHECK_NULL); + k()->initialize(CHECK_NULL); fieldDescriptor fd; - if (!Klass::cast(k())->oop_is_instance() || + if (!k()->oop_is_instance() || !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 = InstanceKlass::cast(fd.field_holder())->jni_id_for(fd.offset()); + JNIid* id = fd.field_holder()->jni_id_for(fd.offset()); debug_only(id->set_is_static_field_id();) debug_only(id->verify(fd.field_holder())); @@ -3003,9 +3001,9 @@ JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY( env, clazz, (uintptr_t) fieldID); #endif /* USDT2 */ -#ifndef JNICHECK_KERNEL +#if INCLUDE_JNI_CHECK DEBUG_ONLY(Klass* param_k = jniCheck::validate_class(thread, clazz);) -#endif // JNICHECK_KERNEL +#endif // INCLUDE_JNI_CHECK JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); assert(id->is_static_field_id(), "invalid static field id"); // Keep JVMTI addition small and only check enabled flag here. @@ -3130,10 +3128,9 @@ JNI_END \ JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \ JNIWrapper("SetStatic" XSTR(Result) "Field"); \ - HS_DTRACE_PROBE_CDECL_N(hotspot_jni, SetStatic##Result##Field__entry,\ - ( JNIEnv*, jclass, jfieldID FP_SELECT_##Result(COMMA Argument,/*empty*/) ) ); \ - HS_DTRACE_PROBE_N(hotspot_jni, SetStatic##Result##Field__entry, \ - ( env, clazz, fieldID FP_SELECT_##Result(COMMA value,/*empty*/) ) ); \ + FP_SELECT_##Result( \ + DTRACE_PROBE4(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID, value), \ + DTRACE_PROBE3(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID)); \ \ JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \ assert(id->is_static_field_id(), "invalid static field id"); \ @@ -3440,10 +3437,10 @@ JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass ele 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 = Klass::cast(ek())->array_klass(CHECK_NULL); + 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); + 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++) { @@ -3502,7 +3499,7 @@ JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array)); oop v = JNIHandles::resolve(value); if (a->is_within_bounds(index)) { - if (v == NULL || v->is_a(objArrayKlass::cast(a->klass())->element_klass())) { + if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) { a->obj_at_put(index, v); } else { THROW(vmSymbols::java_lang_ArrayStoreException()); @@ -3787,7 +3784,7 @@ jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \ } else { \ if (len > 0) { \ - int sc = typeArrayKlass::cast(src->klass())->log2_element_size(); \ + int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \ memcpy((u_char*) buf, \ (u_char*) src->Tag##_at_addr(start), \ len << sc); \ @@ -3822,7 +3819,7 @@ jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \ } else { \ if (len > 0) { \ - int sc = typeArrayKlass::cast(src->klass())->log2_element_size(); \ + int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \ memcpy((u_char*) buf, \ (u_char*) src->Tag##_at_addr(start), \ len << sc); \ @@ -3871,7 +3868,7 @@ jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \ } else { \ if (len > 0) { \ - int sc = typeArrayKlass::cast(dst->klass())->log2_element_size(); \ + int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \ memcpy((u_char*) dst->Tag##_at_addr(start), \ (u_char*) buf, \ len << sc); \ @@ -3906,7 +3903,7 @@ jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \ } else { \ if (len > 0) { \ - int sc = typeArrayKlass::cast(dst->klass())->log2_element_size(); \ + int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \ memcpy((u_char*) dst->Tag##_at_addr(start), \ (u_char*) buf, \ len << sc); \ @@ -3951,6 +3948,7 @@ DEFINE_SETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double // 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(); @@ -3970,7 +3968,7 @@ static Method* find_prefixed_native(KlassHandle k, if (trial_name == NULL) { continue; // no such symbol, so this prefix wasn't used, try the next prefix } - method = Klass::cast(k())->lookup_method(trial_name, signature); + method = k()->lookup_method(trial_name, signature); if (method == NULL) { continue; // signature doesn't match, try the next prefix } @@ -3982,16 +3980,17 @@ static Method* find_prefixed_native(KlassHandle k, name_len = trial_len; name_str = trial_name_str; } +#endif // INCLUDE_JVMTI return NULL; // not found } static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) { - Method* method = Klass::cast(k())->lookup_method(name, signature); + 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(Klass::cast(k()), name, signature)); + Method::name_and_sig_as_C_string(k(), name, signature)); THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); } if (!method->is_native()) { @@ -4001,7 +4000,7 @@ static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, addr ResourceMark rm; stringStream st; st.print("Method %s is not declared as native", - Method::name_and_sig_as_C_string(Klass::cast(k()), name, signature)); + Method::name_and_sig_as_C_string(k(), name, signature)); THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); } } @@ -4015,7 +4014,7 @@ static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, addr if (PrintJNIResolving) { ResourceMark rm(THREAD); tty->print_cr("[Registering JNI native method %s.%s]", - Klass::cast(method->method_holder())->external_name(), + method->method_holder()->external_name(), method->name()->as_C_string()); } return true; @@ -4057,7 +4056,7 @@ JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz, if (name == NULL || signature == NULL) { ResourceMark rm; stringStream st; - st.print("Method %s.%s%s not found", Klass::cast(h_k())->external_name(), meth_name, meth_sig); + 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); } @@ -4083,7 +4082,7 @@ JNI_ENTRY(jint, jni_UnregisterNatives(JNIEnv *env, jclass clazz)) #endif /* USDT2 */ Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); //%note jni_2 - if (Klass::cast(k)->oop_is_instance()) { + if (k->oop_is_instance()) { for (int index = 0; index < InstanceKlass::cast(k)->methods()->length(); index++) { Method* m = InstanceKlass::cast(k)->methods()->at(index); if (m->is_native()) { @@ -4251,7 +4250,7 @@ JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboole if (a->is_objArray()) { type = T_OBJECT; } else { - type = typeArrayKlass::cast(a->klass())->element_type(); + type = TypeArrayKlass::cast(a->klass())->element_type(); } void* ret = arrayOop(a)->base(type); #ifndef USDT2 @@ -4975,11 +4974,9 @@ void quicken_jni_functions() { // Returns the function structure struct JNINativeInterface_* jni_functions() { -#ifndef JNICHECK_KERNEL +#if INCLUDE_JNI_CHECK if (CheckJNICalls) return jni_functions_check(); -#else // JNICHECK_KERNEL - if (CheckJNICalls) warning("-Xcheck:jni is not supported in kernel vm."); -#endif // JNICHECK_KERNEL +#endif // INCLUDE_JNI_CHECK return &jni_NativeInterface; } @@ -5044,6 +5041,9 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) { #include "gc_interface/collectedHeap.hpp" #include "utilities/quickSort.hpp" +#if INCLUDE_VM_STRUCTS +#include "runtime/vmStructs.hpp" +#endif #define run_unit_test(unit_test_function_call) \ tty->print_cr("Running test: " #unit_test_function_call); \ @@ -5056,6 +5056,9 @@ void execute_internal_vm_tests() { run_unit_test(CollectedHeap::test_is_in()); run_unit_test(QuickSort::test_quick_sort()); run_unit_test(AltHashing::test_alt_hash()); +#if INCLUDE_VM_STRUCTS + run_unit_test(VMStructs::test()); +#endif tty->print_cr("All internal VM tests passed"); } } @@ -5152,6 +5155,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, v // Check if we should compile all classes on bootclasspath NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();) + NOT_PRODUCT(if (ReplayCompiles) ciReplay::replay(thread);) // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving. ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native); } else { |