Skip to content

Commit b6843a1

Browse files
Yi-Fan TsaiPaul Hohensee
authored andcommitted
8005885: enhance PrintCodeCache to print more data
Reviewed-by: xliu, phh
1 parent 23995f8 commit b6843a1

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) {
@@ -1427,27 +1442,73 @@ void CodeCache::print() {
14271442
#ifndef PRODUCT
14281443
if (!Verbose) return;
14291444

1430-
CodeBlob_sizes live;
1431-
CodeBlob_sizes dead;
1445+
CodeBlob_sizes live[CompLevel_full_optimization + 1];
1446+
CodeBlob_sizes dead[CompLevel_full_optimization + 1];
1447+
CodeBlob_sizes runtimeStub;
1448+
CodeBlob_sizes uncommonTrapStub;
1449+
CodeBlob_sizes deoptimizationStub;
1450+
CodeBlob_sizes adapter;
1451+
CodeBlob_sizes bufferBlob;
1452+
CodeBlob_sizes other;
14321453

14331454
FOR_ALL_ALLOCABLE_HEAPS(heap) {
14341455
FOR_ALL_BLOBS(cb, *heap) {
1435-
if (!cb->is_alive()) {
1436-
dead.add(cb);
1456+
if (cb->is_nmethod()) {
1457+
const int level = cb->as_nmethod()->comp_level();
1458+
assert(0 <= level && level <= CompLevel_full_optimization, "Invalid compilation level");
1459+
if (!cb->is_alive()) {
1460+
dead[level].add(cb);
1461+
} else {
1462+
live[level].add(cb);
1463+
}
1464+
} else if (cb->is_runtime_stub()) {
1465+
runtimeStub.add(cb);
1466+
} else if (cb->is_deoptimization_stub()) {
1467+
deoptimizationStub.add(cb);
1468+
} else if (cb->is_uncommon_trap_stub()) {
1469+
uncommonTrapStub.add(cb);
1470+
} else if (cb->is_adapter_blob()) {
1471+
adapter.add(cb);
1472+
} else if (cb->is_buffer_blob()) {
1473+
bufferBlob.add(cb);
14371474
} else {
1438-
live.add(cb);
1475+
other.add(cb);
14391476
}
14401477
}
14411478
}
14421479

1443-
tty->print_cr("CodeCache:");
14441480
tty->print_cr("nmethod dependency checking time %fs", dependentCheckTime.seconds());
14451481

1446-
if (!live.is_empty()) {
1447-
live.print("live");
1448-
}
1449-
if (!dead.is_empty()) {
1450-
dead.print("dead");
1482+
tty->print_cr("nmethod blobs per compilation level:");
1483+
for (int i = 0; i <= CompLevel_full_optimization; i++) {
1484+
const char *level_name;
1485+
switch (i) {
1486+
case CompLevel_none: level_name = "none"; break;
1487+
case CompLevel_simple: level_name = "simple"; break;
1488+
case CompLevel_limited_profile: level_name = "limited profile"; break;
1489+
case CompLevel_full_profile: level_name = "full profile"; break;
1490+
case CompLevel_full_optimization: level_name = "full optimization"; break;
1491+
default: assert(false, "invalid compilation level");
1492+
}
1493+
tty->print_cr("%s:", level_name);
1494+
live[i].print("live");
1495+
dead[i].print("dead");
1496+
}
1497+
1498+
struct {
1499+
const char* name;
1500+
const CodeBlob_sizes* sizes;
1501+
} non_nmethod_blobs[] = {
1502+
{ "runtime", &runtimeStub },
1503+
{ "uncommon trap", &uncommonTrapStub },
1504+
{ "deoptimization", &deoptimizationStub },
1505+
{ "adapter", &adapter },
1506+
{ "buffer blob", &bufferBlob },
1507+
{ "other", &other },
1508+
};
1509+
tty->print_cr("Non-nmethod blobs:");
1510+
for (auto& blob: non_nmethod_blobs) {
1511+
blob.sizes->print(blob.name);
14511512
}
14521513

14531514
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)