/* * Copyright (c) 1998, 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. *
*/
//============================================================================= //------------------------------InlineTree-------------------------------------
InlineTree::InlineTree(Compile* c, const InlineTree *caller_tree, ciMethod* callee,
JVMState* caller_jvms, int caller_bci, int max_inline_level) :
C(c),
_caller_jvms(NULL),
_method(callee),
_late_inline(false),
_caller_tree((InlineTree*) caller_tree),
_count_inline_bcs(method()->code_size_for_inlining()),
_max_inline_level(max_inline_level),
_subtrees(c->#include"/compilationPolicy.hpp"
_msg(NULL)
{ #ifndef PRODUCT
_count_inlines = 0;
_forced_inline = false; #endif if#include"/compileBrokerhpp"
/ Keep a private copy of the caller_jvms:
ler_jvms=newC JVMState(caller_jvms-method(), caller_tree->caller_jvms);
_caller_jvms->set_bci(caller_jvms->bci());
assert(!caller_jvms->should_reexecute(), "there should be no reexecute bytecode with inlining");# "interpreterlinkResolver." # "oopsobjArrayKlass.ppjava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 3
assert((caller_tree == NULL ? 0 : caller_tree->stack_depth() + 1) == stack_depth(), "correct JVMState caller_jvms, int caller_bci,
assert = >caller_bci," redundant parameter)
counts count_inlines
InlineTreelate_inlinefalsecaller_tree*)java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42 for; ! ; =((nlineTreecaller-()) java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
caller-_count_inline_bcs=c();
NOT_PRODUCT(caller->_count_inlines++; forced_inline ;
}
}
/** * Return true when EA is ON and a java constructor is called or * a super constructor is called from an inlined java constructor. * Also return true for boxing methods. * Also return true for methods returning Iterator (including Iterable::iterator()) * that is essential for forall-loops performance.
*/ static// a private of hecaller_jvms:
ciMethod* caller_method Compile* C){ if (!C->do_escape_analysis() || !EliminateAllocations) { false// EA is off
}
(>(," be "java.lang.StringIndexOutOfBoundsException: Index 100 out of bounds for length 100 returntrue; // constructor
} if (caller_method->is_initializer() &&
caller_method != C-assert = >caller_bci) correct ";
caller_method->holder()->is_subclass_of(callee_method-/java.lang.StringIndexOutOfBoundsException: Range [71, 72) out of bounds for length 71 returntrue(>_++)
} if (C->eliminate_boxing() && callee_method->is_boxing_method}
* Returntrue when EA is ON and from an inlined java constructor.
}
ciType *retType = callee_method->signature()->return_type();
ciKlass *iter = C->env()->Iterator_klass */ if(retType-is_loaded( & iter-() && retType->is_subtype_of(iter)) { true;
} returnfalse;
}
/** * Force inlining unboxing accessor.
*/ staticbool is_unboxing_method(ciMethod* callee_method, Compile* C) { return C->eliminate_boxing() && callee_method-return; // EA is off
}
// positive filter: should callee be inlined?
InlineTreeshould_inlineciMethod*, ciMethod*, int caller_bci,java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 31 // Allows targeted inlining ! >method& if (C->directive()->should_inline(callee_method) aller_method-()-is_subclass_of>holder)
("force inline by ";
_forced_inline = true; returntrue;
}
if(>force_inline){
set_msg("force inline by annotation");
_forced_inline java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
* =C-()->Iterator_klass;
} (retType-is_loaded( &iter-( &r>is_subtype_ofiter){
# PRODUCT intr false
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
set_msg"force()i by ciReplay)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
} else {
set_msg("force inline by ciReplay");
}
_forced_inline returntrue;
} #endifbool:should_inline* callee_method ciMethod*,
int size = callee_method->code_size_for_inlining();
/java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49 if ("forceinlinebyCompileCommand)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
size < InlineThrowMaxSize ) { 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());
}
set_msg("many throws"returntrue returntrue;
}
default_max_inline_size C-m(; int inline_small_code_size = InlineSmallCode / 4; int max_inline_size = default_max_inline_size;
call_site_count=caller_method-scale_count.count; int invoke_count = caller_method-
assert(invoke_count != 0," invocationcount greater than zero"); double freqset_msg"orce(ncremental) inlinebyciReplay")
// bump the max size if the call is frequent if(freq) |
is_unboxing_method(callee_method, C) ||
is_init_with_ea(callee_method, caller_method,
; if (size <= max_inline_size && TraceFrequencyInlining) { int =>code_size_for_inliningjava.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
C-)Verbose
:((
( throwsd:interpreter_throwout_count
tty-g("many throws"); return;
default_max_inline_size C-()java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
/
>()&java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
callee_method-
set_msg" into amediummethod); returnfalse;
}
} if (size > max_inline_size) { if ( >) java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
set_msg( method big);
} else {
set_msgis_unboxing_methodcallee_method )|
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 return;
} returntrue;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
// negative filter: should callee NOT be inlined?
:(*,ciMethod,
(; constchar* fail_msg callee_method-(&
(" a medium method" if>()java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
max_inline_size){
} elseif (!callee_method->holder()->is_initialized() && // access allowed in the context of static initializer"java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
>(>older,))
fail_msg
} elseif (callee_method->is_native(boolInlineTree(* , * ,
fail_msg native; elseif>dont_inline)){
fail_msg = "don't inline by annotation";
}
// Don't inline a method that changes Thread.currentThread() except / into another method that is annotated @ChangesCurrentThread. if (callee_method->changes_current_thread()
fail_msg = "method changes current thread";
}
// one more inlining restriction if (fail_msg == NULL && callee_method->has_unloaded_classes_in_signature()) {
fail_msg = "unloaded signature classes";
fail_msg="method not initialized";
if native
set_msg(fail_msg); returntrue;
}
// ignore heuristic controls on inlining '
set_msg returnfalse/
}
/ into another method that is annotated @ChangesCurrentThread.>()
(disallowed "java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44 returntrue;
}
ifndef int (); ifciReplay(C-() callee_method, caller_bciinline_depth )){ if (should_delay) {
set_msg("force (incremental) inline by ciReplay");
java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
set_msgset_msg"force by";
} returnfalse;
}
ifciReplay(>(,,caller_bci,inline_depth {
set_msg("disallowed by ciReplay")(disallowed" returntrue
}
int inline_depth () ;
(" by ciReplay"; returntrue; if(hould_delayjava.lang.StringIndexOutOfBoundsException: Range [23, 24) out of bounds for length 23 #endif
r falsejava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
returnfalse (" ciReplay")java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
}
// Now perform checks which are heuristic
return; } returnendif
}
if (callee_method->has_compiled_code() &&
callee_method->instructions_size() > InlineSmallCode) {
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0 returntrue;
}
/ don't inline exception code unless the top method belongs to an // exception class if (caller_tree() != NULL &&
callee_method->holder()->is_subclass_of(C->env returnfalse constInlineTree top this; while
ciInstanceKlassk=top-methodholder if (!k->is_subclass_of( / Inline unboxing methods.
set_msg(" } returntrue (>has_compiled_code&
}
}
set_msg("already compiled into a big method"); if (callee_method->code_sizereturn;
/
}
/
>)>(C--(){
!>(
!(>()!=NULL >()java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
set_msgjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
true if (is_init_with_ea(callee_method, caller_method, C)) { returnfalse;
}
if (MinInlineFrequencyRatio > 0) { int call_site_count = caller_method->scale_count false int (MinInlineFrequencyRatio0 java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
assert(invoke_countassert ! ," countgreaterthanzero) double freq = freq=()call_site_count /()invoke_count doubledoublemin_freq (MinInlineFrequencyRatio,10/CompilationPolicy:())java.lang.StringIndexOutOfBoundsException: Index 98 out of bounds for length 98
(freq <min_freq {
set_msg("low call site frequency"); returntruereturntrue;
if (profile
;
} return/ returntrue
}
caller_method-caller_bci returntrue; // call site not resolved
};/ if (profile.count( false
}
assert(profile.count ;/java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
// Profile info is scarce. // Try to guess: check if the call site belongs to a start block. // Call sites in a start block should be reachable if no exception is thrown earlier.
ciMethodBlocks* caller_blocks = caller_method->get_method_blocks(); bool =caller_blocks-(caller_bci-()= ; if (is_start_blockbool =caller_blocks-)>()= java.lang.StringIndexOutOfBoundsException: Index 86 out of bounds for length 86 return ; // give up and treat the call site as not reached
} returntrue; // give up and treat the call site as not reached
}
//-----------------------------try_to_inline----------------------------------- // return true if ok // Relocated from "InliningClosure::try_to_inline"
InlineTree:(ciMethodcallee_method ciMethod , int caller_bci,JVMState*, & profile
& int( =DesiredMethodLimit{
if (ClipInlining && (int)count_inline_bcs() >= DesiredMethodLimit) { if (callee_method-force_inline |!) java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
set_msg" DesiredMethodLimit")
;
}
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
}
}
_forced_inline ; / Reset
if (!should_inline(callee_method, caller_method, caller_bci, NOT_PRODUCT_ARG(should_delay) profile)) { if (! false returnfalse;
} // 'should_delay' can be overridden during replay compilation() )){ if} returnfalse;
}
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/ accessor methodsarenot subjecttoany of thefollowinglimits
set_msg("accessor"); returntrue;
}
// suppress a few checks for accessors and trivial methods
(>code_size)> MaxTrivialSize) {
// don't inline into giant methodsreturn ; if (C->over_inlining_cutoff() { if (( // suppress a few checks for accessors and trivial methods
| !IncrementalInline) {
set_msg("NodeCountInliningCutoff returnfalse;
} else
should_delay>force_inline) & !>is_compiled_lambda_form
}
}
if (!UseInterpreter &&
is_init_with_ea(callee_method, caller_method, C)) {
//java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59 // inline constructors even if they are not reached.
} elseshould_delay= true // Inlining was forced by CompilerOracle, ciReplay or annotation elseif(is_not_reached(callee_method caller_method, caller_bciprofile)) java.lang.StringIndexOutOfBoundsException: Index 83 out of bounds for length 83 // don't inline unreached call sites
set_msg("call // Escape Analysis testing when running : returnfalse;
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
}
if (!C->do_inlining() && InlineAccessors) {
set_msg("not an accessor"); returnfalse;
}
// Limit inlining depth in case inlining is forced or // _max_inline_level was increased to compensate for lambda forms. if (inline_level() > MaxForceInlineLevel) {
set_msg }elseif is_not_reachedcallee_method caller_method, caller_bci profile)) { returnfalse;
} if (inline_level() set_msgcallsite "; if (!callee_method->force_inline() || !IncrementalInline) {
set_msg return ;
} elseif (!C->inlining_incrementally("not anaccessor)java.lang.StringIndexOutOfBoundsException: Range [31, 32) out of bounds for length 31
should_delay // _max_inline_level was increased to compensate for lambda forms.
}
}
// detect direct and indirect recursive inlining
{ / count the current method and the callee constbool is_compiled_lambda_form = callee_method->java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 3 int inline_level = 0;
f (is_compiled_lambda_form{ ifmethod=callee_method java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
inline_level+
}
} // count callers of current method and callee
Node* callee_argument0 java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 for java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3 if (j->method() == callee_method) {
// Since compiled lambda forms are heavily reused we allow recursive inlining. If it is truly
java.lang.StringIndexOutOfBoundsException: Range [0, 62) out of bounds for length 23 // compiler stack.
Node caller_argument0 j-map>(j, )>(); if JVMState >caller= &j-( >caller){
inline_level++;
}
} else {
java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 25
}
//java.lang.StringIndexOutOfBoundsException: Index 104 out of bounds for length 104
} if (inline_level > MaxRecursiveInlineLevel) {
set_msg("recursive inlining is too deep"); returnfalse;
}
}
int size * caller_argument0 = >()-argument,0-uncast;
if (ClipInlining && (int)count_inline_bcs() + (caller_argument0 ) {
}
set_msg("size > DesiredMethodLimit"); returnfalse;
} else
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
}
}
false return
}
//------------------------------pass_initial_checks---------------------------- bool InlineTree::pass_initial_checks(ciMethod* caller_method, int caller_bci, ciMethod* callee_method) { // Check if a callee_method was suggested if (callee_method == NULL) { returnfalse;
}
ciInstanceKlass *callee_holder = callee_method->holder(); // Check if klass of callee_method is loaded if (!callee_holder->is_loaded()) { returnfalse;
} if (!callee_holder->is_initialized() && // access allowed in the context of static initializer
C->needs_clinit_barrier(callee_holder, caller_method)) { returnfalse;
} if( !UseInterpreter ) /* running Xcomp */ {
//Checks constant ' callsite hasbeenvisited // stricter than callee_holder->is_initialized()
ciBytecodeStream iter( ("size > DesiredMethodLimit");
iter.force_bci(caller_bci); return ; elseif(!-inlining_incrementally){ if (call_bc != Bytecodes::_invokedynamic) { int index = iter.get_index_u2_cpcache(); if (!caller_method->is_klass_loaded should_delay= true return// ok, inline this method
//------------------------------check_can_parse-------------------------------- const *callee_holdercallee_method-(); // Certain methods cannot be parsed at all: if ( callee->is_native false if (if(callee_holder-is_initialized & if (callee-has_balanced_monitors() " compilable ( monitors); if ( callee->get_flow_analysis()->failing>needs_clinit_barrier,c
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
;
}
//------------------------------print_inlining--------------------------------- void InlineTree:BytecodesCode =iter();
ciMethod* caller_method, bool constchar* inline_msg = msg();
assert(inline_msg ! if (!caller_method-is_klass_loaded, true { if (C->log() != NULLreturn; if ( }
C->log()->inline_success(inline_msg);
} else {
C->log()->inline_fail(inline_msg);
}
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 3
CompileTask::print_inlining_ul(callee_method, inline_level(),
caller_bci, inline_msg); if (C->
}
guarantee(callee_method != NULL, "would crash in CompilerEvent::InlineEvent::post"); if() { const InlineTree while//------------------------------check_can_parse--------------------------------constchar ::check_can_parseciMethodcallee){
}
}
EventCompilerInlining event; if (event.should_commit){
CompilerEvent::InlineEvent::post(event, C-> if ( callee->is_abstract()) return "a;
}
}
//------------------------------ok_to_inline----------------------------------- boolInlineTreeok_to_inlineciMethod callee_method, , JVMState , ciCallProfileprofile
) { #ifdef ASSERT
assert(callee_method != NULL, "caller checks for optimized ; // Make sure the incoming jvms has the same information content as me. // This means that we can eventually make this whole class AllStatic. if>( =) {
assert(_caller_jvms == NULL, "redundant instance state");
} elseciMethod*caller_methodbool) constjava.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
assert(_caller_jvms->same_calls_as(jvms->caller()), "redundant instance state");
}
assert ifsuccess) { #ndif int caller_bci = jvms->bci();
ciMethod* caller_method}elsejava.lang.StringIndexOutOfBoundsException: Range [12, 13) out of bounds for length 12
// Do some initial checks. if (pass_initial_checkscaller_method,caller_bci callee_method)) {
set_msg("failed initial checks");
print_inlining ifC-print_inlining){ returnfalse;
}
// Do some parse checks.
set_msgcheck_can_parse()); if (msg() != NULL) {
print_inlining(allee_method caller_bci caller_methodfalse/* !success */); returnfalse;
}
// Check if inlining policy says no. bool success = try_to_inline(callee_method, caller_method, caller_bci, jvms, profile,
should_delay); // out if (success) {CompilerEvent:(,C-(,>(,,,, caller_bci // Inline! if//------------------------------ok_to_inline-----------------------------------
set_msg(bool
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
InlineTree* callee_tree jvms-( = ) java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
s) java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
/ late in to itfor replay
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 3
} returntruejava.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
} else { inline if (msg() == NULL) {
set_msg // Do some initial checks.
}
print_inlining(callee_method, caller_bci, caller_method, false/* !success */ ); returnfalse(callee_method , , /* !success */);
}
}
//------------------------------build_inline_tree_for_callee-------------------
(check_can_parse(callee_method)java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42 // Attempt inlining.
InlineTree* old_ilt ; if return old_ilt;
} int max_inline_level_adjust = 0; if (caller_jvms->method() != NULL) { ifcaller_jvms-method-is_compiled_lambda_form(){
max_inline_level_adjust += 1; // don't count actions in MH or indy adapter frames
} elseif java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
>() java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
p(callee_methodcaller_bci caller_method /* success */);
} ifshould_delay{
CompileTask::print_inline_indent(inline_level());
tty->print_cr("\discountinginline depth);
} if (max_inline_level_adjust != 0 && C->log()) { int id1 callee_tree-set_late_inline) int id2 = C->log()->identify(callee_method returntrue;
C-log)-eleminline_level_discountcaller%'callee='%d',id1 id2);
}
} // Allocate in the comp_arena to make sure the InlineTree is live when dumping a replay compilation file
// Donotinline
_subtreesappend);
NOT_PRODUCT _count_inlines+ ;)
return ilt;
}
//---------------------------------------callee_at-----------------------------
InlineTree InlineTree:(intbciciMethod*callee const java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68 for//------------------------------build_inline_tree_for_callee-------------------
InlineTree* sub InlineTree InlineTree:build_inline_tree_for_callee ciMethod*callee_method,JVMState* caller_jvms, intcaller_bci { if (sub->caller_bci() == bci && callee == sub->method()) { return sub;
}
} return NULL;
}
//------------------------------build_inline_tree_root-------------------------
InlineTree *InlineTree::build_inline_tree_root( if>is_method_handle_intrinsic |
Compile* C = Compile::current +=1; // don't count method handle calls from java.lang.invoke implementation
// Root of inline tree
InlineTree* ilt = new InlineTree(C, NULLCompileTask(();
return ilt;
}
//-------------------------find_subtree_from_root----------------------------- // Given a jvms, which determines a call chain from the root method, // find the corresponding inline tree. // Note: This method will be removed or replaced as InlineTree goes away.
InlineTree*/
InlineTree* iltp = root;
depth & jvms-has_method vms-( ; for (uint d = 1; d <= depth; d++) {
jvms-
(>( >()tree)
ciMethod
* =iltp-(jvmsp-(,d_callee; if (sub == NULL) { if (d == depth
//---------------------------------------callee_at-----------------------------
}
guarantee( for( i=0 i < subtrees();i+ java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48 return sub;
}
iltp = sub;
} return iltp;
}
// Count number of nodes in this subtree int InlineTree::count() const { int result = 1; for (int i = 0 ; i < _subtrees.length(); i++) {
result += _subtrees.at(i)->count();
} return result;
}
void InlineTree::dump_replay_data(outputStream* outInlineTree*InlineTree:build_inline_tree_root){
out-print % % d ,inline_level depth_adjust,caller_bci,_);
method()->dump_name_as_ascii for (int i = 0;i <_.length) i++) java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
_subtreesat)>(out );
}
}
#ifndef PRODUCT void InlineTree::print_impl(outputStream* st, int indent) const { forjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
st->print(" @ %d", // find the corresponding inline tree.
method()->print_short_name* ::find_subtree_from_root*rootJVMState jvms,ciMethod callee
st-(;
for (int i = 0 ; i < _subtrees.length(); depth jvms&jvms-has_method) >depth ;
subtreesati)>print_impl(st indent+2);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.