8255746: Make PrintCompilation available on a per method level

Reviewed-by: chagedorn, kvn, xliu
This commit is contained in:
Joshua Cao 2022-10-19 19:40:18 +00:00 committed by Xin Liu
parent 388a56e4c4
commit f872467d69
8 changed files with 181 additions and 52 deletions

View File

@ -2093,11 +2093,13 @@ CompilerDirectives* DirectivesStack::_bottom = NULL;
//
void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
task->print_ul();
if (PrintCompilation) {
elapsedTimer time;
DirectiveSet* directive = task->directive();
if (directive->PrintCompilationOption) {
ResourceMark rm;
task->print_tty();
}
elapsedTimer time;
CompilerThread* thread = CompilerThread::current();
ResourceMark rm(thread);
@ -2114,19 +2116,14 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
bool should_break = false;
const int task_level = task->comp_level();
AbstractCompiler* comp = task->compiler();
DirectiveSet* directive;
{
// create the handle inside it's own block so it can't
// accidentally be referenced once the thread transitions to
// native. The NoHandleMark before the transition should catch
// any cases where this occurs in the future.
methodHandle method(thread, task->method());
assert(!method->is_native(), "no longer compile natives");
// Look up matching directives
directive = DirectivesStack::getMatchingDirective(method, comp);
task->set_directive(directive);
assert(!method->is_native(), "no longer compile natives");
// Update compile information when using perfdata.
if (UsePerfData) {

View File

@ -117,7 +117,8 @@ void CompileTask::initialize(int compile_id,
_time_started = 0;
_compile_reason = compile_reason;
_nm_content_size = 0;
_directive = NULL;
AbstractCompiler* comp = compiler();
_directive = DirectivesStack::getMatchingDirective(method, comp);
_nm_insts_size = 0;
_nm_total_size = 0;
_failure_reason = NULL;

View File

@ -86,7 +86,7 @@ class CompileTask : public CHeapObj<mtCompiler> {
CodeSection::csize_t _nm_content_size;
CodeSection::csize_t _nm_total_size;
CodeSection::csize_t _nm_insts_size;
const DirectiveSet* _directive;
DirectiveSet* _directive;
#if INCLUDE_JVMCI
bool _has_waiter;
// Compilation state for a blocking JVMCI compilation
@ -127,8 +127,7 @@ class CompileTask : public CHeapObj<mtCompiler> {
bool is_complete() const { return _is_complete; }
bool is_blocking() const { return _is_blocking; }
bool is_success() const { return _is_success; }
void set_directive(const DirectiveSet* directive) { _directive = directive; }
const DirectiveSet* directive() const { return _directive; }
DirectiveSet* directive() const { return _directive; }
CodeSection::csize_t nm_content_size() { return _nm_content_size; }
void set_nm_content_size(CodeSection::csize_t size) { _nm_content_size = size; }
CodeSection::csize_t nm_insts_size() { return _nm_insts_size; }

View File

@ -42,6 +42,7 @@
cflags(BreakAtCompile, bool, false, BreakAtCompile) \
cflags(Log, bool, LogCompilation, Unknown) \
cflags(PrintAssembly, bool, PrintAssembly, PrintAssembly) \
cflags(PrintCompilation, bool, PrintCompilation, PrintCompilation) \
cflags(PrintInlining, bool, PrintInlining, PrintInlining) \
cflags(PrintNMethods, bool, PrintNMethods, PrintNMethods) \
cflags(BackgroundCompilation, bool, BackgroundCompilation, BackgroundCompilation) \

View File

@ -58,6 +58,7 @@ class methodHandle;
option(BreakAtExecute, "BreakAtExecute", Bool) \
option(BreakAtCompile, "BreakAtCompile", Bool) \
option(PrintAssembly, "PrintAssembly", Bool) \
option(PrintCompilation, "PrintCompilation", Bool) \
option(PrintInlining, "PrintInlining", Bool) \
option(PrintIntrinsics, "PrintIntrinsics", Bool) \
option(PrintNMethods, "PrintNMethods", Bool) \

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2022, Oracle and/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
* @bug 8255746
* @summary Checks that -XX:CompileCommand=PrintCompilation,... works
* @library /test/lib
* @run driver compiler.print.CompileCommandPrintCompilation
*/
package compiler.print;
import java.util.ArrayList;
import java.util.List;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
public class CompileCommandPrintCompilation {
final static String METHOD1 = "method1";
final static String METHOD2 = "method2";
public static void main(String[] args) throws Exception {
test(METHOD1, METHOD2);
test(METHOD2, METHOD1);
}
private static void test(String include, String exclude) throws Exception {
List<String> options = new ArrayList<String>();
options.add("-Xcomp");
options.add("-XX:-Inline");
options.add("-XX:CompileCommand=compileonly," + getTestClass() + "::*");
options.add("-XX:CompileCommand=PrintCompilation," + getTestMethod(include));
options.add(getTestClass());
OutputAnalyzer oa = ProcessTools.executeTestJvm(options);
oa.shouldHaveExitValue(0)
.shouldContain(getTestMethod(include))
.shouldNotContain(getTestMethod(exclude));
}
// Test class that is invoked by the sub process
public static String getTestClass() {
return TestMain.class.getName();
}
public static String getTestMethod(String method) {
return getTestClass() + "::" + method;
}
public static class TestMain {
public static void main(String[] args) {
method1();
method2();
}
static void method1() {}
static void method2() {}
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2022, Oracle and/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
* @summary Checks that -XX:PrintCompilation works
* @library /test/lib
* @run driver compiler.print.PrintCompilation
*/
package compiler.print;
import java.util.ArrayList;
import java.util.List;
import jdk.test.lib.Asserts;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
public class PrintCompilation {
public static void main(String[] args) throws Exception {
List<String> options = new ArrayList<String>();
options.add("-XX:+PrintCompilation");
options.add("-Xcomp");
options.add("-XX:-Inline");
options.add("-XX:CompileCommand=compileonly," + getTestClass() + "::*");
options.add(getTestClass());
OutputAnalyzer oa = ProcessTools.executeTestJvm(options);
oa.shouldHaveExitValue(0)
.shouldContain(getTestMethod("method1"))
.shouldContain(getTestMethod("method2"))
.shouldContain(getTestMethod("method3"))
.shouldNotContain(getTestMethod("notcalled"));
}
// Test class that is invoked by the sub process
public static String getTestClass() {
return TestMain.class.getName();
}
public static String getTestMethod(String method) {
return getTestClass() + "::" + method;
}
public static class TestMain {
public static void main(String[] args) {
method1();
method2();
method3();
}
static void method1() { System.out.println("method1()"); }
static void method2() {}
static void method3() {}
static void notcalled() {}
}
}

View File

@ -43,52 +43,16 @@ import sun.management.*;
import com.sun.management.*;
public class BooleanTest {
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
private static final Boolean[] TESTS = {true, false, true, true, false};
private static final String TEST_NAME = "BooleanTest";
private static final String FLAG_NAME = "PrintCompilation";
private static final String FLAG_DEBUG_NAME = "SafepointALot";
private static final String METHOD = TEST_NAME + "::method";
private static final String METHOD1 = METHOD + "1";
private static final String METHOD2 = METHOD + "2";
public static void main(String[] args) throws Exception {
if (args.length == 0) {
VmFlagTest.runTest(FLAG_NAME, TESTS,
VmFlagTest.WHITE_BOX::setBooleanVMFlag,
VmFlagTest.WHITE_BOX::getBooleanVMFlag);
testFunctional(false);
testFunctional(true);
VmFlagTest.runTest(FLAG_DEBUG_NAME, VmFlagTest.WHITE_BOX::getBooleanVMFlag);
} else {
boolean value = Boolean.valueOf(args[0]);
method1();
VmFlagTest.WHITE_BOX.setBooleanVMFlag(FLAG_NAME, value);
method2();
}
VmFlagTest.runTest(FLAG_NAME, TESTS,
VmFlagTest.WHITE_BOX::setBooleanVMFlag,
VmFlagTest.WHITE_BOX::getBooleanVMFlag);
VmFlagTest.runTest(FLAG_DEBUG_NAME, VmFlagTest.WHITE_BOX::getBooleanVMFlag);
}
private static void testFunctional(boolean value) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xbootclasspath/a:.",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
"-Xcomp",
"-XX:CompileCommand=compileonly," + METHOD + "*",
"-XX:" + (value ? "-" : "+") + FLAG_NAME,
TEST_NAME,
"" + value);
OutputAnalyzer out = new OutputAnalyzer(pb.start());
if (value) {
out.shouldNotContain(METHOD1);
out.shouldContain(METHOD2);
} else {
out.shouldContain(METHOD1);
out.shouldNotContain(METHOD2);
}
}
private static void method1() { }
private static void method2() { }
}