< prev index next >
src/share/vm/prims/methodHandles.cpp
Print this page
*** 937,946 ****
--- 937,975 ----
// return number of elements we at leasted wanted to initialize
return rfill + overflow;
}
+ // Get context class for a CallSite instance: either extract existing context or use default one.
+ InstanceKlass* MethodHandles::get_call_site_context(oop call_site) {
+ assert_locked_or_safepoint(Compile_lock);
+ assert(java_lang_invoke_CallSite::is_instance(call_site), "");
+ oop context_oop = java_lang_invoke_CallSite::context_volatile(call_site);
+ if (oopDesc::is_null(context_oop)) {
+ return NULL; // The context hasn't been initialized yet.
+ }
+ if (java_lang_invoke_DependencyContext::is_default_context(context_oop)) {
+ // Extract context klass from call site target when default context is used.
+ oop mh = java_lang_invoke_CallSite::target(call_site);
+ oop lform = java_lang_invoke_MethodHandle::form(mh);
+ oop mname = java_lang_invoke_LambdaForm::vmentry(lform);
+ oop clazz = java_lang_invoke_MemberName::clazz(mname);
+ return InstanceKlass::cast(java_lang_Class::as_Klass(clazz));
+ } else {
+ // In order to extract a context the following traversal is performed:
+ // DependencyContext.cleaner => Cleaner.referent => Class._klass => Klass
+ oop cleaner_oop = java_lang_invoke_DependencyContext::cleaner(context_oop);
+ oop context_class_oop = java_lang_ref_Reference::referent(cleaner_oop);
+ if (oopDesc::is_null(context_class_oop)) {
+ // The context reference was cleared by GC, so current DependencyContext instance
+ // isn't usable anymore. Context should be fetched from CallSite again.
+ return NULL;
+ }
+ return InstanceKlass::cast(java_lang_Class::as_Klass(context_class_oop));
+ }
+ }
+
//------------------------------------------------------------------------------
// MemberNameTable
//
MemberNameTable::MemberNameTable(int methods_cnt)
*** 1244,1254 ****
}
JVM_END
JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
! Handle target (THREAD, JNIHandles::resolve(target_jh));
{
// Walk all nmethods depending on this call site.
MutexLocker mu(Compile_lock, thread);
CodeCache::flush_dependents_on(call_site, target);
java_lang_invoke_CallSite::set_target(call_site(), target());
--- 1273,1283 ----
}
JVM_END
JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
! Handle target (THREAD, JNIHandles::resolve_non_null(target_jh));
{
// Walk all nmethods depending on this call site.
MutexLocker mu(Compile_lock, thread);
CodeCache::flush_dependents_on(call_site, target);
java_lang_invoke_CallSite::set_target(call_site(), target());
*** 1256,1275 ****
}
JVM_END
JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
! Handle target (THREAD, JNIHandles::resolve(target_jh));
{
// Walk all nmethods depending on this call site.
MutexLocker mu(Compile_lock, thread);
CodeCache::flush_dependents_on(call_site, target);
java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
}
}
JVM_END
/**
* Throws a java/lang/UnsupportedOperationException unconditionally.
* This is required by the specification of MethodHandle.invoke if
* invoked directly.
*/
--- 1285,1331 ----
}
JVM_END
JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
! Handle target (THREAD, JNIHandles::resolve_non_null(target_jh));
{
// Walk all nmethods depending on this call site.
MutexLocker mu(Compile_lock, thread);
CodeCache::flush_dependents_on(call_site, target);
java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
}
}
JVM_END
+ JVM_ENTRY(void, MHN_invalidateDependentNMethods(JNIEnv* env, jobject igcls, jobject call_site_jh)) {
+ Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
+ {
+ // Walk all nmethods depending on this call site.
+ MutexLocker mu1(Compile_lock, thread);
+
+ CallSiteDepChange changes(call_site(), Handle());
+
+ InstanceKlass* ctxk = MethodHandles::get_call_site_context(call_site());
+ if (ctxk == NULL) {
+ return; // No dependencies to invalidate yet.
+ }
+ int marked = 0;
+ {
+ MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ marked = ctxk->mark_dependent_nmethods(changes);
+ }
+ java_lang_invoke_CallSite::set_context_volatile(call_site(), NULL); // Reset call site to initial state
+ if (marked > 0) {
+ // At least one nmethod has been marked for deoptimization
+ VM_Deoptimize op;
+ VMThread::execute(&op);
+ }
+ }
+ }
+ JVM_END
+
/**
* Throws a java/lang/UnsupportedOperationException unconditionally.
* This is required by the specification of MethodHandle.invoke if
* invoked directly.
*/
*** 1320,1329 ****
--- 1376,1386 ----
// int matchFlags, Class<?> caller, int skip, MemberName[] results);
{CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)},
{CC"objectFieldOffset", CC"("MEM")J", FN_PTR(MHN_objectFieldOffset)},
{CC"setCallSiteTargetNormal", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetNormal)},
{CC"setCallSiteTargetVolatile", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetVolatile)},
+ {CC"invalidateDependentNMethods", CC"("CS")V", FN_PTR(MHN_invalidateDependentNMethods)},
{CC"staticFieldOffset", CC"("MEM")J", FN_PTR(MHN_staticFieldOffset)},
{CC"staticFieldBase", CC"("MEM")"OBJ, FN_PTR(MHN_staticFieldBase)},
{CC"getMemberVMInfo", CC"("MEM")"OBJ, FN_PTR(MHN_getMemberVMInfo)}
};
< prev index next >