< prev index next >

src/share/vm/prims/jni.cpp

Print this page

        

*** 29,38 **** --- 29,39 ---- #include "classfile/classLoader.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" + #include "code/dependencies.hpp" #include "gc/shared/gcLocker.inline.hpp" #include "interpreter/linkResolver.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "memory/oopFactory.hpp"
*** 58,67 **** --- 59,69 ---- #include "runtime/atomic.inline.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/fprofiler.hpp" #include "runtime/handles.inline.hpp" + #include "runtime/init.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/java.hpp" #include "runtime/javaCalls.hpp" #include "runtime/jfieldIDWorkaround.hpp" #include "runtime/orderAccess.inline.hpp"
*** 166,176 **** // out-of-line helpers for class jfieldIDWorkaround: bool jfieldIDWorkaround::is_valid_jfieldID(Klass* k, jfieldID id) { ! if (jfieldIDWorkaround::is_instance_jfieldID(k, id)) { uintptr_t as_uint = (uintptr_t) id; intptr_t offset = raw_instance_offset(id); if (is_checked_jfieldID(id)) { if (!klass_hash_ok(k, id)) { return false; --- 168,178 ---- // out-of-line helpers for class jfieldIDWorkaround: bool jfieldIDWorkaround::is_valid_jfieldID(Klass* k, jfieldID id) { ! if (jfieldIDWorkaround::is_instance_jfieldID(id)) { uintptr_t as_uint = (uintptr_t) id; intptr_t offset = raw_instance_offset(id); if (is_checked_jfieldID(id)) { if (!klass_hash_ok(k, id)) { return false;
*** 227,237 **** } while (k != NULL); return false; } void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) { ! guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" ); uintptr_t as_uint = (uintptr_t) id; intptr_t offset = raw_instance_offset(id); if (VerifyJNIFields) { if (is_checked_jfieldID(id)) { guarantee(klass_hash_ok(k, id), --- 229,239 ---- } while (k != NULL); return false; } void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) { ! guarantee(jfieldIDWorkaround::is_instance_jfieldID(id), "must be an instance field" ); uintptr_t as_uint = (uintptr_t) id; intptr_t offset = raw_instance_offset(id); if (VerifyJNIFields) { if (is_checked_jfieldID(id)) { guarantee(klass_hash_ok(k, id),
*** 504,514 **** // 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 --- 506,517 ---- // 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"); ! bool is_final = (modifiers & JVM_ACC_FINAL) != 0; ! ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset, is_final); return ret; JNI_END DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
*** 2039,2049 **** 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)) --- 2042,2052 ---- 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(), fd.access_flags().is_final()); return ret; JNI_END JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
*** 2159,2171 **** --- 2162,2191 ---- } address jni_GetDoubleField_addr() { return (address)jni_GetDoubleField; } + static void check_final_field(jobject obj, jfieldID fieldID, TRAPS) { + if (TrustFinalNonStaticFields && + jfieldIDWorkaround::is_final_jfieldID(fieldID) && + jfieldIDWorkaround::is_instance_jfieldID(fieldID)) { + ResetNoHandleMark rm; + HandleMark hm; + Handle recv(THREAD, JNIHandles::resolve(obj)); + if (!recv.is_null()) { + instanceKlassHandle ctxk(THREAD, InstanceKlass::cast(recv->klass())); + int offset = (int)jfieldIDWorkaround::from_instance_jfieldID(ctxk(), fieldID); + ConstantFieldDepChange changes(recv, offset); + Dependencies::invalidate_dependent_nmethods(ctxk, changes, THREAD); + } + } + } + JNI_QUICK_ENTRY(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)) JNIWrapper("SetObjectField"); HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value); + check_final_field(obj, fieldID, thread); oop o = JNIHandles::resolve_non_null(obj); Klass* k = o->klass(); int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); // Keep JVMTI addition small and only check enabled flag here. // jni_SetField_probe_nh() assumes that is not okay to create handles
*** 2186,2195 **** --- 2206,2216 ---- JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \ JNIWrapper("Set" XSTR(Result) "Field"); \ \ EntryProbe; \ \ + check_final_field(obj, fieldID, thread); \ oop o = JNIHandles::resolve_non_null(obj); \ Klass* k = o->klass(); \ int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \ /* Keep JVMTI addition small and only check enabled flag here. */ \ /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
< prev index next >