Skip to content

Commit 928fa5b

Browse files
committed
8244540: Print more information with -XX:+PrintSharedArchiveAndExit
Reviewed-by: iklam, ccheung
1 parent e073486 commit 928fa5b

8 files changed

Lines changed: 294 additions & 11 deletions

File tree

src/hotspot/share/classfile/symbolTable.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,13 @@ void SymbolTable::symbols_do(SymbolClosure *cl) {
275275
_local_table->do_safepoint_scan(sd);
276276
}
277277

278+
// Call function for all symbols in shared table. Used by -XX:+PrintSharedArchiveAndExit
279+
void SymbolTable::shared_symbols_do(SymbolClosure *cl) {
280+
SharedSymbolIterator iter(cl);
281+
_shared_table.iterate(&iter);
282+
_dynamic_shared_table.iterate(&iter);
283+
}
284+
278285
Symbol* SymbolTable::lookup_dynamic(const char* name,
279286
int len, unsigned int hash) {
280287
Symbol* sym = do_lookup(name, len, hash);

src/hotspot/share/classfile/symbolTable.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -207,6 +207,7 @@ class SymbolTable : public AllStatic {
207207
static void symbols_do(SymbolClosure *cl);
208208

209209
// Sharing
210+
static void shared_symbols_do(SymbolClosure *cl); // no safepoint iteration.
210211
private:
211212
static void copy_shared_symbol_table(GrowableArray<Symbol*>* symbols,
212213
CompactHashtableWriter* ch_table);

src/hotspot/share/classfile/systemDictionaryShared.cpp

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,6 +2224,24 @@ void SystemDictionaryShared::update_shared_entry(InstanceKlass* k, int id) {
22242224
info->_id = id;
22252225
}
22262226

2227+
const char* class_loader_name_for_shared(Klass* k) {
2228+
assert(k != nullptr, "Sanity");
2229+
assert(k->is_shared(), "Must be");
2230+
assert(k->is_instance_klass(), "Must be");
2231+
InstanceKlass* ik = InstanceKlass::cast(k);
2232+
if (ik->is_shared_boot_class()) {
2233+
return "boot_loader";
2234+
} else if (ik->is_shared_platform_class()) {
2235+
return "platform_loader";
2236+
} else if (ik->is_shared_app_class()) {
2237+
return "app_loader";
2238+
} else if (ik->is_shared_unregistered_class()) {
2239+
return "unregistered_loader";
2240+
} else {
2241+
return "unknown loader";
2242+
}
2243+
}
2244+
22272245
class SharedDictionaryPrinter : StackObj {
22282246
outputStream* _st;
22292247
int _index;
@@ -2232,23 +2250,25 @@ class SharedDictionaryPrinter : StackObj {
22322250

22332251
void do_value(const RunTimeSharedClassInfo* record) {
22342252
ResourceMark rm;
2235-
_st->print_cr("%4d: %s", (_index++), record->_klass->external_name());
2253+
_st->print_cr("%4d: %s %s", (_index++), record->_klass->external_name(),
2254+
class_loader_name_for_shared(record->_klass));
22362255
}
2256+
int index() const { return _index; }
22372257
};
22382258

22392259
class SharedLambdaDictionaryPrinter : StackObj {
22402260
outputStream* _st;
22412261
int _index;
22422262
public:
2243-
SharedLambdaDictionaryPrinter(outputStream* st) : _st(st), _index(0) {}
2263+
SharedLambdaDictionaryPrinter(outputStream* st, int idx) : _st(st), _index(idx) {}
22442264

22452265
void do_value(const RunTimeLambdaProxyClassInfo* record) {
22462266
if (record->proxy_klass_head()->lambda_proxy_is_available()) {
22472267
ResourceMark rm;
2248-
_st->print_cr("%4d: %s", (_index++), record->proxy_klass_head()->external_name());
2249-
Klass* k = record->proxy_klass_head()->next_link();
2250-
while (k != NULL) {
2251-
_st->print_cr("%4d: %s", (_index++), k->external_name());
2268+
Klass* k = record->proxy_klass_head();
2269+
while (k != nullptr) {
2270+
_st->print_cr("%4d: %s %s", (++_index), k->external_name(),
2271+
class_loader_name_for_shared(k));
22522272
k = k->next_link();
22532273
}
22542274
}
@@ -2262,15 +2282,30 @@ void SystemDictionaryShared::print_on(const char* prefix,
22622282
outputStream* st) {
22632283
st->print_cr("%sShared Dictionary", prefix);
22642284
SharedDictionaryPrinter p(st);
2285+
st->print_cr("%sShared Builtin Dictionary", prefix);
22652286
builtin_dictionary->iterate(&p);
2287+
st->print_cr("%sShared Unregistered Dictionary", prefix);
22662288
unregistered_dictionary->iterate(&p);
22672289
if (!lambda_dictionary->empty()) {
22682290
st->print_cr("%sShared Lambda Dictionary", prefix);
2269-
SharedLambdaDictionaryPrinter ldp(st);
2291+
SharedLambdaDictionaryPrinter ldp(st, p.index());
22702292
lambda_dictionary->iterate(&ldp);
22712293
}
22722294
}
22732295

2296+
void SystemDictionaryShared::print_shared_archive(outputStream* st, bool is_static) {
2297+
if (UseSharedSpaces) {
2298+
if (is_static) {
2299+
print_on("", &_builtin_dictionary, &_unregistered_dictionary, &_lambda_proxy_class_dictionary, st);
2300+
} else {
2301+
if (DynamicArchive::is_mapped()) {
2302+
print_on("", &_dynamic_builtin_dictionary, &_dynamic_unregistered_dictionary,
2303+
&_dynamic_lambda_proxy_class_dictionary, st);
2304+
}
2305+
}
2306+
}
2307+
}
2308+
22742309
void SystemDictionaryShared::print_on(outputStream* st) {
22752310
if (UseSharedSpaces) {
22762311
print_on("", &_builtin_dictionary, &_unregistered_dictionary, &_lambda_proxy_class_dictionary, st);

src/hotspot/share/classfile/systemDictionaryShared.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ class SystemDictionaryShared: public SystemDictionary {
316316
static void serialize_vm_classes(class SerializeClosure* soc);
317317
static void print() { return print_on(tty); }
318318
static void print_on(outputStream* st) NOT_CDS_RETURN;
319+
static void print_shared_archive(outputStream* st, bool is_static = true) NOT_CDS_RETURN;
319320
static void print_table_statistics(outputStream* st) NOT_CDS_RETURN;
320321
static bool empty_dumptime_table() NOT_CDS_RETURN_(true);
321322
static void start_dumping() NOT_CDS_RETURN;

src/hotspot/share/memory/filemap.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,10 @@ class FileMapInfo : public CHeapObj<mtInternal> {
544544
header()->print(st);
545545
}
546546

547+
const char* vm_version() {
548+
return header()->jvm_ident();
549+
}
550+
547551
private:
548552
void seek_to_position(size_t pos);
549553
char* skip_first_path_entry(const char* path) NOT_CDS_RETURN_(NULL);

src/hotspot/share/memory/metaspaceShared.cpp

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,34 @@ void MetaspaceShared::unmap_archive(FileMapInfo* mapinfo) {
13281328
}
13291329
}
13301330

1331+
// For -XX:PrintSharedArchiveAndExit
1332+
class CountSharedSymbols : public SymbolClosure {
1333+
private:
1334+
int _count;
1335+
public:
1336+
CountSharedSymbols() : _count(0) {}
1337+
void do_symbol(Symbol** sym) {
1338+
_count++;
1339+
}
1340+
int total() { return _count; }
1341+
1342+
};
1343+
1344+
// For -XX:PrintSharedArchiveAndExit
1345+
class CountSharedStrings : public OopClosure {
1346+
private:
1347+
int _count;
1348+
public:
1349+
CountSharedStrings() : _count(0) {}
1350+
void do_oop(oop* p) {
1351+
_count++;
1352+
}
1353+
void do_oop(narrowOop* p) {
1354+
_count++;
1355+
}
1356+
int total() { return _count; }
1357+
};
1358+
13311359
// Read the miscellaneous data from the shared file, and
13321360
// serialize it out to its various destinations.
13331361

@@ -1362,10 +1390,30 @@ void MetaspaceShared::initialize_shared_spaces() {
13621390
}
13631391

13641392
if (PrintSharedArchiveAndExit) {
1365-
if (PrintSharedDictionary) {
1366-
tty->print_cr("\nShared classes:\n");
1367-
SystemDictionaryShared::print_on(tty);
1393+
// Print archive names
1394+
if (dynamic_mapinfo != nullptr) {
1395+
tty->print_cr("\n\nBase archive name: %s", Arguments::GetSharedArchivePath());
1396+
tty->print_cr("Base archive version %d", static_mapinfo->version());
1397+
} else {
1398+
tty->print_cr("Static archive name: %s", static_mapinfo->full_path());
1399+
tty->print_cr("Static archive version %d", static_mapinfo->version());
13681400
}
1401+
1402+
SystemDictionaryShared::print_shared_archive(tty);
1403+
if (dynamic_mapinfo != nullptr) {
1404+
tty->print_cr("\n\nDynamic archive name: %s", dynamic_mapinfo->full_path());
1405+
tty->print_cr("Dynamic archive version %d", dynamic_mapinfo->version());
1406+
SystemDictionaryShared::print_shared_archive(tty, false/*dynamic*/);
1407+
}
1408+
1409+
// collect shared symbols and strings
1410+
CountSharedSymbols cl;
1411+
SymbolTable::shared_symbols_do(&cl);
1412+
tty->print_cr("Number of shared symbols: %d", cl.total());
1413+
CountSharedStrings cs;
1414+
StringTable::shared_oops_do(&cs);
1415+
tty->print_cr("Number of shared strings: %d", cs.total());
1416+
tty->print_cr("VM version: %s\r\n", static_mapinfo->vm_version());
13691417
if (FileMapInfo::current_info() == NULL || _archive_loading_failed) {
13701418
tty->print_cr("archive is invalid");
13711419
vm_exit(1);
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (c) 2021, 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+
* @summary test -XX:+PrintSharedArchiveAndExit output for shared class.
28+
* @comment the code is mostly copied from HelloCustom
29+
* @requires vm.cds
30+
* @requires vm.cds.custom.loaders
31+
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
32+
* @compile test-classes/HelloUnload.java test-classes/CustomLoadee.java
33+
* @build sun.hotspot.WhiteBox jdk.test.lib.classloader.ClassUnloadCommon
34+
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar HelloUnload
35+
* jdk.test.lib.classloader.ClassUnloadCommon
36+
* jdk.test.lib.classloader.ClassUnloadCommon$1
37+
* jdk.test.lib.classloader.ClassUnloadCommon$TestFailure
38+
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello_custom.jar CustomLoadee
39+
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
40+
* @run driver PrintSharedArchiveAndExit
41+
*/
42+
43+
import jdk.test.lib.process.OutputAnalyzer;
44+
import jdk.test.lib.helpers.ClassFileInstaller;
45+
import sun.hotspot.WhiteBox;
46+
47+
public class PrintSharedArchiveAndExit {
48+
public static void main(String[] args) throws Exception {
49+
run();
50+
}
51+
public static void run(String... extra_runtime_args) throws Exception {
52+
String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
53+
String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
54+
55+
String appJar = ClassFileInstaller.getJarPath("hello.jar");
56+
String customJarPath = ClassFileInstaller.getJarPath("hello_custom.jar");
57+
58+
// Dump the archive
59+
String classlist[] = new String[] {
60+
"HelloUnload",
61+
"java/lang/Object id: 1",
62+
"CustomLoadee id: 2 super: 1 source: " + customJarPath
63+
};
64+
65+
OutputAnalyzer output;
66+
TestCommon.testDump(appJar, classlist,
67+
// command-line arguments ...
68+
use_whitebox_jar);
69+
70+
output = TestCommon.exec(appJar,
71+
TestCommon.concat(extra_runtime_args,
72+
// command-line arguments ...
73+
use_whitebox_jar,
74+
"-XX:+UnlockDiagnosticVMOptions",
75+
"-XX:+WhiteBoxAPI",
76+
"-XX:+PrintSharedArchiveAndExit",
77+
"HelloUnload", customJarPath, "true", "true"));
78+
output.shouldMatch(".* archive version \\d+")
79+
.shouldContain("java.lang.Object boot_loader")
80+
.shouldContain("HelloUnload app_loader")
81+
.shouldContain("CustomLoadee unregistered_loader")
82+
.shouldContain("Shared Builtin Dictionary")
83+
.shouldContain("Shared Unregistered Dictionary")
84+
.shouldMatch("Number of shared symbols: \\d+")
85+
.shouldMatch("Number of shared strings: \\d+")
86+
.shouldMatch("VM version: .*");
87+
}
88+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright (c) 2021, 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+
* @summary Hello World test for dynamic archive with custom loader
28+
* @requires vm.cds
29+
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes
30+
* @build HelloUnload CustomLoadee jdk.test.lib.classloader.ClassUnloadCommon
31+
* @build sun.hotspot.WhiteBox
32+
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar HelloUnload
33+
* jdk.test.lib.classloader.ClassUnloadCommon
34+
* jdk.test.lib.classloader.ClassUnloadCommon$1
35+
* jdk.test.lib.classloader.ClassUnloadCommon$TestFailure
36+
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello_custom.jar CustomLoadee
37+
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
38+
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar PrintSharedArchiveAndExit
39+
*/
40+
41+
import java.io.File;
42+
import jdk.test.lib.cds.CDSTestUtils;
43+
import jdk.test.lib.process.OutputAnalyzer;
44+
import jdk.test.lib.helpers.ClassFileInstaller;
45+
46+
public class PrintSharedArchiveAndExit extends DynamicArchiveTestBase {
47+
private static final String ARCHIVE_NAME = CDSTestUtils.getOutputFileName("top.jsa");
48+
49+
public static void main(String... args) throws Exception {
50+
runTest(PrintSharedArchiveAndExit::testPrtNExit);
51+
}
52+
53+
public static void testPrtNExit() throws Exception {
54+
String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
55+
String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
56+
String appJar = ClassFileInstaller.getJarPath("hello.jar");
57+
String customJarPath = ClassFileInstaller.getJarPath("hello_custom.jar");
58+
String mainAppClass = "HelloUnload";
59+
60+
dump(ARCHIVE_NAME,
61+
use_whitebox_jar,
62+
"-XX:+UnlockDiagnosticVMOptions",
63+
"-XX:+WhiteBoxAPI",
64+
"-Xlog:cds",
65+
"-Xlog:cds+dynamic=debug",
66+
"-cp", appJar,
67+
mainAppClass, customJarPath, "false", "false")
68+
.assertNormalExit(output -> {
69+
output.shouldContain("Written dynamic archive 0x")
70+
.shouldNotContain("klasses.*=.*CustomLoadee")
71+
.shouldHaveExitValue(0);
72+
});
73+
74+
run(ARCHIVE_NAME,
75+
use_whitebox_jar,
76+
"-XX:+UnlockDiagnosticVMOptions",
77+
"-XX:+WhiteBoxAPI",
78+
"-Xlog:class+load",
79+
"-Xlog:cds=debug",
80+
"-Xlog:cds+dynamic=info",
81+
"-cp", appJar,
82+
"-XX:+PrintSharedArchiveAndExit",
83+
mainAppClass, customJarPath, "false", "true")
84+
.assertNormalExit(output -> {
85+
output.shouldHaveExitValue(0)
86+
.shouldMatch("Base archive name: .*.jsa") // given name ends with .jsa, maynot default name.
87+
.shouldMatch("Dynamic archive name: .*" + ARCHIVE_NAME)
88+
.shouldMatch("Base archive version \\d+")
89+
.shouldContain("java.lang.Object boot_loader")
90+
.shouldContain("HelloUnload app_loader")
91+
.shouldContain("CustomLoadee unregistered_loader")
92+
.shouldContain("Shared Builtin Dictionary")
93+
.shouldContain("Shared Unregistered Dictionary")
94+
.shouldMatch("Number of shared symbols: \\d+")
95+
.shouldMatch("Number of shared strings: \\d+")
96+
.shouldMatch("VM version: .*");
97+
});
98+
}
99+
}

0 commit comments

Comments
 (0)