This repository has been archived by the owner. It is now read-only.
Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
8232081: Try to link all classes during dynamic CDS dump
During CDS dynamic dump, link all classes loaded by the builtin class loaders in JVM_BeforeHalt() and JavaThread::invoke_shutdown_hooks(). Reviewed-by: iklam, dholmes
- Loading branch information
Showing
with
202 additions
and 13 deletions.
- +16 −7 src/hotspot/share/memory/metaspaceShared.cpp
- +0 −6 src/hotspot/share/oops/instanceKlass.hpp
- +4 −0 src/hotspot/share/prims/jvm.cpp
- +7 −0 src/hotspot/share/runtime/thread.cpp
- +93 −0 test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java
- +82 −0 test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LinkClassApp.java
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,93 @@ | ||
/* | ||
* Copyright (c) 2020, 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 | ||
* @summary Classes loaded by the builtin class loaders should be linked | ||
* during dynamic CDS dump time. | ||
* @requires vm.cds | ||
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds | ||
* /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes | ||
* @build LinkClassApp | ||
* @run driver ClassFileInstaller -jar link_class_app.jar LinkClassApp Parent Child Parent2 Child2 MyShutdown | ||
* @run driver LinkClassTest | ||
*/ | ||
|
||
public class LinkClassTest extends DynamicArchiveTestBase { | ||
public static void main(String[] args) throws Exception { | ||
runTest(LinkClassTest::test); | ||
} | ||
|
||
static void test() throws Exception { | ||
String topArchiveName = getNewArchiveName(); | ||
String appJar = ClassFileInstaller.getJarPath("link_class_app.jar"); | ||
String mainClass = "LinkClassApp"; | ||
|
||
// dump archive with the app without calling System.exit(). | ||
dump(topArchiveName, | ||
"-Xlog:class+load,cds+dynamic=info,cds", | ||
"-cp", appJar, mainClass) | ||
.assertNormalExit(output -> { | ||
output.shouldNotContain("Skipping Parent: Not linked") | ||
.shouldNotContain("Skipping Parent2: Not linked") | ||
.shouldNotContain("Skipping Child: Not linked") | ||
.shouldNotContain("Skipping Child2: Not linked") | ||
.shouldHaveExitValue(0); | ||
}); | ||
|
||
run(topArchiveName, | ||
"-Xlog:class+load", | ||
"-cp", appJar, mainClass, "run") | ||
.assertNormalExit(output -> { | ||
output.shouldContain("Parent source: shared objects file (top)") | ||
.shouldContain("Parent2 source: shared objects file (top)") | ||
.shouldContain("Child source: shared objects file (top)") | ||
.shouldContain("Child2 source: shared objects file (top)") | ||
.shouldHaveExitValue(0); | ||
}); | ||
|
||
// dump archive with the app calling System.exit(). | ||
dump(topArchiveName, | ||
"-Xlog:class+load,cds+dynamic=info,cds", | ||
"-cp", appJar, mainClass, "callExit") | ||
.assertNormalExit(output -> { | ||
output.shouldNotContain("Skipping Parent: Not linked") | ||
.shouldNotContain("Skipping Parent2: Not linked") | ||
.shouldNotContain("Skipping Child: Not linked") | ||
.shouldNotContain("Skipping Child2: Not linked") | ||
.shouldHaveExitValue(0); | ||
}); | ||
|
||
run(topArchiveName, | ||
"-Xlog:class+load", | ||
"-cp", appJar, mainClass, "run") | ||
.assertNormalExit(output -> { | ||
output.shouldContain("Parent source: shared objects file (top)") | ||
.shouldContain("Parent2 source: shared objects file (top)") | ||
.shouldContain("Child source: shared objects file (top)") | ||
.shouldContain("Child2 source: shared objects file (top)") | ||
.shouldHaveExitValue(0); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright (c) 2020, 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. | ||
*/ | ||
|
||
class Parent { | ||
int get() {return 1;} | ||
} | ||
|
||
class Child extends Parent { | ||
int get() {return 2;} | ||
int dummy() { | ||
// When Child is linked during dynamic dump (when the VM is shutting | ||
// down), it will be verified, which will recursively cause Child2/Parent2 | ||
// to be loaded and verified. | ||
// We want to make sure that this is done at a point in the VM lifecycle where | ||
// it's still safe to do so. | ||
Parent2 x = new Child2(); | ||
return x.get(); | ||
} | ||
} | ||
|
||
class Parent2 { | ||
int get() {return 3;} | ||
} | ||
|
||
class Child2 extends Parent2 { | ||
int get() {return 4;} | ||
} | ||
|
||
class MyShutdown extends Thread{ | ||
public void run(){ | ||
System.out.println("shut down hook invoked..."); | ||
} | ||
} | ||
|
||
class LinkClassApp { | ||
public static void main(String args[]) { | ||
Runtime r=Runtime.getRuntime(); | ||
r.addShutdownHook(new MyShutdown()); | ||
|
||
if (args.length > 0 && args[0].equals("run")) { | ||
System.out.println("test() = " + test()); | ||
} else { | ||
// Executed during dynamic dumping. | ||
System.out.println("Test.class is initialized."); | ||
System.out.println("Parent.class and Child.class are loaded when Test.class is verified,"); | ||
System.out.println("but these two classes are not linked"); | ||
} | ||
|
||
if (args.length > 0 && args[0].equals("callExit")) { | ||
System.exit(0); | ||
} | ||
} | ||
|
||
static int test() { | ||
// Verification of Test.test() would load Child and Parent, and create a verification constraint that | ||
// Child must be a subtype of Parent. | ||
// | ||
// Child and Parent are not linked until Test.test() is actually executed. | ||
Parent x = new Child(); | ||
return x.get(); | ||
} | ||
} |