< prev index next >

src/share/vm/prims/jni.cpp

Print this page

        

@@ -29,10 +29,11 @@
 #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,10 +59,11 @@
 #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,11 +168,11 @@
 
 
 // out-of-line helpers for class jfieldIDWorkaround:
 
 bool jfieldIDWorkaround::is_valid_jfieldID(Klass* k, jfieldID id) {
-  if (jfieldIDWorkaround::is_instance_jfieldID(k, 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,11 +229,11 @@
   } 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" );
+  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,11 +506,12 @@
   // 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);
+  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,11 +2042,11 @@
     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());
+  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,13 +2162,30 @@
 }
 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,10 +2206,11 @@
 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 >