1 /*
  2  * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 /**
 26  * @test
 27  * @comment the test uses -XX:ArchiveRelocationMode=1 to force relocation.
 28  * @requires vm.cds
 29  * @summary Testing relocation of dynamic CDS archive (during both dump time and run time)
 30  * @comment JDK-8231610 Relocate the CDS archive if it cannot be mapped to the requested address
 31  * @bug 8231610
 32  * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes
 33  * @enablePreview
 34  * @modules java.base/jdk.internal.value
 35  *          java.base/jdk.internal.vm.annotation
 36  * @compile ../test-classes/HelloInlineClassApp.java ../test-classes/HelloRelocation.java
 37  * @build jdk.test.whitebox.WhiteBox
 38  * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar HelloRelocation HelloInlineClassApp HelloInlineClassApp$Point HelloInlineClassApp$Rectangle  HelloInlineClassApp$ValueRecord
 39  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 40  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. DynamicArchiveRelocationTest
 41  */
 42 
 43 import jdk.test.lib.process.OutputAnalyzer;
 44 import jdk.test.lib.helpers.ClassFileInstaller;
 45 import jtreg.SkippedException;
 46 
 47 public class DynamicArchiveRelocationTest extends DynamicArchiveTestBase {
 48     public static void main(String... args) throws Exception {
 49         try {
 50             testOuter();
 51         } catch (SkippedException s) {
 52             s.printStackTrace();
 53             throw new RuntimeException("Archive mapping should always succeed after JDK-8231610 (did the machine run out of memory?)");
 54         }
 55     }
 56 
 57     static void testOuter() throws Exception {
 58         testInner(true,  false);
 59         testInner(false, true);
 60         testInner(true,  true);
 61     }
 62 
 63     static boolean dump_top_reloc, run_reloc;
 64 
 65     // dump_top_reloc  - force relocation of archive when dumping top  archive
 66     // run_reloc       - force relocation of archive when running
 67     static void testInner(boolean dump_top_reloc, boolean run_reloc) throws Exception {
 68         DynamicArchiveRelocationTest.dump_top_reloc  = dump_top_reloc;
 69         DynamicArchiveRelocationTest.run_reloc       = run_reloc;
 70 
 71         runTest(DynamicArchiveRelocationTest::doTest);
 72     }
 73 
 74     static int caseCount = 0;
 75     static void doTest() throws Exception {
 76         caseCount += 1;
 77         System.out.println("============================================================");
 78         System.out.println("case = " + caseCount
 79                            + ", top_reloc = " + dump_top_reloc
 80                            + ", run = " + run_reloc);
 81         System.out.println("============================================================");
 82 
 83         String appJar = ClassFileInstaller.getJarPath("hello.jar");
 84         String mainClass = "HelloRelocation";
 85         String forceRelocation = "-XX:ArchiveRelocationMode=1";
 86         String dumpTopRelocArg  = dump_top_reloc  ? forceRelocation : "-showversion";
 87         String runRelocArg      = run_reloc       ? forceRelocation : "-showversion";
 88         String logArg = "-Xlog:cds=debug,cds+reloc=debug";
 89 
 90         String baseArchiveName = getNewArchiveName("base");
 91         String topArchiveName  = getNewArchiveName("top");
 92 
 93         String runtimeMsg = "Try to map archive(s) at an alternative address";
 94         String unlockArg = "-XX:+UnlockDiagnosticVMOptions";
 95 
 96         // (1) Dump base archive (static)
 97 
 98         TestCommon.dumpBaseArchive(baseArchiveName, "--enable-preview", unlockArg, logArg)
 99           .shouldContain("Relocating archive from");
100 
101         // (2) Dump top archive (dynamic)
102 
103         dump2(baseArchiveName, topArchiveName,
104               "--enable-preview",
105               unlockArg,
106               dumpTopRelocArg,
107               logArg,
108               "-cp", appJar, mainClass)
109             .assertNormalExit(output -> {
110                     if (dump_top_reloc) {
111                         output.shouldContain(runtimeMsg);
112                     }
113                 });
114 
115         run2(baseArchiveName, topArchiveName,
116              "--enable-preview",
117              unlockArg,
118              runRelocArg,
119              logArg,
120             "-cp", appJar, mainClass)
121             .assertNormalExit(output -> {
122                     if (run_reloc) {
123                         output.shouldContain(runtimeMsg);
124                     }
125                 });
126     }
127 }