Skip to content

Commit

Permalink
Backport b6843a162411b0fa32271592d8f3a6f241a54384
Browse files Browse the repository at this point in the history
  • Loading branch information
duke committed Jun 5, 2024
1 parent ab84520 commit a34c697
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 27 deletions.
115 changes: 88 additions & 27 deletions src/hotspot/share/code/codeCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,22 +101,37 @@ class CodeBlob_sizes {
scopes_pcs_size = 0;
}

int total() { return total_size; }
bool is_empty() { return count == 0; }

void print(const char* title) {
tty->print_cr(" #%d %s = %dK (hdr %d%%, loc %d%%, code %d%%, stub %d%%, [oops %d%%, metadata %d%%, data %d%%, pcs %d%%])",
count,
title,
(int)(total() / K),
header_size * 100 / total_size,
relocation_size * 100 / total_size,
code_size * 100 / total_size,
stub_size * 100 / total_size,
scopes_oop_size * 100 / total_size,
scopes_metadata_size * 100 / total_size,
scopes_data_size * 100 / total_size,
scopes_pcs_size * 100 / total_size);
int total() const { return total_size; }
bool is_empty() const { return count == 0; }

void print(const char* title) const {
if (is_empty()) {
tty->print_cr(" #%d %s = %dK",
count,
title,
total() / (int)K);
} else {
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%%])",
count,
title,
total() / (int)K,
header_size / (int)K,
header_size * 100 / total_size,
relocation_size / (int)K,
relocation_size * 100 / total_size,
code_size / (int)K,
code_size * 100 / total_size,
stub_size / (int)K,
stub_size * 100 / total_size,
scopes_oop_size / (int)K,
scopes_oop_size * 100 / total_size,
scopes_metadata_size / (int)K,
scopes_metadata_size * 100 / total_size,
scopes_data_size / (int)K,
scopes_data_size * 100 / total_size,
scopes_pcs_size / (int)K,
scopes_pcs_size * 100 / total_size);
}
}

void add(CodeBlob* cb) {
Expand Down Expand Up @@ -1468,27 +1483,73 @@ void CodeCache::print() {
#ifndef PRODUCT
if (!Verbose) return;

CodeBlob_sizes live;
CodeBlob_sizes dead;
CodeBlob_sizes live[CompLevel_full_optimization + 1];
CodeBlob_sizes dead[CompLevel_full_optimization + 1];
CodeBlob_sizes runtimeStub;
CodeBlob_sizes uncommonTrapStub;
CodeBlob_sizes deoptimizationStub;
CodeBlob_sizes adapter;
CodeBlob_sizes bufferBlob;
CodeBlob_sizes other;

FOR_ALL_ALLOCABLE_HEAPS(heap) {
FOR_ALL_BLOBS(cb, *heap) {
if (!cb->is_alive()) {
dead.add(cb);
if (cb->is_nmethod()) {
const int level = cb->as_nmethod()->comp_level();
assert(0 <= level && level <= CompLevel_full_optimization, "Invalid compilation level");
if (!cb->is_alive()) {
dead[level].add(cb);
} else {
live[level].add(cb);
}
} else if (cb->is_runtime_stub()) {
runtimeStub.add(cb);
} else if (cb->is_deoptimization_stub()) {
deoptimizationStub.add(cb);
} else if (cb->is_uncommon_trap_stub()) {
uncommonTrapStub.add(cb);
} else if (cb->is_adapter_blob()) {
adapter.add(cb);
} else if (cb->is_buffer_blob()) {
bufferBlob.add(cb);
} else {
live.add(cb);
other.add(cb);
}
}
}

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

if (!live.is_empty()) {
live.print("live");
}
if (!dead.is_empty()) {
dead.print("dead");
tty->print_cr("nmethod blobs per compilation level:");
for (int i = 0; i <= CompLevel_full_optimization; i++) {
const char *level_name;
switch (i) {
case CompLevel_none: level_name = "none"; break;
case CompLevel_simple: level_name = "simple"; break;
case CompLevel_limited_profile: level_name = "limited profile"; break;
case CompLevel_full_profile: level_name = "full profile"; break;
case CompLevel_full_optimization: level_name = "full optimization"; break;
default: assert(false, "invalid compilation level");
}
tty->print_cr("%s:", level_name);
live[i].print("live");
dead[i].print("dead");
}

struct {
const char* name;
const CodeBlob_sizes* sizes;
} non_nmethod_blobs[] = {
{ "runtime", &runtimeStub },
{ "uncommon trap", &uncommonTrapStub },
{ "deoptimization", &deoptimizationStub },
{ "adapter", &adapter },
{ "buffer blob", &bufferBlob },
{ "other", &other },
};
tty->print_cr("Non-nmethod blobs:");
for (auto& blob: non_nmethod_blobs) {
blob.sizes->print(blob.name);
}

if (WizardMode) {
Expand Down
79 changes: 79 additions & 0 deletions test/hotspot/jtreg/compiler/codecache/CheckCodeCacheInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright Amazon.com Inc. 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 CheckCodeCacheInfo
* @bug 8005885
* @summary Checks VM verbose information related to the code cache
* @library /test/lib
* @requires vm.debug
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* compiler.codecache.CheckCodeCacheInfo
*/

package compiler.codecache;

import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;

public class CheckCodeCacheInfo {
private static final String VERBOSE_REGEXP;

static {
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";
String pair = " #\\d+ live = " + entry
+ " #\\d+ dead = " + entry;

VERBOSE_REGEXP = "nmethod blobs per compilation level:\\n"
+ "none:\\n"
+ pair
+ "simple:\\n"
+ pair
+ "limited profile:\\n"
+ pair
+ "full profile:\\n"
+ pair
+ "full optimization:\\n"
+ pair
+ "Non-nmethod blobs:\\n"
+ " #\\d+ runtime = " + entry
+ " #\\d+ uncommon trap = " + entry
+ " #\\d+ deoptimization = " + entry
+ " #\\d+ adapter = " + entry
+ " #\\d+ buffer blob = " + entry
+ " #\\d+ other = " + entry;
}

public static void main(String[] args) throws Exception {
ProcessBuilder pb;

pb = ProcessTools.createJavaProcessBuilder("-XX:+PrintCodeCache",
"-XX:+Verbose",
"-version");
OutputAnalyzer out = new OutputAnalyzer(pb.start());
out.shouldHaveExitValue(0);
out.stdoutShouldMatch(VERBOSE_REGEXP);
}
}

0 comments on commit a34c697

Please sign in to comment.