8304693: Remove -XX:-UseVtableBasedCHA

Reviewed-by: kvn, coleenp, dholmes
This commit is contained in:
Vladimir Ivanov 2024-06-27 18:25:16 +00:00
parent 9d986a013d
commit 243bae7dc0
11 changed files with 12 additions and 165 deletions

View File

@ -718,17 +718,10 @@ ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller,
{ {
MutexLocker locker(Compile_lock); MutexLocker locker(Compile_lock);
InstanceKlass* context = actual_recv->get_instanceKlass(); InstanceKlass* context = actual_recv->get_instanceKlass();
if (UseVtableBasedCHA) { target = methodHandle(THREAD, Dependencies::find_unique_concrete_method(context,
target = methodHandle(THREAD, Dependencies::find_unique_concrete_method(context, root_m->get_Method(),
root_m->get_Method(), callee_holder->get_Klass(),
callee_holder->get_Klass(), this->get_Method()));
this->get_Method()));
} else {
if (root_m->is_abstract()) {
return nullptr; // not supported
}
target = methodHandle(THREAD, Dependencies::find_unique_concrete_method(context, root_m->get_Method()));
}
assert(target() == nullptr || !target()->is_abstract(), "not allowed"); assert(target() == nullptr || !target()->is_abstract(), "not allowed");
// %%% Should upgrade this ciMethod API to look for 1 or 2 concrete methods. // %%% Should upgrade this ciMethod API to look for 1 or 2 concrete methods.
} }

View File

@ -113,11 +113,7 @@ void Dependencies::assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm)
void Dependencies::assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm, ciKlass* resolved_klass, ciMethod* resolved_method) { void Dependencies::assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm, ciKlass* resolved_klass, ciMethod* resolved_method) {
check_ctxk(ctxk); check_ctxk(ctxk);
check_unique_method(ctxk, uniqm); check_unique_method(ctxk, uniqm);
if (UseVtableBasedCHA) { assert_common_4(unique_concrete_method_4, ctxk, uniqm, resolved_klass, resolved_method);
assert_common_4(unique_concrete_method_4, ctxk, uniqm, resolved_klass, resolved_method);
} else {
assert_common_2(unique_concrete_method_2, ctxk, uniqm);
}
} }
void Dependencies::assert_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk) { void Dependencies::assert_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk) {
@ -1474,7 +1470,6 @@ class LinkedConcreteMethodFinder : public AbstractClassHierarchyWalker {
// Optionally, a method which was previously determined as a unique target (uniqm) is added as a participant // Optionally, a method which was previously determined as a unique target (uniqm) is added as a participant
// to enable dependency spot-checking and speed up the search. // to enable dependency spot-checking and speed up the search.
LinkedConcreteMethodFinder(InstanceKlass* resolved_klass, Method* resolved_method, Method* uniqm = nullptr) : AbstractClassHierarchyWalker(nullptr) { LinkedConcreteMethodFinder(InstanceKlass* resolved_klass, Method* resolved_method, Method* uniqm = nullptr) : AbstractClassHierarchyWalker(nullptr) {
assert(UseVtableBasedCHA, "required");
assert(resolved_klass->is_linked(), "required"); assert(resolved_klass->is_linked(), "required");
assert(resolved_method->method_holder()->is_linked(), "required"); assert(resolved_method->method_holder()->is_linked(), "required");
assert(!resolved_method->can_be_statically_bound(), "no vtable index available"); assert(!resolved_method->can_be_statically_bound(), "no vtable index available");
@ -1948,7 +1943,6 @@ Klass* Dependencies::check_unique_concrete_method(InstanceKlass* ctxk,
Klass* resolved_klass, Klass* resolved_klass,
Method* resolved_method, Method* resolved_method,
KlassDepChange* changes) { KlassDepChange* changes) {
assert(UseVtableBasedCHA, "required");
assert(!ctxk->is_interface() || ctxk == resolved_klass, "sanity"); assert(!ctxk->is_interface() || ctxk == resolved_klass, "sanity");
assert(!resolved_method->can_be_statically_bound() || resolved_method == uniqm, "sanity"); assert(!resolved_method->can_be_statically_bound() || resolved_method == uniqm, "sanity");
assert(resolved_klass->is_subtype_of(resolved_method->method_holder()), "sanity"); assert(resolved_klass->is_subtype_of(resolved_method->method_holder()), "sanity");
@ -2129,7 +2123,7 @@ Klass* Dependencies::DepStream::check_klass_dependency(KlassDepChange* changes)
Dependencies::check_valid_dependency_type(type()); Dependencies::check_valid_dependency_type(type());
if (changes != nullptr) { if (changes != nullptr) {
if (UseVtableBasedCHA && changes->is_klass_init_change()) { if (changes->is_klass_init_change()) {
return check_klass_init_dependency(changes->as_klass_init_change()); return check_klass_init_dependency(changes->as_klass_init_change());
} else { } else {
return check_new_klass_dependency(changes->as_new_klass_change()); return check_new_klass_dependency(changes->as_new_klass_change());

View File

@ -929,7 +929,7 @@ bool InstanceKlass::link_class_impl(TRAPS) {
// In case itable verification is ever added. // In case itable verification is ever added.
// itable().verify(tty, true); // itable().verify(tty, true);
#endif #endif
if (UseVtableBasedCHA && Universe::is_fully_initialized()) { if (Universe::is_fully_initialized()) {
DeoptimizationScope deopt_scope; DeoptimizationScope deopt_scope;
{ {
// Now mark all code that assumes the class is not linked. // Now mark all code that assumes the class is not linked.
@ -1264,7 +1264,7 @@ void InstanceKlass::set_initialization_state_and_notify(ClassState state, TRAPS)
// Update hierarchy. This is done before the new klass has been added to the SystemDictionary. The Compile_lock // Update hierarchy. This is done before the new klass has been added to the SystemDictionary. The Compile_lock
// is grabbed, to ensure that the compiler is not using the class hierarchy. // is grabbed, to ensure that the compiler is not using the class hierarchy.
void InstanceKlass::add_to_hierarchy_impl(JavaThread* current) { void InstanceKlass::add_to_hierarchy(JavaThread* current) {
assert(!SafepointSynchronize::is_at_safepoint(), "must NOT be at safepoint"); assert(!SafepointSynchronize::is_at_safepoint(), "must NOT be at safepoint");
DeoptimizationScope deopt_scope; DeoptimizationScope deopt_scope;
@ -1290,23 +1290,6 @@ void InstanceKlass::add_to_hierarchy_impl(JavaThread* current) {
deopt_scope.deoptimize_marked(); deopt_scope.deoptimize_marked();
} }
void InstanceKlass::add_to_hierarchy(JavaThread* current) {
if (UseVtableBasedCHA || !Universe::is_fully_initialized()) {
add_to_hierarchy_impl(current);
} else {
// In case we are not using CHA based vtables we need to make sure the loaded
// deopt is completed before anyone links this class.
// Linking is done with init_lock held, by loading and deopting with it
// held we make sure the deopt is completed before linking.
Handle h_init_lock(current, init_lock());
ObjectLocker ol(h_init_lock, current);
add_to_hierarchy_impl(current);
// This doesn't need a notify because the wait is only on the class initialization path.
}
}
InstanceKlass* InstanceKlass::implementor() const { InstanceKlass* InstanceKlass::implementor() const {
InstanceKlass* volatile* ik = adr_implementor(); InstanceKlass* volatile* ik = adr_implementor();

View File

@ -828,9 +828,6 @@ public:
void set_jni_ids(JNIid* ids) { _jni_ids = ids; } void set_jni_ids(JNIid* ids) { _jni_ids = ids; }
JNIid* jni_id_for(int offset); JNIid* jni_id_for(int offset);
private:
void add_to_hierarchy_impl(JavaThread* current);
public: public:
// maintenance of deoptimization dependencies // maintenance of deoptimization dependencies
inline DependencyContext dependencies(); inline DependencyContext dependencies();

View File

@ -522,6 +522,7 @@ static SpecialFlag const special_jvm_flags[] = {
#endif // X86 #endif // X86
{ "HeapFirstMaximumCompactionCount", JDK_Version::undefined(), JDK_Version::jdk(24), JDK_Version::jdk(25) }, { "HeapFirstMaximumCompactionCount", JDK_Version::undefined(), JDK_Version::jdk(24), JDK_Version::jdk(25) },
{ "UseVtableBasedCHA", JDK_Version::undefined(), JDK_Version::jdk(24), JDK_Version::jdk(25) },
#ifdef ASSERT #ifdef ASSERT
{ "DummyObsoleteTestFlag", JDK_Version::undefined(), JDK_Version::jdk(18), JDK_Version::undefined() }, { "DummyObsoleteTestFlag", JDK_Version::undefined(), JDK_Version::jdk(18), JDK_Version::undefined() },
#endif #endif

View File

@ -968,9 +968,6 @@ const int ObjectAlignmentInBytes = 8;
develop(bool, UseCHA, true, \ develop(bool, UseCHA, true, \
"Enable CHA") \ "Enable CHA") \
\ \
product(bool, UseVtableBasedCHA, true, DIAGNOSTIC, \
"Use vtable information during CHA") \
\
product(bool, UseTypeProfile, true, \ product(bool, UseTypeProfile, true, \
"Check interpreter profile for historically monomorphic calls") \ "Check interpreter profile for historically monomorphic calls") \
\ \

View File

@ -23,7 +23,7 @@
/* /*
* @test * @test
* @requires !vm.graal.enabled & vm.opt.final.UseVtableBasedCHA == true * @requires !vm.graal.enabled
* @modules java.base/jdk.internal.org.objectweb.asm * @modules java.base/jdk.internal.org.objectweb.asm
* java.base/jdk.internal.misc * java.base/jdk.internal.misc
* java.base/jdk.internal.vm.annotation * java.base/jdk.internal.vm.annotation

View File

@ -23,7 +23,7 @@
/* /*
* @test * @test
* @requires !vm.graal.enabled & vm.opt.final.UseVtableBasedCHA == true * @requires !vm.graal.enabled
* @modules java.base/jdk.internal.org.objectweb.asm * @modules java.base/jdk.internal.org.objectweb.asm
* java.base/jdk.internal.misc * java.base/jdk.internal.misc
* java.base/jdk.internal.vm.annotation * java.base/jdk.internal.vm.annotation

View File

@ -23,7 +23,7 @@
/* /*
* @test * @test
* @requires !vm.graal.enabled & vm.opt.final.UseVtableBasedCHA == true * @requires !vm.graal.enabled
* @modules java.base/jdk.internal.org.objectweb.asm * @modules java.base/jdk.internal.org.objectweb.asm
* java.base/jdk.internal.misc * java.base/jdk.internal.misc
* java.base/jdk.internal.vm.annotation * java.base/jdk.internal.vm.annotation

View File

@ -1,117 +0,0 @@
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
* @test id=special
* @summary Run invocation tests with old CHA (-XX:-UseVtableBasedCHA)
* @requires vm.flagless
* @library /test/lib
* @modules java.base/jdk.internal.org.objectweb.asm
* java.base/jdk.internal.misc
* @compile invokespecial/Checker.java invokespecial/ClassGenerator.java invokespecial/Generator.java
*
* @run driver/timeout=1800 invocationOldCHATests special
*/
/*
* @test id=virtual
* @summary Run invocation tests with old CHA (-XX:-UseVtableBasedCHA)
* @requires vm.flagless
* @library /test/lib
* @modules java.base/jdk.internal.org.objectweb.asm
* java.base/jdk.internal.misc
* @compile invokevirtual/Checker.java invokevirtual/ClassGenerator.java invokevirtual/Generator.java
*
* @run driver/timeout=1800 invocationOldCHATests virtual
*/
/*
* @test id=interface
* @summary Run invocation tests with old CHA (-XX:-UseVtableBasedCHA)
* @requires vm.flagless
* @library /test/lib
* @modules java.base/jdk.internal.org.objectweb.asm
* java.base/jdk.internal.misc
* @compile invokeinterface/Checker.java invokeinterface/ClassGenerator.java invokeinterface/Generator.java
*
* @run driver/timeout=1800 invocationOldCHATests interface
*/
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.compiler.InMemoryJavaCompiler;
public class invocationOldCHATests {
public static void runTest(String whichTests, String classFileVersion) throws Throwable {
System.out.println("\nOld CHA invocation tests, Tests: " + whichTests +
", class file version: " + classFileVersion);
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xmx128M",
"-Xcomp", "-XX:+UnlockDiagnosticVMOptions", "-XX:-UseVtableBasedCHA",
"--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED",
whichTests, "--classfile_version=" + classFileVersion);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
try {
output.shouldContain("EXECUTION STATUS: PASSED");
output.shouldHaveExitValue(0);
} catch (Throwable e) {
System.out.println(
"\nNote that an entry such as 'B.m/C.m' in the failure chart means that" +
" the test case failed because method B.m was invoked but the test " +
"expected method C.m to be invoked. Similarly, a result such as 'AME/C.m'" +
" means that an AbstractMethodError exception was thrown but the test" +
" case expected method C.m to be invoked.");
System.out.println(
"\nAlso note that passing --dump to invoke*.Generator will" +
" dump the generated classes (for debugging purposes).\n");
throw e;
}
}
public static void main(String args[]) throws Throwable {
if (args.length < 1) {
throw new IllegalArgumentException("Should provide the test name");
}
String testName = args[0];
// Get current major class file version and test with it.
byte klassbuf[] = InMemoryJavaCompiler.compile("blah", "public class blah { }");
int major_version = klassbuf[6] << 8 | klassbuf[7];
switch (testName) {
case "special":
runTest("invokespecial.Generator", String.valueOf(major_version));
break;
case "virtual":
runTest("invokevirtual.Generator", String.valueOf(major_version));
break;
case "interface":
runTest("invokeinterface.Generator", String.valueOf(major_version));
break;
default:
throw new IllegalArgumentException("Unknown test name: " + testName);
}
}
}

View File

@ -386,7 +386,6 @@ public class VMProps implements Callable<Map<String, String>> {
vmOptFinalFlag(map, "EliminateAllocations"); vmOptFinalFlag(map, "EliminateAllocations");
vmOptFinalFlag(map, "UseCompressedOops"); vmOptFinalFlag(map, "UseCompressedOops");
vmOptFinalFlag(map, "UseVectorizedMismatchIntrinsic"); vmOptFinalFlag(map, "UseVectorizedMismatchIntrinsic");
vmOptFinalFlag(map, "UseVtableBasedCHA");
vmOptFinalFlag(map, "ZGenerational"); vmOptFinalFlag(map, "ZGenerational");
} }