< prev index next >

src/share/vm/prims/jni.cpp

Print this page




  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "ci/ciReplay.hpp"
  28 #include "classfile/altHashing.hpp"
  29 #include "classfile/classLoader.hpp"
  30 #include "classfile/javaClasses.hpp"
  31 #include "classfile/symbolTable.hpp"
  32 #include "classfile/systemDictionary.hpp"
  33 #include "classfile/vmSymbols.hpp"

  34 #include "gc/shared/gcLocker.inline.hpp"
  35 #include "interpreter/linkResolver.hpp"
  36 #include "memory/allocation.hpp"
  37 #include "memory/allocation.inline.hpp"
  38 #include "memory/oopFactory.hpp"
  39 #include "memory/universe.inline.hpp"
  40 #include "oops/instanceKlass.hpp"
  41 #include "oops/instanceOop.hpp"
  42 #include "oops/markOop.hpp"
  43 #include "oops/method.hpp"
  44 #include "oops/objArrayKlass.hpp"
  45 #include "oops/objArrayOop.inline.hpp"
  46 #include "oops/oop.inline.hpp"
  47 #include "oops/symbol.hpp"
  48 #include "oops/typeArrayKlass.hpp"
  49 #include "oops/typeArrayOop.hpp"
  50 #include "prims/jni.h"
  51 #include "prims/jniCheck.hpp"
  52 #include "prims/jniExport.hpp"
  53 #include "prims/jniFastGetField.hpp"
  54 #include "prims/jvm.h"
  55 #include "prims/jvm_misc.hpp"
  56 #include "prims/jvmtiExport.hpp"
  57 #include "prims/jvmtiThreadState.hpp"
  58 #include "runtime/atomic.inline.hpp"
  59 #include "runtime/compilationPolicy.hpp"
  60 #include "runtime/fieldDescriptor.hpp"
  61 #include "runtime/fprofiler.hpp"
  62 #include "runtime/handles.inline.hpp"

  63 #include "runtime/interfaceSupport.hpp"
  64 #include "runtime/java.hpp"
  65 #include "runtime/javaCalls.hpp"
  66 #include "runtime/jfieldIDWorkaround.hpp"
  67 #include "runtime/orderAccess.inline.hpp"
  68 #include "runtime/reflection.hpp"
  69 #include "runtime/sharedRuntime.hpp"
  70 #include "runtime/signature.hpp"
  71 #include "runtime/thread.inline.hpp"
  72 #include "runtime/vm_operations.hpp"
  73 #include "services/memTracker.hpp"
  74 #include "services/runtimeService.hpp"
  75 #include "trace/tracing.hpp"
  76 #include "utilities/defaultStream.hpp"
  77 #include "utilities/dtrace.hpp"
  78 #include "utilities/events.hpp"
  79 #include "utilities/histogram.hpp"
  80 #include "utilities/macros.hpp"
  81 #if INCLUDE_ALL_GCS
  82 #include "gc/g1/g1SATBCardTableModRefBS.hpp"


 151 #define FP_SELECT_Float(intcode, fpcode)   fpcode
 152 #define FP_SELECT_Double(intcode, fpcode)  fpcode
 153 #define FP_SELECT(TypeName, intcode, fpcode) \
 154   FP_SELECT_##TypeName(intcode, fpcode)
 155 
 156 #define COMMA ,
 157 
 158 // Choose DT_RETURN_MARK macros  based on the type: float/double -> void
 159 // (dtrace doesn't do FP yet)
 160 #define DT_RETURN_MARK_DECL_FOR(TypeName, name, type, probe)    \
 161   FP_SELECT(TypeName, \
 162     DT_RETURN_MARK_DECL(name, type, probe), DT_VOID_RETURN_MARK_DECL(name, probe) )
 163 #define DT_RETURN_MARK_FOR(TypeName, name, type, ref) \
 164   FP_SELECT(TypeName, \
 165     DT_RETURN_MARK(name, type, ref), DT_VOID_RETURN_MARK(name) )
 166 
 167 
 168 // out-of-line helpers for class jfieldIDWorkaround:
 169 
 170 bool jfieldIDWorkaround::is_valid_jfieldID(Klass* k, jfieldID id) {
 171   if (jfieldIDWorkaround::is_instance_jfieldID(k, id)) {
 172     uintptr_t as_uint = (uintptr_t) id;
 173     intptr_t offset = raw_instance_offset(id);
 174     if (is_checked_jfieldID(id)) {
 175       if (!klass_hash_ok(k, id)) {
 176         return false;
 177       }
 178     }
 179     return InstanceKlass::cast(k)->contains_field_offset(offset);
 180   } else {
 181     JNIid* result = (JNIid*) id;
 182 #ifdef ASSERT
 183     return result != NULL && result->is_static_field_id();
 184 #else
 185     return result != NULL;
 186 #endif
 187   }
 188 }
 189 
 190 
 191 intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) {


 212     #endif
 213 #endif
 214     return 0;
 215   }
 216 }
 217 
 218 bool jfieldIDWorkaround::klass_hash_ok(Klass* k, jfieldID id) {
 219   uintptr_t as_uint = (uintptr_t) id;
 220   intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask;
 221   do {
 222     debug_only(No_Safepoint_Verifier nosafepoint;)
 223     // Could use a non-blocking query for identity_hash here...
 224     if ((k->identity_hash() & klass_mask) == klass_hash)
 225       return true;
 226     k = k->super();
 227   } while (k != NULL);
 228   return false;
 229 }
 230 
 231 void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) {
 232   guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" );
 233   uintptr_t as_uint = (uintptr_t) id;
 234   intptr_t offset = raw_instance_offset(id);
 235   if (VerifyJNIFields) {
 236     if (is_checked_jfieldID(id)) {
 237       guarantee(klass_hash_ok(k, id),
 238     "Bug in native code: jfieldID class must match object");
 239     } else {
 240 #if 0
 241       #ifndef PRODUCT
 242       if (Verbose) {
 243   ResourceMark rm;
 244   warning("VerifyJNIFields: unverified offset %d for %s", offset, k->external_name());
 245       }
 246       #endif
 247 #endif
 248     }
 249   }
 250   guarantee(InstanceKlass::cast(k)->contains_field_offset(offset),
 251       "Bug in native code: jfieldID offset must address interior of object");
 252 }


 489   KlassHandle k1(THREAD, k);
 490   // Make sure class is initialized before handing id's out to fields
 491   k1()->initialize(CHECK_NULL);
 492 
 493   // First check if this is a static field
 494   if (modifiers & JVM_ACC_STATIC) {
 495     intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );
 496     JNIid* id = InstanceKlass::cast(k1())->jni_id_for(offset);
 497     assert(id != NULL, "corrupt Field object");
 498     debug_only(id->set_is_static_field_id();)
 499     // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
 500     ret = jfieldIDWorkaround::to_static_jfieldID(id);
 501     return ret;
 502   }
 503 
 504   // The slot is the index of the field description in the field-array
 505   // The jfieldID is the offset of the field within the object
 506   // It may also have hash bits for k, if VerifyJNIFields is turned on.
 507   intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );
 508   assert(InstanceKlass::cast(k1())->contains_field_offset(offset), "stay within object");
 509   ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset);

 510   return ret;
 511 JNI_END
 512 
 513 
 514 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 515                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 516 
 517 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 518   JNIWrapper("ToReflectedMethod");
 519 
 520   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 521 
 522   jobject ret = NULL;
 523   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 524 
 525   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 526   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 527   oop reflection_method;
 528   if (m->is_initializer()) {
 529     reflection_method = Reflection::new_constructor(m, CHECK_NULL);


2024   // passed in) so the field and signature should already be in the symbol
2025   // table.  If they're not there, the field doesn't exist.
2026   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
2027   TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
2028   if (fieldname == NULL || signame == NULL) {
2029     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2030   }
2031   KlassHandle k(THREAD,
2032                 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
2033   // Make sure class is initialized before handing id's out to fields
2034   k()->initialize(CHECK_NULL);
2035 
2036   fieldDescriptor fd;
2037   if (!k()->oop_is_instance() ||
2038       !InstanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) {
2039     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2040   }
2041 
2042   // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
2043   // It may also have hash bits for k, if VerifyJNIFields is turned on.
2044   ret = jfieldIDWorkaround::to_instance_jfieldID(k(), fd.offset());
2045   return ret;
2046 JNI_END
2047 
2048 
2049 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
2050   JNIWrapper("GetObjectField");
2051   HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
2052   oop o = JNIHandles::resolve_non_null(obj);
2053   Klass* k = o->klass();
2054   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2055   // Keep JVMTI addition small and only check enabled flag here.
2056   // jni_GetField_probe() assumes that is okay to create handles.
2057   if (JvmtiExport::should_post_field_access()) {
2058     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2059   }
2060   jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
2061 #if INCLUDE_ALL_GCS
2062   // If G1 is enabled and we are accessing the value of the referent
2063   // field in a reference object then we need to register a non-null
2064   // referent with the SATB barrier.


2144 }
2145 address jni_GetCharField_addr() {
2146   return (address)jni_GetCharField;
2147 }
2148 address jni_GetShortField_addr() {
2149   return (address)jni_GetShortField;
2150 }
2151 address jni_GetIntField_addr() {
2152   return (address)jni_GetIntField;
2153 }
2154 address jni_GetLongField_addr() {
2155   return (address)jni_GetLongField;
2156 }
2157 address jni_GetFloatField_addr() {
2158   return (address)jni_GetFloatField;
2159 }
2160 address jni_GetDoubleField_addr() {
2161   return (address)jni_GetDoubleField;
2162 }
2163 
















2164 JNI_QUICK_ENTRY(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
2165   JNIWrapper("SetObjectField");
2166   HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);

2167   oop o = JNIHandles::resolve_non_null(obj);
2168   Klass* k = o->klass();
2169   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2170   // Keep JVMTI addition small and only check enabled flag here.
2171   // jni_SetField_probe_nh() assumes that is not okay to create handles
2172   // and creates a ResetNoHandleMark.
2173   if (JvmtiExport::should_post_field_modification()) {
2174     jvalue field_value;
2175     field_value.l = value;
2176     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value);
2177   }
2178   o->obj_field_put(offset, JNIHandles::resolve(value));
2179   HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
2180 JNI_END
2181 
2182 
2183 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
2184                         , EntryProbe, ReturnProbe) \
2185 \
2186 JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
2187   JNIWrapper("Set" XSTR(Result) "Field"); \
2188 \
2189   EntryProbe; \
2190 \

2191   oop o = JNIHandles::resolve_non_null(obj); \
2192   Klass* k = o->klass(); \
2193   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
2194   /* Keep JVMTI addition small and only check enabled flag here.       */ \
2195   /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
2196   /* and creates a ResetNoHandleMark.                                   */ \
2197   if (JvmtiExport::should_post_field_modification()) { \
2198     jvalue field_value; \
2199     field_value.unionType = value; \
2200     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
2201   } \
2202   o->Fieldname##_field_put(offset, value); \
2203   ReturnProbe; \
2204 JNI_END
2205 
2206 DEFINE_SETFIELD(jboolean, bool,   Boolean, 'Z', z
2207                 , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2208                 HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
2209 DEFINE_SETFIELD(jbyte,    byte,   Byte,    'B', b
2210                 , HOTSPOT_JNI_SETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),




  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "ci/ciReplay.hpp"
  28 #include "classfile/altHashing.hpp"
  29 #include "classfile/classLoader.hpp"
  30 #include "classfile/javaClasses.hpp"
  31 #include "classfile/symbolTable.hpp"
  32 #include "classfile/systemDictionary.hpp"
  33 #include "classfile/vmSymbols.hpp"
  34 #include "code/dependencies.hpp"
  35 #include "gc/shared/gcLocker.inline.hpp"
  36 #include "interpreter/linkResolver.hpp"
  37 #include "memory/allocation.hpp"
  38 #include "memory/allocation.inline.hpp"
  39 #include "memory/oopFactory.hpp"
  40 #include "memory/universe.inline.hpp"
  41 #include "oops/instanceKlass.hpp"
  42 #include "oops/instanceOop.hpp"
  43 #include "oops/markOop.hpp"
  44 #include "oops/method.hpp"
  45 #include "oops/objArrayKlass.hpp"
  46 #include "oops/objArrayOop.inline.hpp"
  47 #include "oops/oop.inline.hpp"
  48 #include "oops/symbol.hpp"
  49 #include "oops/typeArrayKlass.hpp"
  50 #include "oops/typeArrayOop.hpp"
  51 #include "prims/jni.h"
  52 #include "prims/jniCheck.hpp"
  53 #include "prims/jniExport.hpp"
  54 #include "prims/jniFastGetField.hpp"
  55 #include "prims/jvm.h"
  56 #include "prims/jvm_misc.hpp"
  57 #include "prims/jvmtiExport.hpp"
  58 #include "prims/jvmtiThreadState.hpp"
  59 #include "runtime/atomic.inline.hpp"
  60 #include "runtime/compilationPolicy.hpp"
  61 #include "runtime/fieldDescriptor.hpp"
  62 #include "runtime/fprofiler.hpp"
  63 #include "runtime/handles.inline.hpp"
  64 #include "runtime/init.hpp"
  65 #include "runtime/interfaceSupport.hpp"
  66 #include "runtime/java.hpp"
  67 #include "runtime/javaCalls.hpp"
  68 #include "runtime/jfieldIDWorkaround.hpp"
  69 #include "runtime/orderAccess.inline.hpp"
  70 #include "runtime/reflection.hpp"
  71 #include "runtime/sharedRuntime.hpp"
  72 #include "runtime/signature.hpp"
  73 #include "runtime/thread.inline.hpp"
  74 #include "runtime/vm_operations.hpp"
  75 #include "services/memTracker.hpp"
  76 #include "services/runtimeService.hpp"
  77 #include "trace/tracing.hpp"
  78 #include "utilities/defaultStream.hpp"
  79 #include "utilities/dtrace.hpp"
  80 #include "utilities/events.hpp"
  81 #include "utilities/histogram.hpp"
  82 #include "utilities/macros.hpp"
  83 #if INCLUDE_ALL_GCS
  84 #include "gc/g1/g1SATBCardTableModRefBS.hpp"


 153 #define FP_SELECT_Float(intcode, fpcode)   fpcode
 154 #define FP_SELECT_Double(intcode, fpcode)  fpcode
 155 #define FP_SELECT(TypeName, intcode, fpcode) \
 156   FP_SELECT_##TypeName(intcode, fpcode)
 157 
 158 #define COMMA ,
 159 
 160 // Choose DT_RETURN_MARK macros  based on the type: float/double -> void
 161 // (dtrace doesn't do FP yet)
 162 #define DT_RETURN_MARK_DECL_FOR(TypeName, name, type, probe)    \
 163   FP_SELECT(TypeName, \
 164     DT_RETURN_MARK_DECL(name, type, probe), DT_VOID_RETURN_MARK_DECL(name, probe) )
 165 #define DT_RETURN_MARK_FOR(TypeName, name, type, ref) \
 166   FP_SELECT(TypeName, \
 167     DT_RETURN_MARK(name, type, ref), DT_VOID_RETURN_MARK(name) )
 168 
 169 
 170 // out-of-line helpers for class jfieldIDWorkaround:
 171 
 172 bool jfieldIDWorkaround::is_valid_jfieldID(Klass* k, jfieldID id) {
 173   if (jfieldIDWorkaround::is_instance_jfieldID(id)) {
 174     uintptr_t as_uint = (uintptr_t) id;
 175     intptr_t offset = raw_instance_offset(id);
 176     if (is_checked_jfieldID(id)) {
 177       if (!klass_hash_ok(k, id)) {
 178         return false;
 179       }
 180     }
 181     return InstanceKlass::cast(k)->contains_field_offset(offset);
 182   } else {
 183     JNIid* result = (JNIid*) id;
 184 #ifdef ASSERT
 185     return result != NULL && result->is_static_field_id();
 186 #else
 187     return result != NULL;
 188 #endif
 189   }
 190 }
 191 
 192 
 193 intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) {


 214     #endif
 215 #endif
 216     return 0;
 217   }
 218 }
 219 
 220 bool jfieldIDWorkaround::klass_hash_ok(Klass* k, jfieldID id) {
 221   uintptr_t as_uint = (uintptr_t) id;
 222   intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask;
 223   do {
 224     debug_only(No_Safepoint_Verifier nosafepoint;)
 225     // Could use a non-blocking query for identity_hash here...
 226     if ((k->identity_hash() & klass_mask) == klass_hash)
 227       return true;
 228     k = k->super();
 229   } while (k != NULL);
 230   return false;
 231 }
 232 
 233 void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) {
 234   guarantee(jfieldIDWorkaround::is_instance_jfieldID(id), "must be an instance field" );
 235   uintptr_t as_uint = (uintptr_t) id;
 236   intptr_t offset = raw_instance_offset(id);
 237   if (VerifyJNIFields) {
 238     if (is_checked_jfieldID(id)) {
 239       guarantee(klass_hash_ok(k, id),
 240     "Bug in native code: jfieldID class must match object");
 241     } else {
 242 #if 0
 243       #ifndef PRODUCT
 244       if (Verbose) {
 245   ResourceMark rm;
 246   warning("VerifyJNIFields: unverified offset %d for %s", offset, k->external_name());
 247       }
 248       #endif
 249 #endif
 250     }
 251   }
 252   guarantee(InstanceKlass::cast(k)->contains_field_offset(offset),
 253       "Bug in native code: jfieldID offset must address interior of object");
 254 }


 491   KlassHandle k1(THREAD, k);
 492   // Make sure class is initialized before handing id's out to fields
 493   k1()->initialize(CHECK_NULL);
 494 
 495   // First check if this is a static field
 496   if (modifiers & JVM_ACC_STATIC) {
 497     intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );
 498     JNIid* id = InstanceKlass::cast(k1())->jni_id_for(offset);
 499     assert(id != NULL, "corrupt Field object");
 500     debug_only(id->set_is_static_field_id();)
 501     // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
 502     ret = jfieldIDWorkaround::to_static_jfieldID(id);
 503     return ret;
 504   }
 505 
 506   // The slot is the index of the field description in the field-array
 507   // The jfieldID is the offset of the field within the object
 508   // It may also have hash bits for k, if VerifyJNIFields is turned on.
 509   intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );
 510   assert(InstanceKlass::cast(k1())->contains_field_offset(offset), "stay within object");
 511   bool is_final = (modifiers & JVM_ACC_FINAL) != 0;
 512   ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset, is_final);
 513   return ret;
 514 JNI_END
 515 
 516 
 517 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 518                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 519 
 520 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 521   JNIWrapper("ToReflectedMethod");
 522 
 523   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 524 
 525   jobject ret = NULL;
 526   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 527 
 528   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 529   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 530   oop reflection_method;
 531   if (m->is_initializer()) {
 532     reflection_method = Reflection::new_constructor(m, CHECK_NULL);


2027   // passed in) so the field and signature should already be in the symbol
2028   // table.  If they're not there, the field doesn't exist.
2029   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
2030   TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
2031   if (fieldname == NULL || signame == NULL) {
2032     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2033   }
2034   KlassHandle k(THREAD,
2035                 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
2036   // Make sure class is initialized before handing id's out to fields
2037   k()->initialize(CHECK_NULL);
2038 
2039   fieldDescriptor fd;
2040   if (!k()->oop_is_instance() ||
2041       !InstanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) {
2042     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2043   }
2044 
2045   // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
2046   // It may also have hash bits for k, if VerifyJNIFields is turned on.
2047   ret = jfieldIDWorkaround::to_instance_jfieldID(k(), fd.offset(), fd.access_flags().is_final());
2048   return ret;
2049 JNI_END
2050 
2051 
2052 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
2053   JNIWrapper("GetObjectField");
2054   HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
2055   oop o = JNIHandles::resolve_non_null(obj);
2056   Klass* k = o->klass();
2057   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2058   // Keep JVMTI addition small and only check enabled flag here.
2059   // jni_GetField_probe() assumes that is okay to create handles.
2060   if (JvmtiExport::should_post_field_access()) {
2061     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2062   }
2063   jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
2064 #if INCLUDE_ALL_GCS
2065   // If G1 is enabled and we are accessing the value of the referent
2066   // field in a reference object then we need to register a non-null
2067   // referent with the SATB barrier.


2147 }
2148 address jni_GetCharField_addr() {
2149   return (address)jni_GetCharField;
2150 }
2151 address jni_GetShortField_addr() {
2152   return (address)jni_GetShortField;
2153 }
2154 address jni_GetIntField_addr() {
2155   return (address)jni_GetIntField;
2156 }
2157 address jni_GetLongField_addr() {
2158   return (address)jni_GetLongField;
2159 }
2160 address jni_GetFloatField_addr() {
2161   return (address)jni_GetFloatField;
2162 }
2163 address jni_GetDoubleField_addr() {
2164   return (address)jni_GetDoubleField;
2165 }
2166 
2167 static void check_final_field(jobject obj, jfieldID fieldID, TRAPS) {
2168   if (TrustFinalNonStaticFields &&
2169       jfieldIDWorkaround::is_final_jfieldID(fieldID) &&
2170       jfieldIDWorkaround::is_instance_jfieldID(fieldID)) {
2171     ResetNoHandleMark rm;
2172     HandleMark hm;
2173     Handle recv(THREAD, JNIHandles::resolve(obj));
2174     if (!recv.is_null()) {
2175       instanceKlassHandle ctxk(THREAD, InstanceKlass::cast(recv->klass()));
2176       int offset = (int)jfieldIDWorkaround::from_instance_jfieldID(ctxk(), fieldID);
2177       ConstantFieldDepChange changes(recv, offset);
2178       Dependencies::invalidate_dependent_nmethods(ctxk, changes, THREAD);
2179     }
2180   }
2181 }
2182 
2183 JNI_QUICK_ENTRY(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
2184   JNIWrapper("SetObjectField");
2185   HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
2186   check_final_field(obj, fieldID, thread);
2187   oop o = JNIHandles::resolve_non_null(obj);
2188   Klass* k = o->klass();
2189   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2190   // Keep JVMTI addition small and only check enabled flag here.
2191   // jni_SetField_probe_nh() assumes that is not okay to create handles
2192   // and creates a ResetNoHandleMark.
2193   if (JvmtiExport::should_post_field_modification()) {
2194     jvalue field_value;
2195     field_value.l = value;
2196     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value);
2197   }
2198   o->obj_field_put(offset, JNIHandles::resolve(value));
2199   HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
2200 JNI_END
2201 
2202 
2203 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
2204                         , EntryProbe, ReturnProbe) \
2205 \
2206 JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
2207   JNIWrapper("Set" XSTR(Result) "Field"); \
2208 \
2209   EntryProbe; \
2210 \
2211   check_final_field(obj, fieldID, thread); \
2212   oop o = JNIHandles::resolve_non_null(obj); \
2213   Klass* k = o->klass(); \
2214   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
2215   /* Keep JVMTI addition small and only check enabled flag here.       */ \
2216   /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
2217   /* and creates a ResetNoHandleMark.                                   */ \
2218   if (JvmtiExport::should_post_field_modification()) { \
2219     jvalue field_value; \
2220     field_value.unionType = value; \
2221     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
2222   } \
2223   o->Fieldname##_field_put(offset, value); \
2224   ReturnProbe; \
2225 JNI_END
2226 
2227 DEFINE_SETFIELD(jboolean, bool,   Boolean, 'Z', z
2228                 , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2229                 HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
2230 DEFINE_SETFIELD(jbyte,    byte,   Byte,    'B', b
2231                 , HOTSPOT_JNI_SETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),


< prev index next >