mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
7042122: JSR 292: adjust various inline thresholds for JSR 292 API methods and method handle adapters
Reviewed-by: jrose, never, kvn
This commit is contained in:
parent
42e49be1bc
commit
fee8d7fca4
7 changed files with 95 additions and 51 deletions
|
@ -42,7 +42,7 @@ ciMethod* ciMethodHandle::get_adapter(bool is_invokedynamic) const {
|
||||||
methodHandle callee(_callee->get_methodOop());
|
methodHandle callee(_callee->get_methodOop());
|
||||||
// We catch all exceptions here that could happen in the method
|
// We catch all exceptions here that could happen in the method
|
||||||
// handle compiler and stop the VM.
|
// handle compiler and stop the VM.
|
||||||
MethodHandleCompiler mhc(h, callee, is_invokedynamic, THREAD);
|
MethodHandleCompiler mhc(h, callee, call_profile()->count(), is_invokedynamic, THREAD);
|
||||||
if (!HAS_PENDING_EXCEPTION) {
|
if (!HAS_PENDING_EXCEPTION) {
|
||||||
methodHandle m = mhc.compile(THREAD);
|
methodHandle m = mhc.compile(THREAD);
|
||||||
if (!HAS_PENDING_EXCEPTION) {
|
if (!HAS_PENDING_EXCEPTION) {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#ifndef SHARE_VM_CI_CIMETHODHANDLE_HPP
|
#ifndef SHARE_VM_CI_CIMETHODHANDLE_HPP
|
||||||
#define SHARE_VM_CI_CIMETHODHANDLE_HPP
|
#define SHARE_VM_CI_CIMETHODHANDLE_HPP
|
||||||
|
|
||||||
|
#include "ci/ciCallProfile.hpp"
|
||||||
#include "ci/ciInstance.hpp"
|
#include "ci/ciInstance.hpp"
|
||||||
#include "prims/methodHandles.hpp"
|
#include "prims/methodHandles.hpp"
|
||||||
|
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
class ciMethodHandle : public ciInstance {
|
class ciMethodHandle : public ciInstance {
|
||||||
private:
|
private:
|
||||||
ciMethod* _callee;
|
ciMethod* _callee;
|
||||||
|
ciCallProfile* _profile;
|
||||||
|
|
||||||
// Return an adapter for this MethodHandle.
|
// Return an adapter for this MethodHandle.
|
||||||
ciMethod* get_adapter(bool is_invokedynamic) const;
|
ciMethod* get_adapter(bool is_invokedynamic) const;
|
||||||
|
@ -50,6 +52,9 @@ public:
|
||||||
ciMethod* callee() const { return _callee; }
|
ciMethod* callee() const { return _callee; }
|
||||||
void set_callee(ciMethod* m) { _callee = m; }
|
void set_callee(ciMethod* m) { _callee = m; }
|
||||||
|
|
||||||
|
ciCallProfile* call_profile() const { return _profile; }
|
||||||
|
void set_call_profile(ciCallProfile* profile) { _profile = profile; }
|
||||||
|
|
||||||
// Return an adapter for a MethodHandle call.
|
// Return an adapter for a MethodHandle call.
|
||||||
ciMethod* get_method_handle_adapter() const {
|
ciMethod* get_method_handle_adapter() const {
|
||||||
return get_adapter(false);
|
return get_adapter(false);
|
||||||
|
|
|
@ -89,7 +89,7 @@ static bool is_init_with_ea(ciMethod* callee_method,
|
||||||
}
|
}
|
||||||
|
|
||||||
// positive filter: should send be inlined? returns NULL, if yes, or rejection msg
|
// positive filter: should send be inlined? returns NULL, if yes, or rejection msg
|
||||||
const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const {
|
const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const {
|
||||||
// Allows targeted inlining
|
// Allows targeted inlining
|
||||||
if(callee_method->should_inline()) {
|
if(callee_method->should_inline()) {
|
||||||
*wci_result = *(WarmCallInfo::always_hot());
|
*wci_result = *(WarmCallInfo::always_hot());
|
||||||
|
@ -102,7 +102,6 @@ const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_m
|
||||||
|
|
||||||
// positive filter: should send be inlined? returns NULL (--> yes)
|
// positive filter: should send be inlined? returns NULL (--> yes)
|
||||||
// or rejection msg
|
// or rejection msg
|
||||||
int max_size = C->max_inline_size();
|
|
||||||
int size = callee_method->code_size();
|
int size = callee_method->code_size();
|
||||||
|
|
||||||
// Check for too many throws (and not too huge)
|
// Check for too many throws (and not too huge)
|
||||||
|
@ -120,18 +119,36 @@ const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_m
|
||||||
return NULL; // size and frequency are represented in a new way
|
return NULL; // size and frequency are represented in a new way
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int default_max_inline_size = C->max_inline_size();
|
||||||
|
int inline_small_code_size = InlineSmallCode / 4;
|
||||||
|
int max_inline_size = default_max_inline_size;
|
||||||
|
|
||||||
int call_site_count = method()->scale_count(profile.count());
|
int call_site_count = method()->scale_count(profile.count());
|
||||||
int invoke_count = method()->interpreter_invocation_count();
|
int invoke_count = method()->interpreter_invocation_count();
|
||||||
assert( invoke_count != 0, "Require invokation count greater than zero");
|
|
||||||
int freq = call_site_count/invoke_count;
|
// Bytecoded method handle adapters do not have interpreter
|
||||||
|
// profiling data but only made up MDO data. Get the counter from
|
||||||
|
// there.
|
||||||
|
if (caller_method->is_method_handle_adapter()) {
|
||||||
|
assert(method()->method_data_or_null(), "must have an MDO");
|
||||||
|
ciMethodData* mdo = method()->method_data();
|
||||||
|
ciProfileData* mha_profile = mdo->bci_to_data(caller_bci);
|
||||||
|
assert(mha_profile, "must exist");
|
||||||
|
CounterData* cd = mha_profile->as_CounterData();
|
||||||
|
invoke_count = cd->count();
|
||||||
|
call_site_count = invoke_count; // use the same value
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(invoke_count != 0, "require invocation count greater than zero");
|
||||||
|
int freq = call_site_count / invoke_count;
|
||||||
|
|
||||||
// bump the max size if the call is frequent
|
// bump the max size if the call is frequent
|
||||||
if ((freq >= InlineFrequencyRatio) ||
|
if ((freq >= InlineFrequencyRatio) ||
|
||||||
(call_site_count >= InlineFrequencyCount) ||
|
(call_site_count >= InlineFrequencyCount) ||
|
||||||
is_init_with_ea(callee_method, caller_method, C)) {
|
is_init_with_ea(callee_method, caller_method, C)) {
|
||||||
|
|
||||||
max_size = C->freq_inline_size();
|
max_inline_size = C->freq_inline_size();
|
||||||
if (size <= max_size && TraceFrequencyInlining) {
|
if (size <= max_inline_size && TraceFrequencyInlining) {
|
||||||
CompileTask::print_inline_indent(inline_depth());
|
CompileTask::print_inline_indent(inline_depth());
|
||||||
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_depth());
|
||||||
|
@ -141,11 +158,11 @@ const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_m
|
||||||
} else {
|
} else {
|
||||||
// Not hot. Check for medium-sized pre-existing nmethod at cold sites.
|
// Not hot. Check for medium-sized pre-existing nmethod at cold sites.
|
||||||
if (callee_method->has_compiled_code() &&
|
if (callee_method->has_compiled_code() &&
|
||||||
callee_method->instructions_size(CompLevel_full_optimization) > InlineSmallCode/4)
|
callee_method->instructions_size(CompLevel_full_optimization) > inline_small_code_size)
|
||||||
return "already compiled into a medium method";
|
return "already compiled into a medium method";
|
||||||
}
|
}
|
||||||
if (size > max_size) {
|
if (size > max_inline_size) {
|
||||||
if (max_size > C->max_inline_size())
|
if (max_inline_size > default_max_inline_size)
|
||||||
return "hot method too big";
|
return "hot method too big";
|
||||||
return "too big";
|
return "too big";
|
||||||
}
|
}
|
||||||
|
@ -154,7 +171,7 @@ const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_m
|
||||||
|
|
||||||
|
|
||||||
// negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg
|
// negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg
|
||||||
const char* InlineTree::shouldNotInline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const {
|
const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const {
|
||||||
// negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
|
// negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
|
||||||
if (!UseOldInlining) {
|
if (!UseOldInlining) {
|
||||||
const char* fail = NULL;
|
const char* fail = NULL;
|
||||||
|
@ -269,14 +286,13 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *msg = NULL;
|
const char *msg = NULL;
|
||||||
if ((msg = shouldInline(callee_method, caller_method, caller_bci,
|
msg = should_inline(callee_method, caller_method, caller_bci, profile, wci_result);
|
||||||
profile, wci_result)) != NULL) {
|
if (msg != NULL)
|
||||||
return msg;
|
return msg;
|
||||||
}
|
|
||||||
if ((msg = shouldNotInline(callee_method, caller_method,
|
msg = should_not_inline(callee_method, caller_method, wci_result);
|
||||||
wci_result)) != NULL) {
|
if (msg != NULL)
|
||||||
return msg;
|
return msg;
|
||||||
}
|
|
||||||
|
|
||||||
if (InlineAccessors && callee_method->is_accessor()) {
|
if (InlineAccessors && callee_method->is_accessor()) {
|
||||||
// accessor methods are not subject to any of the following limits.
|
// accessor methods are not subject to any of the following limits.
|
||||||
|
@ -492,9 +508,8 @@ InlineTree *InlineTree::build_inline_tree_for_callee( ciMethod* callee_method, J
|
||||||
new_depth_adjust -= 1; // don't count method handle calls from java.lang.invoke implem
|
new_depth_adjust -= 1; // don't count method handle calls from java.lang.invoke implem
|
||||||
}
|
}
|
||||||
if (new_depth_adjust != 0 && PrintInlining) {
|
if (new_depth_adjust != 0 && PrintInlining) {
|
||||||
stringStream nm1; caller_jvms->method()->print_name(&nm1);
|
CompileTask::print_inline_indent(inline_depth());
|
||||||
stringStream nm2; callee_method->print_name(&nm2);
|
tty->print_cr(" \\-> discounting inline depth");
|
||||||
tty->print_cr("discounting inlining depth from %s to %s", nm1.base(), nm2.base());
|
|
||||||
}
|
}
|
||||||
if (new_depth_adjust != 0 && C->log()) {
|
if (new_depth_adjust != 0 && C->log()) {
|
||||||
int id1 = C->log()->identify(caller_jvms->method());
|
int id1 = C->log()->identify(caller_jvms->method());
|
||||||
|
|
|
@ -74,6 +74,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
|
||||||
// from more specific profile data which pertains to this inlining.
|
// from more specific profile data which pertains to this inlining.
|
||||||
// Right now, ignore the information in jvms->caller(), and do method[bci].
|
// Right now, ignore the information in jvms->caller(), and do method[bci].
|
||||||
ciCallProfile profile = jvms->method()->call_profile_at_bci(jvms->bci());
|
ciCallProfile profile = jvms->method()->call_profile_at_bci(jvms->bci());
|
||||||
|
Bytecodes::Code bytecode = jvms->method()->java_code_at_bci(jvms->bci());
|
||||||
|
|
||||||
// See how many times this site has been invoked.
|
// See how many times this site has been invoked.
|
||||||
int site_count = profile.count();
|
int site_count = profile.count();
|
||||||
|
@ -116,7 +117,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
|
||||||
// MethodHandle.invoke* are native methods which obviously don't
|
// MethodHandle.invoke* are native methods which obviously don't
|
||||||
// have bytecodes and so normal inlining fails.
|
// have bytecodes and so normal inlining fails.
|
||||||
if (call_method->is_method_handle_invoke()) {
|
if (call_method->is_method_handle_invoke()) {
|
||||||
if (jvms->method()->java_code_at_bci(jvms->bci()) != Bytecodes::_invokedynamic) {
|
if (bytecode != Bytecodes::_invokedynamic) {
|
||||||
GraphKit kit(jvms);
|
GraphKit kit(jvms);
|
||||||
Node* n = kit.argument(0);
|
Node* n = kit.argument(0);
|
||||||
|
|
||||||
|
@ -128,15 +129,16 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
|
||||||
// Set the actually called method to have access to the class
|
// Set the actually called method to have access to the class
|
||||||
// and signature in the MethodHandleCompiler.
|
// and signature in the MethodHandleCompiler.
|
||||||
method_handle->set_callee(call_method);
|
method_handle->set_callee(call_method);
|
||||||
|
method_handle->set_call_profile(&profile);
|
||||||
|
|
||||||
// Get an adapter for the MethodHandle.
|
// Get an adapter for the MethodHandle.
|
||||||
ciMethod* target_method = method_handle->get_method_handle_adapter();
|
ciMethod* target_method = method_handle->get_method_handle_adapter();
|
||||||
CallGenerator* hit_cg = NULL;
|
if (target_method != NULL) {
|
||||||
if (target_method != NULL)
|
CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
|
||||||
hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
|
|
||||||
if (hit_cg != NULL && hit_cg->is_inline())
|
if (hit_cg != NULL && hit_cg->is_inline())
|
||||||
return hit_cg;
|
return hit_cg;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return CallGenerator::for_direct_call(call_method);
|
return CallGenerator::for_direct_call(call_method);
|
||||||
}
|
}
|
||||||
|
@ -151,16 +153,17 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
|
||||||
// Set the actually called method to have access to the class
|
// Set the actually called method to have access to the class
|
||||||
// and signature in the MethodHandleCompiler.
|
// and signature in the MethodHandleCompiler.
|
||||||
method_handle->set_callee(call_method);
|
method_handle->set_callee(call_method);
|
||||||
|
method_handle->set_call_profile(&profile);
|
||||||
|
|
||||||
// Get an adapter for the MethodHandle.
|
// Get an adapter for the MethodHandle.
|
||||||
ciMethod* target_method = method_handle->get_invokedynamic_adapter();
|
ciMethod* target_method = method_handle->get_invokedynamic_adapter();
|
||||||
CallGenerator* hit_cg = NULL;
|
if (target_method != NULL) {
|
||||||
if (target_method != NULL)
|
CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
|
||||||
hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor);
|
|
||||||
if (hit_cg != NULL && hit_cg->is_inline()) {
|
if (hit_cg != NULL && hit_cg->is_inline()) {
|
||||||
CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method);
|
CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method);
|
||||||
return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor);
|
return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If something failed, generate a normal dynamic call.
|
// If something failed, generate a normal dynamic call.
|
||||||
return CallGenerator::for_dynamic_call(call_method);
|
return CallGenerator::for_dynamic_call(call_method);
|
||||||
|
|
|
@ -68,8 +68,8 @@ protected:
|
||||||
JVMState* caller_jvms,
|
JVMState* caller_jvms,
|
||||||
int caller_bci);
|
int caller_bci);
|
||||||
const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result);
|
const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result);
|
||||||
const char* shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const;
|
const char* should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const;
|
||||||
const char* shouldNotInline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const;
|
const char* should_not_inline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const;
|
||||||
void print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const;
|
void print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const;
|
||||||
|
|
||||||
InlineTree *caller_tree() const { return _caller_tree; }
|
InlineTree *caller_tree() const { return _caller_tree; }
|
||||||
|
|
|
@ -616,9 +616,10 @@ int MethodHandleWalker::argument_count_slow() {
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// MethodHandleCompiler
|
// MethodHandleCompiler
|
||||||
|
|
||||||
MethodHandleCompiler::MethodHandleCompiler(Handle root, methodHandle callee, bool is_invokedynamic, TRAPS)
|
MethodHandleCompiler::MethodHandleCompiler(Handle root, methodHandle callee, int invoke_count, bool is_invokedynamic, TRAPS)
|
||||||
: MethodHandleWalker(root, is_invokedynamic, THREAD),
|
: MethodHandleWalker(root, is_invokedynamic, THREAD),
|
||||||
_callee(callee),
|
_callee(callee),
|
||||||
|
_invoke_count(invoke_count),
|
||||||
_thread(THREAD),
|
_thread(THREAD),
|
||||||
_bytecode(THREAD, 50),
|
_bytecode(THREAD, 50),
|
||||||
_constants(THREAD, 10),
|
_constants(THREAD, 10),
|
||||||
|
@ -1182,7 +1183,7 @@ constantPoolHandle MethodHandleCompiler::get_constant_pool(TRAPS) const {
|
||||||
|
|
||||||
|
|
||||||
methodHandle MethodHandleCompiler::get_method_oop(TRAPS) const {
|
methodHandle MethodHandleCompiler::get_method_oop(TRAPS) const {
|
||||||
methodHandle nullHandle;
|
methodHandle empty;
|
||||||
// Create a method that holds the generated bytecode. invokedynamic
|
// Create a method that holds the generated bytecode. invokedynamic
|
||||||
// has no receiver, normal MH calls do.
|
// has no receiver, normal MH calls do.
|
||||||
int flags_bits;
|
int flags_bits;
|
||||||
|
@ -1191,13 +1192,16 @@ methodHandle MethodHandleCompiler::get_method_oop(TRAPS) const {
|
||||||
else
|
else
|
||||||
flags_bits = (/*JVM_MH_INVOKE_BITS |*/ JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_SYNTHETIC);
|
flags_bits = (/*JVM_MH_INVOKE_BITS |*/ JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_SYNTHETIC);
|
||||||
|
|
||||||
|
// Create a new method
|
||||||
|
methodHandle m;
|
||||||
|
{
|
||||||
methodOop m_oop = oopFactory::new_method(bytecode_length(),
|
methodOop m_oop = oopFactory::new_method(bytecode_length(),
|
||||||
accessFlags_from(flags_bits),
|
accessFlags_from(flags_bits),
|
||||||
0, 0, 0, oopDesc::IsSafeConc, CHECK_(nullHandle));
|
0, 0, 0, oopDesc::IsSafeConc, CHECK_(empty));
|
||||||
methodHandle m(THREAD, m_oop);
|
m = methodHandle(THREAD, m_oop);
|
||||||
m_oop = NULL; // oop not GC safe
|
}
|
||||||
|
|
||||||
constantPoolHandle cpool = get_constant_pool(CHECK_(nullHandle));
|
constantPoolHandle cpool = get_constant_pool(CHECK_(empty));
|
||||||
m->set_constants(cpool());
|
m->set_constants(cpool());
|
||||||
|
|
||||||
m->set_name_index(_name_index);
|
m->set_name_index(_name_index);
|
||||||
|
@ -1212,16 +1216,32 @@ methodHandle MethodHandleCompiler::get_method_oop(TRAPS) const {
|
||||||
typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
|
typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
|
||||||
m->set_exception_table(exception_handlers());
|
m->set_exception_table(exception_handlers());
|
||||||
|
|
||||||
// Set the carry bit of the invocation counter to force inlining of
|
// Set the invocation counter's count to the invoke count of the
|
||||||
// the adapter.
|
// original call site.
|
||||||
InvocationCounter* ic = m->invocation_counter();
|
InvocationCounter* ic = m->invocation_counter();
|
||||||
ic->set_carry_flag();
|
ic->set(InvocationCounter::wait_for_compile, _invoke_count);
|
||||||
|
|
||||||
// Rewrite the method and set up the constant pool cache.
|
// Rewrite the method and set up the constant pool cache.
|
||||||
objArrayOop m_array = oopFactory::new_system_objArray(1, CHECK_(nullHandle));
|
objArrayOop m_array = oopFactory::new_system_objArray(1, CHECK_(empty));
|
||||||
objArrayHandle methods(THREAD, m_array);
|
objArrayHandle methods(THREAD, m_array);
|
||||||
methods->obj_at_put(0, m());
|
methods->obj_at_put(0, m());
|
||||||
Rewriter::rewrite(_target_klass(), cpool, methods, CHECK_(nullHandle)); // Use fake class.
|
Rewriter::rewrite(_target_klass(), cpool, methods, CHECK_(empty)); // Use fake class.
|
||||||
|
|
||||||
|
// Create a new MDO
|
||||||
|
{
|
||||||
|
methodDataOop mdo = oopFactory::new_methodData(m, CHECK_(empty));
|
||||||
|
assert(m->method_data() == NULL, "there should not be an MDO yet");
|
||||||
|
m->set_method_data(mdo);
|
||||||
|
|
||||||
|
// Iterate over all profile data and set the count of the counter
|
||||||
|
// data entries to the original call site counter.
|
||||||
|
for (ProfileData* pd = mdo->first_data(); mdo->is_valid(pd); pd = mdo->next_data(pd)) {
|
||||||
|
if (pd->is_CounterData()) {
|
||||||
|
CounterData* cd = pd->as_CounterData();
|
||||||
|
cd->set_count(_invoke_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if (TraceMethodHandles) {
|
if (TraceMethodHandles) {
|
||||||
|
|
|
@ -247,6 +247,7 @@ public:
|
||||||
class MethodHandleCompiler : public MethodHandleWalker {
|
class MethodHandleCompiler : public MethodHandleWalker {
|
||||||
private:
|
private:
|
||||||
methodHandle _callee;
|
methodHandle _callee;
|
||||||
|
int _invoke_count; // count the original call site has been executed
|
||||||
KlassHandle _rklass; // Return type for casting.
|
KlassHandle _rklass; // Return type for casting.
|
||||||
BasicType _rtype;
|
BasicType _rtype;
|
||||||
KlassHandle _target_klass;
|
KlassHandle _target_klass;
|
||||||
|
@ -416,7 +417,7 @@ private:
|
||||||
methodHandle get_method_oop(TRAPS) const;
|
methodHandle get_method_oop(TRAPS) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MethodHandleCompiler(Handle root, methodHandle call_method, bool for_invokedynamic, TRAPS);
|
MethodHandleCompiler(Handle root, methodHandle call_method, int invoke_count, bool for_invokedynamic, TRAPS);
|
||||||
|
|
||||||
// Compile the given MH chain into bytecode.
|
// Compile the given MH chain into bytecode.
|
||||||
methodHandle compile(TRAPS);
|
methodHandle compile(TRAPS);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue