提交 11d5fcaf 编写于 作者: N never

7057587: JSR 292 - crash with jruby in test/test_respond_to.rb

Summary: don't skip receiver when GC'ing compiled invokedynamic callsites
Reviewed-by: twisti, kvn, jrose
上级 d9b5f39e
...@@ -1832,7 +1832,9 @@ void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map ...@@ -1832,7 +1832,9 @@ void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map
if (!method()->is_native()) { if (!method()->is_native()) {
SimpleScopeDesc ssd(this, fr.pc()); SimpleScopeDesc ssd(this, fr.pc());
Bytecode_invoke call(ssd.method(), ssd.bci()); Bytecode_invoke call(ssd.method(), ssd.bci());
bool has_receiver = call.has_receiver(); // compiled invokedynamic call sites have an implicit receiver at
// resolution time, so make sure it gets GC'ed.
bool has_receiver = !call.is_invokestatic();
Symbol* signature = call.signature(); Symbol* signature = call.signature();
fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f); fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
} }
......
...@@ -35,14 +35,16 @@ ...@@ -35,14 +35,16 @@
//============================================================================= //=============================================================================
//------------------------------InlineTree------------------------------------- //------------------------------InlineTree-------------------------------------
InlineTree::InlineTree( Compile* c, InlineTree::InlineTree(Compile* c,
const InlineTree *caller_tree, ciMethod* callee, const InlineTree *caller_tree, ciMethod* callee,
JVMState* caller_jvms, int caller_bci, JVMState* caller_jvms, int caller_bci,
float site_invoke_ratio, int site_depth_adjust) float site_invoke_ratio, int max_inline_level) :
: C(c), _caller_jvms(caller_jvms), C(c),
_caller_tree((InlineTree*)caller_tree), _caller_jvms(caller_jvms),
_method(callee), _site_invoke_ratio(site_invoke_ratio), _caller_tree((InlineTree*) caller_tree),
_site_depth_adjust(site_depth_adjust), _method(callee),
_site_invoke_ratio(site_invoke_ratio),
_max_inline_level(max_inline_level),
_count_inline_bcs(method()->code_size()) _count_inline_bcs(method()->code_size())
{ {
NOT_PRODUCT(_count_inlines = 0;) NOT_PRODUCT(_count_inlines = 0;)
...@@ -66,10 +68,13 @@ InlineTree::InlineTree( Compile* c, ...@@ -66,10 +68,13 @@ InlineTree::InlineTree( Compile* c,
} }
InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms,
float site_invoke_ratio, int site_depth_adjust) float site_invoke_ratio, int max_inline_level) :
: C(c), _caller_jvms(caller_jvms), _caller_tree(NULL), C(c),
_method(callee_method), _site_invoke_ratio(site_invoke_ratio), _caller_jvms(caller_jvms),
_site_depth_adjust(site_depth_adjust), _caller_tree(NULL),
_method(callee_method),
_site_invoke_ratio(site_invoke_ratio),
_max_inline_level(max_inline_level),
_count_inline_bcs(method()->code_size()) _count_inline_bcs(method()->code_size())
{ {
NOT_PRODUCT(_count_inlines = 0;) NOT_PRODUCT(_count_inlines = 0;)
...@@ -94,7 +99,7 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_ ...@@ -94,7 +99,7 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_
if(callee_method->should_inline()) { if(callee_method->should_inline()) {
*wci_result = *(WarmCallInfo::always_hot()); *wci_result = *(WarmCallInfo::always_hot());
if (PrintInlining && Verbose) { if (PrintInlining && Verbose) {
CompileTask::print_inline_indent(inline_depth()); CompileTask::print_inline_indent(inline_level());
tty->print_cr("Inlined method is hot: "); tty->print_cr("Inlined method is hot: ");
} }
return NULL; return NULL;
...@@ -109,7 +114,7 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_ ...@@ -109,7 +114,7 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_
size < InlineThrowMaxSize ) { size < InlineThrowMaxSize ) {
wci_result->set_profit(wci_result->profit() * 100); wci_result->set_profit(wci_result->profit() * 100);
if (PrintInlining && Verbose) { if (PrintInlining && Verbose) {
CompileTask::print_inline_indent(inline_depth()); CompileTask::print_inline_indent(inline_level());
tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count());
} }
return NULL; return NULL;
...@@ -149,9 +154,9 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_ ...@@ -149,9 +154,9 @@ const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_
max_inline_size = C->freq_inline_size(); max_inline_size = C->freq_inline_size();
if (size <= max_inline_size && TraceFrequencyInlining) { if (size <= max_inline_size && TraceFrequencyInlining) {
CompileTask::print_inline_indent(inline_depth()); CompileTask::print_inline_indent(inline_level());
tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count); tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count);
CompileTask::print_inline_indent(inline_depth()); CompileTask::print_inline_indent(inline_level());
callee_method->print(); callee_method->print();
tty->cr(); tty->cr();
} }
...@@ -322,7 +327,7 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_ ...@@ -322,7 +327,7 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_
if (!C->do_inlining() && InlineAccessors) { if (!C->do_inlining() && InlineAccessors) {
return "not an accessor"; return "not an accessor";
} }
if( inline_depth() > MaxInlineLevel ) { if (inline_level() > _max_inline_level) {
return "inlining too deep"; return "inlining too deep";
} }
...@@ -392,7 +397,7 @@ bool pass_initial_checks(ciMethod* caller_method, int caller_bci, ciMethod* call ...@@ -392,7 +397,7 @@ bool pass_initial_checks(ciMethod* caller_method, int caller_bci, ciMethod* call
//------------------------------print_inlining--------------------------------- //------------------------------print_inlining---------------------------------
// Really, the failure_msg can be a success message also. // Really, the failure_msg can be a success message also.
void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const char* failure_msg) const { void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const char* failure_msg) const {
CompileTask::print_inlining(callee_method, inline_depth(), caller_bci, failure_msg ? failure_msg : "inline"); CompileTask::print_inlining(callee_method, inline_level(), caller_bci, failure_msg ? failure_msg : "inline");
if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); if (callee_method == NULL) tty->print(" callee not monotonic or profiled");
if (Verbose && callee_method) { if (Verbose && callee_method) {
const InlineTree *top = this; const InlineTree *top = this;
...@@ -500,25 +505,25 @@ InlineTree *InlineTree::build_inline_tree_for_callee( ciMethod* callee_method, J ...@@ -500,25 +505,25 @@ InlineTree *InlineTree::build_inline_tree_for_callee( ciMethod* callee_method, J
if (old_ilt != NULL) { if (old_ilt != NULL) {
return old_ilt; return old_ilt;
} }
int new_depth_adjust = 0; int max_inline_level_adjust = 0;
if (caller_jvms->method() != NULL) { if (caller_jvms->method() != NULL) {
if (caller_jvms->method()->is_method_handle_adapter()) if (caller_jvms->method()->is_method_handle_adapter())
new_depth_adjust -= 1; // don't count actions in MH or indy adapter frames max_inline_level_adjust += 1; // don't count actions in MH or indy adapter frames
else if (callee_method->is_method_handle_invoke()) { else if (callee_method->is_method_handle_invoke()) {
new_depth_adjust -= 1; // don't count method handle calls from java.lang.invoke implem max_inline_level_adjust += 1; // don't count method handle calls from java.lang.invoke implem
} }
if (new_depth_adjust != 0 && PrintInlining) { if (max_inline_level_adjust != 0 && PrintInlining && (Verbose || WizardMode)) {
CompileTask::print_inline_indent(inline_depth()); CompileTask::print_inline_indent(inline_level());
tty->print_cr(" \\-> discounting inline depth"); tty->print_cr(" \\-> discounting inline depth");
} }
if (new_depth_adjust != 0 && C->log()) { if (max_inline_level_adjust != 0 && C->log()) {
int id1 = C->log()->identify(caller_jvms->method()); int id1 = C->log()->identify(caller_jvms->method());
int id2 = C->log()->identify(callee_method); int id2 = C->log()->identify(callee_method);
C->log()->elem("inline_depth_discount caller='%d' callee='%d'", id1, id2); C->log()->elem("inline_level_discount caller='%d' callee='%d'", id1, id2);
} }
} }
InlineTree *ilt = new InlineTree(C, this, callee_method, caller_jvms, caller_bci, recur_frequency, _site_depth_adjust + new_depth_adjust); InlineTree* ilt = new InlineTree(C, this, callee_method, caller_jvms, caller_bci, recur_frequency, _max_inline_level + max_inline_level_adjust);
_subtrees.append( ilt ); _subtrees.append(ilt);
NOT_PRODUCT( _count_inlines += 1; ) NOT_PRODUCT( _count_inlines += 1; )
...@@ -543,7 +548,7 @@ InlineTree *InlineTree::build_inline_tree_root() { ...@@ -543,7 +548,7 @@ InlineTree *InlineTree::build_inline_tree_root() {
Compile* C = Compile::current(); Compile* C = Compile::current();
// Root of inline tree // Root of inline tree
InlineTree *ilt = new InlineTree(C, NULL, C->method(), NULL, -1, 1.0F, 0); InlineTree* ilt = new InlineTree(C, NULL, C->method(), NULL, -1, 1.0F, MaxInlineLevel);
return ilt; return ilt;
} }
......
...@@ -183,7 +183,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, ...@@ -183,7 +183,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
// TO DO: When UseOldInlining is removed, copy the ILT code elsewhere. // TO DO: When UseOldInlining is removed, copy the ILT code elsewhere.
float site_invoke_ratio = prof_factor; float site_invoke_ratio = prof_factor;
// Note: ilt is for the root of this parse, not the present call site. // Note: ilt is for the root of this parse, not the present call site.
ilt = new InlineTree(this, jvms->method(), jvms->caller(), site_invoke_ratio, 0); ilt = new InlineTree(this, jvms->method(), jvms->caller(), site_invoke_ratio, MaxInlineLevel);
} }
WarmCallInfo scratch_ci; WarmCallInfo scratch_ci;
if (!UseOldInlining) if (!UseOldInlining)
......
...@@ -50,7 +50,7 @@ class InlineTree : public ResourceObj { ...@@ -50,7 +50,7 @@ class InlineTree : public ResourceObj {
// Always between 0.0 and 1.0. Represents the percentage of the method's // Always between 0.0 and 1.0. Represents the percentage of the method's
// total execution time used at this call site. // total execution time used at this call site.
const float _site_invoke_ratio; const float _site_invoke_ratio;
const int _site_depth_adjust; const int _max_inline_level; // the maximum inline level for this sub-tree (may be adjusted)
float compute_callee_frequency( int caller_bci ) const; float compute_callee_frequency( int caller_bci ) const;
GrowableArray<InlineTree*> _subtrees; GrowableArray<InlineTree*> _subtrees;
...@@ -63,7 +63,7 @@ protected: ...@@ -63,7 +63,7 @@ protected:
JVMState* caller_jvms, JVMState* caller_jvms,
int caller_bci, int caller_bci,
float site_invoke_ratio, float site_invoke_ratio,
int site_depth_adjust); int max_inline_level);
InlineTree *build_inline_tree_for_callee(ciMethod* callee_method, InlineTree *build_inline_tree_for_callee(ciMethod* callee_method,
JVMState* caller_jvms, JVMState* caller_jvms,
int caller_bci); int caller_bci);
...@@ -74,7 +74,7 @@ protected: ...@@ -74,7 +74,7 @@ protected:
InlineTree *caller_tree() const { return _caller_tree; } InlineTree *caller_tree() const { return _caller_tree; }
InlineTree* callee_at(int bci, ciMethod* m) const; InlineTree* callee_at(int bci, ciMethod* m) const;
int inline_depth() const { return stack_depth() + _site_depth_adjust; } int inline_level() const { return stack_depth(); }
int stack_depth() const { return _caller_jvms ? _caller_jvms->depth() : 0; } int stack_depth() const { return _caller_jvms ? _caller_jvms->depth() : 0; }
public: public:
...@@ -82,7 +82,7 @@ public: ...@@ -82,7 +82,7 @@ public:
static InlineTree* find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee, bool create_if_not_found = false); static InlineTree* find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee, bool create_if_not_found = false);
// For temporary (stack-allocated, stateless) ilts: // For temporary (stack-allocated, stateless) ilts:
InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, float site_invoke_ratio, int site_depth_adjust); InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, float site_invoke_ratio, int max_inline_level);
// InlineTree enum // InlineTree enum
enum InlineStyle { enum InlineStyle {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册