8022585: VM crashes when ran with -XX:+PrintInlining
Use adr_at() to access inline info structures in growableArray. Add ability to specify print inlining per method. Reviewed-by: twisti
This commit is contained in:
parent
a2889becd9
commit
0ccb2841ea
@ -4219,7 +4219,9 @@ void GraphBuilder::print_inlining(ciMethod* callee, const char* msg, bool succes
|
||||
}
|
||||
}
|
||||
|
||||
if (!PrintInlining) return;
|
||||
if (!PrintInlining && !compilation()->method()->has_option("PrintInlining")) {
|
||||
return;
|
||||
}
|
||||
CompileTask::print_inlining(callee, scope()->level(), bci(), msg);
|
||||
if (success && CIPrintMethodCodes) {
|
||||
callee->print_codes();
|
||||
|
@ -123,7 +123,7 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method,
|
||||
// Allows targeted inlining
|
||||
if(callee_method->should_inline()) {
|
||||
*wci_result = *(WarmCallInfo::always_hot());
|
||||
if (PrintInlining && Verbose) {
|
||||
if (C->print_inlining() && Verbose) {
|
||||
CompileTask::print_inline_indent(inline_level());
|
||||
tty->print_cr("Inlined method is hot: ");
|
||||
}
|
||||
@ -137,7 +137,7 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method,
|
||||
if(callee_method->interpreter_throwout_count() > InlineThrowCount &&
|
||||
size < InlineThrowMaxSize ) {
|
||||
wci_result->set_profit(wci_result->profit() * 100);
|
||||
if (PrintInlining && Verbose) {
|
||||
if (C->print_inlining() && Verbose) {
|
||||
CompileTask::print_inline_indent(inline_level());
|
||||
tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count());
|
||||
}
|
||||
@ -491,7 +491,7 @@ void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci,
|
||||
C->log()->inline_fail(inline_msg);
|
||||
}
|
||||
}
|
||||
if (PrintInlining) {
|
||||
if (C->print_inlining()) {
|
||||
C->print_inlining(callee_method, inline_level(), caller_bci, inline_msg);
|
||||
if (callee_method == NULL) tty->print(" callee not monotonic or profiled");
|
||||
if (Verbose && callee_method) {
|
||||
@ -540,7 +540,7 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms,
|
||||
|
||||
#ifndef PRODUCT
|
||||
if (UseOldInlining && InlineWarmCalls
|
||||
&& (PrintOpto || PrintOptoInlining || PrintInlining)) {
|
||||
&& (PrintOpto || C->print_inlining())) {
|
||||
bool cold = wci.is_cold();
|
||||
bool hot = !cold && wci.is_hot();
|
||||
bool old_cold = !success;
|
||||
@ -617,7 +617,7 @@ InlineTree *InlineTree::build_inline_tree_for_callee( ciMethod* callee_method, J
|
||||
callee_method->is_compiled_lambda_form()) {
|
||||
max_inline_level_adjust += 1; // don't count method handle calls from java.lang.invoke implem
|
||||
}
|
||||
if (max_inline_level_adjust != 0 && PrintInlining && (Verbose || WizardMode)) {
|
||||
if (max_inline_level_adjust != 0 && C->print_inlining() && (Verbose || WizardMode)) {
|
||||
CompileTask::print_inline_indent(inline_level());
|
||||
tty->print_cr(" \\-> discounting inline depth");
|
||||
}
|
||||
|
@ -159,8 +159,9 @@ class CallGenerator : public ResourceObj {
|
||||
virtual void print_inlining_late(const char* msg) { ShouldNotReachHere(); }
|
||||
|
||||
static void print_inlining(Compile* C, ciMethod* callee, int inline_level, int bci, const char* msg) {
|
||||
if (PrintInlining)
|
||||
if (C->print_inlining()) {
|
||||
C->print_inlining(callee, inline_level, bci, msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -654,7 +654,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
|
||||
_inlining_progress(false),
|
||||
_inlining_incrementally(false),
|
||||
_print_inlining_list(NULL),
|
||||
_print_inlining(0) {
|
||||
_print_inlining_idx(0) {
|
||||
C = this;
|
||||
|
||||
CompileWrapper cw(this);
|
||||
@ -679,6 +679,8 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
|
||||
set_print_assembly(print_opto_assembly);
|
||||
set_parsed_irreducible_loop(false);
|
||||
#endif
|
||||
set_print_inlining(PrintInlining || method()->has_option("PrintInlining") NOT_PRODUCT( || PrintOptoInlining));
|
||||
set_print_intrinsics(PrintIntrinsics || method()->has_option("PrintIntrinsics"));
|
||||
|
||||
if (ProfileTraps) {
|
||||
// Make sure the method being compiled gets its own MDO,
|
||||
@ -710,7 +712,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
|
||||
PhaseGVN gvn(node_arena(), estimated_size);
|
||||
set_initial_gvn(&gvn);
|
||||
|
||||
if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) {
|
||||
if (print_inlining() || print_intrinsics()) {
|
||||
_print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer>(comp_arena(), 1, 1, PrintInliningBuffer());
|
||||
}
|
||||
{ // Scope for timing the parser
|
||||
@ -937,7 +939,7 @@ Compile::Compile( ciEnv* ci_env,
|
||||
_inlining_progress(false),
|
||||
_inlining_incrementally(false),
|
||||
_print_inlining_list(NULL),
|
||||
_print_inlining(0) {
|
||||
_print_inlining_idx(0) {
|
||||
C = this;
|
||||
|
||||
#ifndef PRODUCT
|
||||
@ -3611,7 +3613,7 @@ void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n
|
||||
}
|
||||
|
||||
void Compile::dump_inlining() {
|
||||
if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) {
|
||||
if (print_inlining() || print_intrinsics()) {
|
||||
// Print inlining message for candidates that we couldn't inline
|
||||
// for lack of space or non constant receiver
|
||||
for (int i = 0; i < _late_inlines.length(); i++) {
|
||||
@ -3635,7 +3637,7 @@ void Compile::dump_inlining() {
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < _print_inlining_list->length(); i++) {
|
||||
tty->print(_print_inlining_list->at(i).ss()->as_string());
|
||||
tty->print(_print_inlining_list->adr_at(i)->ss()->as_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -312,6 +312,8 @@ class Compile : public Phase {
|
||||
bool _do_method_data_update; // True if we generate code to update MethodData*s
|
||||
int _AliasLevel; // Locally-adjusted version of AliasLevel flag.
|
||||
bool _print_assembly; // True if we should dump assembly code for this compilation
|
||||
bool _print_inlining; // True if we should print inlining for this compilation
|
||||
bool _print_intrinsics; // True if we should print intrinsics for this compilation
|
||||
#ifndef PRODUCT
|
||||
bool _trace_opto_output;
|
||||
bool _parsed_irreducible_loop; // True if ciTypeFlow detected irreducible loops during parsing
|
||||
@ -414,7 +416,7 @@ class Compile : public Phase {
|
||||
};
|
||||
|
||||
GrowableArray<PrintInliningBuffer>* _print_inlining_list;
|
||||
int _print_inlining;
|
||||
int _print_inlining_idx;
|
||||
|
||||
// Only keep nodes in the expensive node list that need to be optimized
|
||||
void cleanup_expensive_nodes(PhaseIterGVN &igvn);
|
||||
@ -426,24 +428,24 @@ class Compile : public Phase {
|
||||
public:
|
||||
|
||||
outputStream* print_inlining_stream() const {
|
||||
return _print_inlining_list->at(_print_inlining).ss();
|
||||
return _print_inlining_list->adr_at(_print_inlining_idx)->ss();
|
||||
}
|
||||
|
||||
void print_inlining_skip(CallGenerator* cg) {
|
||||
if (PrintInlining) {
|
||||
_print_inlining_list->at(_print_inlining).set_cg(cg);
|
||||
_print_inlining++;
|
||||
_print_inlining_list->insert_before(_print_inlining, PrintInliningBuffer());
|
||||
if (_print_inlining) {
|
||||
_print_inlining_list->adr_at(_print_inlining_idx)->set_cg(cg);
|
||||
_print_inlining_idx++;
|
||||
_print_inlining_list->insert_before(_print_inlining_idx, PrintInliningBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
void print_inlining_insert(CallGenerator* cg) {
|
||||
if (PrintInlining) {
|
||||
if (_print_inlining) {
|
||||
for (int i = 0; i < _print_inlining_list->length(); i++) {
|
||||
if (_print_inlining_list->at(i).cg() == cg) {
|
||||
if (_print_inlining_list->adr_at(i)->cg() == cg) {
|
||||
_print_inlining_list->insert_before(i+1, PrintInliningBuffer());
|
||||
_print_inlining = i+1;
|
||||
_print_inlining_list->at(i).set_cg(NULL);
|
||||
_print_inlining_idx = i+1;
|
||||
_print_inlining_list->adr_at(i)->set_cg(NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -572,6 +574,10 @@ class Compile : public Phase {
|
||||
int AliasLevel() const { return _AliasLevel; }
|
||||
bool print_assembly() const { return _print_assembly; }
|
||||
void set_print_assembly(bool z) { _print_assembly = z; }
|
||||
bool print_inlining() const { return _print_inlining; }
|
||||
void set_print_inlining(bool z) { _print_inlining = z; }
|
||||
bool print_intrinsics() const { return _print_intrinsics; }
|
||||
void set_print_intrinsics(bool z) { _print_intrinsics = z; }
|
||||
// check the CompilerOracle for special behaviours for this compile
|
||||
bool method_has_option(const char * option) {
|
||||
return method() != NULL && method()->has_option(option);
|
||||
|
@ -41,9 +41,9 @@
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
|
||||
void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) {
|
||||
if (TraceTypeProfile || PrintInlining NOT_PRODUCT(|| PrintOptoInlining)) {
|
||||
if (TraceTypeProfile || C->print_inlining()) {
|
||||
outputStream* out = tty;
|
||||
if (!PrintInlining) {
|
||||
if (!C->print_inlining()) {
|
||||
if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) {
|
||||
method->print_short_name();
|
||||
tty->cr();
|
||||
|
@ -543,7 +543,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
|
||||
Compile* C = kit.C;
|
||||
int nodes = C->unique();
|
||||
#ifndef PRODUCT
|
||||
if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) {
|
||||
if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
|
||||
char buf[1000];
|
||||
const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
|
||||
tty->print_cr("Intrinsic %s", str);
|
||||
@ -554,7 +554,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
|
||||
|
||||
// Try to inline the intrinsic.
|
||||
if (kit.try_to_inline()) {
|
||||
if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) {
|
||||
if (C->print_intrinsics() || C->print_inlining()) {
|
||||
C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
|
||||
}
|
||||
C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked);
|
||||
@ -570,7 +570,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
|
||||
}
|
||||
|
||||
// The intrinsic bailed out
|
||||
if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) {
|
||||
if (C->print_intrinsics() || C->print_inlining()) {
|
||||
if (jvms->has_method()) {
|
||||
// Not a root compile.
|
||||
const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)";
|
||||
@ -592,7 +592,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) {
|
||||
int nodes = C->unique();
|
||||
#ifndef PRODUCT
|
||||
assert(is_predicted(), "sanity");
|
||||
if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) {
|
||||
if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
|
||||
char buf[1000];
|
||||
const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
|
||||
tty->print_cr("Predicate for intrinsic %s", str);
|
||||
@ -603,7 +603,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) {
|
||||
|
||||
Node* slow_ctl = kit.try_to_predicate();
|
||||
if (!kit.failing()) {
|
||||
if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) {
|
||||
if (C->print_intrinsics() || C->print_inlining()) {
|
||||
C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
|
||||
}
|
||||
C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked);
|
||||
@ -617,7 +617,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) {
|
||||
}
|
||||
|
||||
// The intrinsic bailed out
|
||||
if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) {
|
||||
if (C->print_intrinsics() || C->print_inlining()) {
|
||||
if (jvms->has_method()) {
|
||||
// Not a root compile.
|
||||
const char* msg = "failed to generate predicate for intrinsic";
|
||||
@ -2299,7 +2299,7 @@ const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_
|
||||
const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass);
|
||||
|
||||
#ifndef PRODUCT
|
||||
if (PrintIntrinsics || PrintInlining || PrintOptoInlining) {
|
||||
if (C->print_intrinsics() || C->print_inlining()) {
|
||||
tty->print(" from base type: "); adr_type->dump();
|
||||
tty->print(" sharpened value: "); tjp->dump();
|
||||
}
|
||||
@ -3260,7 +3260,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) {
|
||||
if (mirror_con == NULL) return false; // cannot happen?
|
||||
|
||||
#ifndef PRODUCT
|
||||
if (PrintIntrinsics || PrintInlining || PrintOptoInlining) {
|
||||
if (C->print_intrinsics() || C->print_inlining()) {
|
||||
ciType* k = mirror_con->java_mirror_type();
|
||||
if (k) {
|
||||
tty->print("Inlining %s on constant Class ", vmIntrinsics::name_at(intrinsic_id()));
|
||||
@ -3952,14 +3952,14 @@ bool LibraryCallKit::inline_native_getClass() {
|
||||
// caller sensitive methods.
|
||||
bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
|
||||
#ifndef PRODUCT
|
||||
if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
|
||||
if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
|
||||
tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!jvms()->has_method()) {
|
||||
#ifndef PRODUCT
|
||||
if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
|
||||
if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
|
||||
tty->print_cr(" Bailing out because intrinsic was inlined at top level");
|
||||
}
|
||||
#endif
|
||||
@ -3983,7 +3983,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
|
||||
// Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass).
|
||||
if (!m->caller_sensitive()) {
|
||||
#ifndef PRODUCT
|
||||
if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
|
||||
if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
|
||||
tty->print_cr(" Bailing out: CallerSensitive annotation expected at frame %d", n);
|
||||
}
|
||||
#endif
|
||||
@ -3999,7 +3999,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
|
||||
set_result(makecon(TypeInstPtr::make(caller_mirror)));
|
||||
|
||||
#ifndef PRODUCT
|
||||
if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
|
||||
if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
|
||||
tty->print_cr(" Succeeded: caller = %d) %s.%s, JVMS depth = %d", n, caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), jvms()->depth());
|
||||
tty->print_cr(" JVM state at this point:");
|
||||
for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) {
|
||||
@ -4015,7 +4015,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
|
||||
if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
|
||||
tty->print_cr(" Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth());
|
||||
tty->print_cr(" JVM state at this point:");
|
||||
for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) {
|
||||
|
36
hotspot/test/compiler/print/PrintInlining.java
Normal file
36
hotspot/test/compiler/print/PrintInlining.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 8022585
|
||||
* @summary VM crashes when ran with -XX:+PrintInlining
|
||||
* @run main/othervm -Xcomp -XX:+PrintInlining PrintInlining
|
||||
*
|
||||
*/
|
||||
|
||||
public class PrintInlining {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Passed");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user