< prev index next >
src/share/vm/prims/methodHandles.cpp
Print this page
*** 938,963 ****
// 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) {
! // In order to extract a context the following traversal is performed:
! // CallSite.context => Cleaner.referent => Class._klass => Klass
! 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.
! }
! oop context_class_oop = java_lang_ref_Reference::referent(context_oop);
! if (oopDesc::is_null(context_class_oop)) {
! // The context reference was cleared by GC, so current dependency context
! // 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
//
--- 938,997 ----
// return number of elements we at leasted wanted to initialize
return rfill + overflow;
}
! void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) {
! assert_locked_or_safepoint(CodeCache_lock);
!
! oop context = java_lang_invoke_CallSite::context(call_site);
! nmethodBucket* deps = java_lang_invoke_CallSite_Context::dependencies(context);
!
! nmethodBucket* new_deps = nmethodBucket::add_dependent_nmethod(deps, nm);
! if (deps != new_deps) {
! java_lang_invoke_CallSite_Context::set_dependencies(context, new_deps);
! }
! }
!
! void MethodHandles::remove_dependent_nmethod(oop call_site, nmethod* nm) {
! assert_locked_or_safepoint(CodeCache_lock);
!
! oop context = java_lang_invoke_CallSite::context(call_site);
! nmethodBucket* deps = java_lang_invoke_CallSite_Context::dependencies(context);
!
! if (nmethodBucket::remove_dependent_nmethod(deps, nm)) {
! nmethodBucket* new_deps = nmethodBucket::clean_dependent_nmethods(deps);
! if (deps != new_deps) {
! java_lang_invoke_CallSite_Context::set_dependencies(context, new_deps);
! }
! }
! }
!
! void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) {
! assert_lock_strong(Compile_lock);
!
! int marked = 0;
! CallSiteDepChange changes(call_site(), target());
! {
! MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
!
! oop context = java_lang_invoke_CallSite::context(call_site());
! nmethodBucket* deps = java_lang_invoke_CallSite_Context::dependencies(context);
!
! marked = nmethodBucket::mark_dependent_nmethods(deps, changes);
! if (marked > 0) {
! nmethodBucket* new_deps = nmethodBucket::clean_dependent_nmethods(deps);
! if (deps != new_deps) {
! java_lang_invoke_CallSite_Context::set_dependencies(context, new_deps);
! }
! }
! }
! if (marked > 0) {
! // At least one nmethod has been marked for deoptimization
! VM_Deoptimize op;
! VMThread::execute(&op);
}
}
//------------------------------------------------------------------------------
// MemberNameTable
//
*** 1272,1282 ****
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());
}
}
JVM_END
--- 1306,1316 ----
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);
! MethodHandles::flush_dependent_nmethods(call_site, target);
java_lang_invoke_CallSite::set_target(call_site(), target());
}
}
JVM_END
*** 1284,1317 ****
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);
}
--- 1318,1355 ----
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);
! MethodHandles::flush_dependent_nmethods(call_site, target);
java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
}
}
JVM_END
! JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
! Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
{
// Walk all nmethods depending on this call site.
MutexLocker mu1(Compile_lock, thread);
int marked = 0;
{
MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
! nmethodBucket* b = java_lang_invoke_CallSite_Context::dependencies(context());
! while(b != NULL) {
! nmethod* nm = b->get_nmethod();
! if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization()) {
! nm->mark_for_deoptimization();
! marked++;
! }
! nmethodBucket* next = b->next();
! delete b;
! b = next;
! }
! java_lang_invoke_CallSite_Context::set_dependencies(context(), NULL); // reset context
}
if (marked > 0) {
// At least one nmethod has been marked for deoptimization
VM_Deoptimize op;
VMThread::execute(&op);
}
*** 1350,1359 ****
--- 1388,1398 ----
#define OBJ LANG"Object;"
#define CLS LANG"Class;"
#define STRG LANG"String;"
#define CS JLINV"CallSite;"
+ #define CTX JLINV"CallSite$Context;"
#define MT JLINV"MethodType;"
#define MH JLINV"MethodHandle;"
#define MEM JLINV"MemberName;"
#define CC (char*) /*cast a literal from (const char*)*/
*** 1370,1380 ****
// 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)}
};
--- 1409,1419 ----
// 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"clearCallSiteContext", CC"("CTX")V", FN_PTR(MHN_clearCallSiteContext)},
{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 >