< prev index next >

src/share/vm/prims/methodHandles.cpp

Print this page




  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/stringTable.hpp"
  28 #include "code/codeCache.hpp"
  29 #include "compiler/compileBroker.hpp"
  30 #include "interpreter/interpreter.hpp"
  31 #include "interpreter/oopMapCache.hpp"
  32 #include "interpreter/linkResolver.hpp"
  33 #include "memory/allocation.inline.hpp"
  34 #include "memory/oopFactory.hpp"
  35 #include "oops/objArrayOop.inline.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "prims/methodHandles.hpp"
  38 #include "prims/jvmtiRedefineClassesTrace.hpp"

  39 #include "runtime/compilationPolicy.hpp"
  40 #include "runtime/javaCalls.hpp"
  41 #include "runtime/reflection.hpp"
  42 #include "runtime/signature.hpp"
  43 #include "runtime/stubRoutines.hpp"
  44 #include "utilities/exceptions.hpp"
  45 
  46 
  47 /*
  48  * JSR 292 reference implementation: method handles
  49  * The JDK 7 reference implementation represented method handle
  50  * combinations as chains.  Each link in the chain had a "vmentry"
  51  * field which pointed at a bit of assembly code which performed
  52  * one transformation before dispatching to the next link in the chain.
  53  *
  54  * The current reference implementation pushes almost all code generation
  55  * responsibility to (trusted) Java code.  A method handle contains a
  56  * pointer to its "LambdaForm", which embodies all details of the method
  57  * handle's behavior.  The LambdaForm is a normal Java object, managed
  58  * by a runtime coded in Java.


1197     } else {
1198       THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed");
1199     }
1200   }
1201 
1202   return JNIHandles::make_local(THREAD, resolved());
1203 }
1204 JVM_END
1205 
1206 static jlong find_member_field_offset(oop mname, bool must_be_static, TRAPS) {
1207   if (mname == NULL ||
1208       java_lang_invoke_MemberName::vmtarget(mname) == NULL) {
1209     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "mname not resolved");
1210   } else {
1211     int flags = java_lang_invoke_MemberName::flags(mname);
1212     if ((flags & IS_FIELD) != 0 &&
1213         (must_be_static
1214          ? (flags & JVM_ACC_STATIC) != 0
1215          : (flags & JVM_ACC_STATIC) == 0)) {
1216       int vmindex = java_lang_invoke_MemberName::vmindex(mname);
1217       return (jlong) vmindex;

1218     }
1219   }
1220   const char* msg = (must_be_static ? "static field required" : "non-static field required");
1221   THROW_MSG_0(vmSymbols::java_lang_InternalError(), msg);
1222   return 0;
1223 }
1224 
1225 JVM_ENTRY(jlong, MHN_objectFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1226   return find_member_field_offset(JNIHandles::resolve(mname_jh), false, THREAD);
1227 }
1228 JVM_END
1229 
1230 JVM_ENTRY(jlong, MHN_staticFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1231   return find_member_field_offset(JNIHandles::resolve(mname_jh), true, THREAD);
1232 }
1233 JVM_END
1234 
1235 JVM_ENTRY(jobject, MHN_staticFieldBase(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1236   // use the other function to perform sanity checks:
1237   jlong ignore = find_member_field_offset(JNIHandles::resolve(mname_jh), true, CHECK_NULL);


1322   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1323   {
1324     // Walk all nmethods depending on this call site.
1325     MutexLocker mu(Compile_lock, thread);
1326     MethodHandles::flush_dependent_nmethods(call_site, target);
1327     java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
1328   }
1329 }
1330 JVM_END
1331 
1332 JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
1333   Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
1334   {
1335     // Walk all nmethods depending on this call site.
1336     MutexLocker mu1(Compile_lock, thread);
1337 
1338     int marked = 0;
1339     {
1340       MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1341       nmethodBucket* b = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context());
1342       while(b != NULL) {
1343         nmethod* nm = b->get_nmethod();
1344         if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization()) {
1345           nm->mark_for_deoptimization();
1346           marked++;
1347         }
1348         nmethodBucket* next = b->next();
1349         delete b;
1350         b = next;
1351       }
1352       java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context(), NULL); // reset context
1353     }
1354     if (marked > 0) {
1355       // At least one nmethod has been marked for deoptimization
1356       VM_Deoptimize op;
1357       VMThread::execute(&op);
1358     }
1359   }
1360 }
1361 JVM_END
1362 
1363 /**
1364  * Throws a java/lang/UnsupportedOperationException unconditionally.
1365  * This is required by the specification of MethodHandle.invoke if
1366  * invoked directly.
1367  */
1368 JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1369   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
1370   return NULL;
1371 }




  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/stringTable.hpp"
  28 #include "code/codeCache.hpp"
  29 #include "compiler/compileBroker.hpp"
  30 #include "interpreter/interpreter.hpp"
  31 #include "interpreter/oopMapCache.hpp"
  32 #include "interpreter/linkResolver.hpp"
  33 #include "memory/allocation.inline.hpp"
  34 #include "memory/oopFactory.hpp"
  35 #include "oops/objArrayOop.inline.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "prims/methodHandles.hpp"
  38 #include "prims/jvmtiRedefineClassesTrace.hpp"
  39 #include "prims/unsafe.hpp"
  40 #include "runtime/compilationPolicy.hpp"
  41 #include "runtime/javaCalls.hpp"
  42 #include "runtime/reflection.hpp"
  43 #include "runtime/signature.hpp"
  44 #include "runtime/stubRoutines.hpp"
  45 #include "utilities/exceptions.hpp"
  46 
  47 
  48 /*
  49  * JSR 292 reference implementation: method handles
  50  * The JDK 7 reference implementation represented method handle
  51  * combinations as chains.  Each link in the chain had a "vmentry"
  52  * field which pointed at a bit of assembly code which performed
  53  * one transformation before dispatching to the next link in the chain.
  54  *
  55  * The current reference implementation pushes almost all code generation
  56  * responsibility to (trusted) Java code.  A method handle contains a
  57  * pointer to its "LambdaForm", which embodies all details of the method
  58  * handle's behavior.  The LambdaForm is a normal Java object, managed
  59  * by a runtime coded in Java.


1198     } else {
1199       THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed");
1200     }
1201   }
1202 
1203   return JNIHandles::make_local(THREAD, resolved());
1204 }
1205 JVM_END
1206 
1207 static jlong find_member_field_offset(oop mname, bool must_be_static, TRAPS) {
1208   if (mname == NULL ||
1209       java_lang_invoke_MemberName::vmtarget(mname) == NULL) {
1210     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "mname not resolved");
1211   } else {
1212     int flags = java_lang_invoke_MemberName::flags(mname);
1213     if ((flags & IS_FIELD) != 0 &&
1214         (must_be_static
1215          ? (flags & JVM_ACC_STATIC) != 0
1216          : (flags & JVM_ACC_STATIC) == 0)) {
1217       int vmindex = java_lang_invoke_MemberName::vmindex(mname);
1218       bool is_final = (flags & JVM_ACC_FINAL) != 0;
1219       return Unsafe::field_offset_from_byte_offset(vmindex, is_final);
1220     }
1221   }
1222   const char* msg = (must_be_static ? "static field required" : "non-static field required");
1223   THROW_MSG_0(vmSymbols::java_lang_InternalError(), msg);
1224   return 0;
1225 }
1226 
1227 JVM_ENTRY(jlong, MHN_objectFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1228   return find_member_field_offset(JNIHandles::resolve(mname_jh), false, THREAD);
1229 }
1230 JVM_END
1231 
1232 JVM_ENTRY(jlong, MHN_staticFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1233   return find_member_field_offset(JNIHandles::resolve(mname_jh), true, THREAD);
1234 }
1235 JVM_END
1236 
1237 JVM_ENTRY(jobject, MHN_staticFieldBase(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1238   // use the other function to perform sanity checks:
1239   jlong ignore = find_member_field_offset(JNIHandles::resolve(mname_jh), true, CHECK_NULL);


1324   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1325   {
1326     // Walk all nmethods depending on this call site.
1327     MutexLocker mu(Compile_lock, thread);
1328     MethodHandles::flush_dependent_nmethods(call_site, target);
1329     java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
1330   }
1331 }
1332 JVM_END
1333 
1334 JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
1335   Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
1336   {
1337     // Walk all nmethods depending on this call site.
1338     MutexLocker mu1(Compile_lock, thread);
1339 
1340     int marked = 0;
1341     {
1342       MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1343       nmethodBucket* b = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context());
1344       marked = nmethodBucket::release(b);









1345       java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context(), NULL); // reset context
1346     }
1347     if (marked > 0) {
1348       // At least one nmethod has been marked for deoptimization
1349       VM_Deoptimize op;
1350       VMThread::execute(&op);
1351     }
1352   }
1353 }
1354 JVM_END
1355 
1356 /**
1357  * Throws a java/lang/UnsupportedOperationException unconditionally.
1358  * This is required by the specification of MethodHandle.invoke if
1359  * invoked directly.
1360  */
1361 JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1362   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
1363   return NULL;
1364 }


< prev index next >