Skip to content

Commit 5377458

Browse files
committed
8005885: enhance PrintCodeCache to print more data
Backport-of: b6843a162411b0fa32271592d8f3a6f241a54384
1 parent d23f4d6 commit 5377458

File tree

2 files changed

+167
-27
lines changed

2 files changed

+167
-27
lines changed

src/hotspot/share/code/codeCache.cpp

Lines changed: 88 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -101,22 +101,37 @@ class CodeBlob_sizes {
101101
scopes_pcs_size = 0;
102102
}
103103

104-
int total() { return total_size; }
105-
bool is_empty() { return count == 0; }
106-
107-
void print(const char* title) {
108-
tty->print_cr(" #%d %s = %dK (hdr %d%%, loc %d%%, code %d%%, stub %d%%, [oops %d%%, metadata %d%%, data %d%%, pcs %d%%])",
109-
count,
110-
title,
111-
(int)(total() / K),
112-
header_size * 100 / total_size,
113-
relocation_size * 100 / total_size,
114-
code_size * 100 / total_size,
115-
stub_size * 100 / total_size,
116-
scopes_oop_size * 100 / total_size,
117-
scopes_metadata_size * 100 / total_size,
118-
scopes_data_size * 100 / total_size,
119-
scopes_pcs_size * 100 / total_size);
104+
int total() const { return total_size; }
105+
bool is_empty() const { return count == 0; }
106+
107+
void print(const char* title) const {
108+
if (is_empty()) {
109+
tty->print_cr(" #%d %s = %dK",
110+
count,
111+
title,
112+
total() / (int)K);
113+
} else {
114+
tty->print_cr(" #%d %s = %dK (hdr %dK %d%%, loc %dK %d%%, code %dK %d%%, stub %dK %d%%, [oops %dK %d%%, metadata %dK %d%%, data %dK %d%%, pcs %dK %d%%])",
115+
count,
116+
title,
117+
total() / (int)K,
118+
header_size / (int)K,
119+
header_size * 100 / total_size,
120+
relocation_size / (int)K,
121+
relocation_size * 100 / total_size,
122+
code_size / (int)K,
123+
code_size * 100 / total_size,
124+
stub_size / (int)K,
125+
stub_size * 100 / total_size,
126+
scopes_oop_size / (int)K,
127+
scopes_oop_size * 100 / total_size,
128+
scopes_metadata_size / (int)K,
129+
scopes_metadata_size * 100 / total_size,
130+
scopes_data_size / (int)K,
131+
scopes_data_size * 100 / total_size,
132+
scopes_pcs_size / (int)K,
133+
scopes_pcs_size * 100 / total_size);
134+
}
120135
}
121136

122137
void add(CodeBlob* cb) {
@@ -1468,27 +1483,73 @@ void CodeCache::print() {
14681483
#ifndef PRODUCT
14691484
if (!Verbose) return;
14701485

1471-
CodeBlob_sizes live;
1472-
CodeBlob_sizes dead;
1486+
CodeBlob_sizes live[CompLevel_full_optimization + 1];
1487+
CodeBlob_sizes dead[CompLevel_full_optimization + 1];
1488+
CodeBlob_sizes runtimeStub;
1489+
CodeBlob_sizes uncommonTrapStub;
1490+
CodeBlob_sizes deoptimizationStub;
1491+
CodeBlob_sizes adapter;
1492+
CodeBlob_sizes bufferBlob;
1493+
CodeBlob_sizes other;
14731494

14741495
FOR_ALL_ALLOCABLE_HEAPS(heap) {
14751496
FOR_ALL_BLOBS(cb, *heap) {
1476-
if (!cb->is_alive()) {
1477-
dead.add(cb);
1497+
if (cb->is_nmethod()) {
1498+
const int level = cb->as_nmethod()->comp_level();
1499+
assert(0 <= level && level <= CompLevel_full_optimization, "Invalid compilation level");
1500+
if (!cb->is_alive()) {
1501+
dead[level].add(cb);
1502+
} else {
1503+
live[level].add(cb);
1504+
}
1505+
} else if (cb->is_runtime_stub()) {
1506+
runtimeStub.add(cb);
1507+
} else if (cb->is_deoptimization_stub()) {
1508+
deoptimizationStub.add(cb);
1509+
} else if (cb->is_uncommon_trap_stub()) {
1510+
uncommonTrapStub.add(cb);
1511+
} else if (cb->is_adapter_blob()) {
1512+
adapter.add(cb);
1513+
} else if (cb->is_buffer_blob()) {
1514+
bufferBlob.add(cb);
14781515
} else {
1479-
live.add(cb);
1516+
other.add(cb);
14801517
}
14811518
}
14821519
}
14831520

1484-
tty->print_cr("CodeCache:");
14851521
tty->print_cr("nmethod dependency checking time %fs", dependentCheckTime.seconds());
14861522

1487-
if (!live.is_empty()) {
1488-
live.print("live");
1489-
}
1490-
if (!dead.is_empty()) {
1491-
dead.print("dead");
1523+
tty->print_cr("nmethod blobs per compilation level:");
1524+
for (int i = 0; i <= CompLevel_full_optimization; i++) {
1525+
const char *level_name;
1526+
switch (i) {
1527+
case CompLevel_none: level_name = "none"; break;
1528+
case CompLevel_simple: level_name = "simple"; break;
1529+
case CompLevel_limited_profile: level_name = "limited profile"; break;
1530+
case CompLevel_full_profile: level_name = "full profile"; break;
1531+
case CompLevel_full_optimization: level_name = "full optimization"; break;
1532+
default: assert(false, "invalid compilation level");
1533+
}
1534+
tty->print_cr("%s:", level_name);
1535+
live[i].print("live");
1536+
dead[i].print("dead");
1537+
}
1538+
1539+
struct {
1540+
const char* name;
1541+
const CodeBlob_sizes* sizes;
1542+
} non_nmethod_blobs[] = {
1543+
{ "runtime", &runtimeStub },
1544+
{ "uncommon trap", &uncommonTrapStub },
1545+
{ "deoptimization", &deoptimizationStub },
1546+
{ "adapter", &adapter },
1547+
{ "buffer blob", &bufferBlob },
1548+
{ "other", &other },
1549+
};
1550+
tty->print_cr("Non-nmethod blobs:");
1551+
for (auto& blob: non_nmethod_blobs) {
1552+
blob.sizes->print(blob.name);
14921553
}
14931554

14941555
if (WizardMode) {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright Amazon.com Inc. 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+
* @test CheckCodeCacheInfo
26+
* @bug 8005885
27+
* @summary Checks VM verbose information related to the code cache
28+
* @library /test/lib
29+
* @requires vm.debug
30+
*
31+
* @run driver jdk.test.lib.helpers.ClassFileInstaller
32+
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
33+
* compiler.codecache.CheckCodeCacheInfo
34+
*/
35+
36+
package compiler.codecache;
37+
38+
import jdk.test.lib.process.OutputAnalyzer;
39+
import jdk.test.lib.process.ProcessTools;
40+
41+
public class CheckCodeCacheInfo {
42+
private static final String VERBOSE_REGEXP;
43+
44+
static {
45+
String entry = "\\d+K( \\(hdr \\d+K \\d+%, loc \\d+K \\d+%, code \\d+K \\d+%, stub \\d+K \\d+%, \\[oops \\d+K \\d+%, metadata \\d+K \\d+%, data \\d+K \\d+%, pcs \\d+K \\d+%\\]\\))?\\n";
46+
String pair = " #\\d+ live = " + entry
47+
+ " #\\d+ dead = " + entry;
48+
49+
VERBOSE_REGEXP = "nmethod blobs per compilation level:\\n"
50+
+ "none:\\n"
51+
+ pair
52+
+ "simple:\\n"
53+
+ pair
54+
+ "limited profile:\\n"
55+
+ pair
56+
+ "full profile:\\n"
57+
+ pair
58+
+ "full optimization:\\n"
59+
+ pair
60+
+ "Non-nmethod blobs:\\n"
61+
+ " #\\d+ runtime = " + entry
62+
+ " #\\d+ uncommon trap = " + entry
63+
+ " #\\d+ deoptimization = " + entry
64+
+ " #\\d+ adapter = " + entry
65+
+ " #\\d+ buffer blob = " + entry
66+
+ " #\\d+ other = " + entry;
67+
}
68+
69+
public static void main(String[] args) throws Exception {
70+
ProcessBuilder pb;
71+
72+
pb = ProcessTools.createJavaProcessBuilder("-XX:+PrintCodeCache",
73+
"-XX:+Verbose",
74+
"-version");
75+
OutputAnalyzer out = new OutputAnalyzer(pb.start());
76+
out.shouldHaveExitValue(0);
77+
out.stdoutShouldMatch(VERBOSE_REGEXP);
78+
}
79+
}

0 commit comments

Comments
 (0)