< 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 >