8179305: Avoid repeated calls to JavaThread::last_frame in InterpreterRuntime
Added LastFrameAccessor class Reviewed-by: dlong, dholmes
This commit is contained in:
parent
cf7c7fedcd
commit
66f0c0d17f
@ -86,14 +86,15 @@ class UnlockFlagSaver {
|
||||
// State accessors
|
||||
|
||||
void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {
|
||||
last_frame(thread).interpreter_frame_set_bcp(bcp);
|
||||
LastFrameAccessor last_frame(thread);
|
||||
last_frame.set_bcp(bcp);
|
||||
if (ProfileInterpreter) {
|
||||
// ProfileTraps uses MDOs independently of ProfileInterpreter.
|
||||
// That is why we must check both ProfileInterpreter and mdo != NULL.
|
||||
MethodData* mdo = last_frame(thread).interpreter_frame_method()->method_data();
|
||||
MethodData* mdo = last_frame.method()->method_data();
|
||||
if (mdo != NULL) {
|
||||
NEEDS_CLEANUP;
|
||||
last_frame(thread).interpreter_frame_set_mdp(mdo->bci_to_dp(last_frame(thread).interpreter_frame_bci()));
|
||||
last_frame.set_mdp(mdo->bci_to_dp(last_frame.bci()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -104,8 +105,9 @@ void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {
|
||||
|
||||
IRT_ENTRY(void, InterpreterRuntime::ldc(JavaThread* thread, bool wide))
|
||||
// access constant pool
|
||||
ConstantPool* pool = method(thread)->constants();
|
||||
int index = wide ? get_index_u2(thread, Bytecodes::_ldc_w) : get_index_u1(thread, Bytecodes::_ldc);
|
||||
LastFrameAccessor last_frame(thread);
|
||||
ConstantPool* pool = last_frame.method()->constants();
|
||||
int index = wide ? last_frame.get_index_u2(Bytecodes::_ldc_w) : last_frame.get_index_u1(Bytecodes::_ldc);
|
||||
constantTag tag = pool->tag_at(index);
|
||||
|
||||
assert (tag.is_unresolved_klass() || tag.is_klass(), "wrong ldc call");
|
||||
@ -118,13 +120,14 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* thread, Bytecodes::C
|
||||
assert(bytecode == Bytecodes::_fast_aldc ||
|
||||
bytecode == Bytecodes::_fast_aldc_w, "wrong bc");
|
||||
ResourceMark rm(thread);
|
||||
methodHandle m (thread, method(thread));
|
||||
Bytecode_loadconstant ldc(m, bci(thread));
|
||||
LastFrameAccessor last_frame(thread);
|
||||
methodHandle m (thread, last_frame.method());
|
||||
Bytecode_loadconstant ldc(m, last_frame.bci());
|
||||
oop result = ldc.resolve_constant(CHECK);
|
||||
#ifdef ASSERT
|
||||
{
|
||||
// The bytecode wrappers aren't GC-safe so construct a new one
|
||||
Bytecode_loadconstant ldc2(m, bci(thread));
|
||||
Bytecode_loadconstant ldc2(m, last_frame.bci());
|
||||
oop coop = m->constants()->resolved_references()->obj_at(ldc2.cache_index());
|
||||
assert(result == coop, "expected result for assembly code");
|
||||
}
|
||||
@ -181,10 +184,11 @@ IRT_END
|
||||
|
||||
IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
|
||||
// We may want to pass in more arguments - could make this slightly faster
|
||||
ConstantPool* constants = method(thread)->constants();
|
||||
int i = get_index_u2(thread, Bytecodes::_multianewarray);
|
||||
Klass* klass = constants->klass_at(i, CHECK);
|
||||
int nof_dims = number_of_dimensions(thread);
|
||||
LastFrameAccessor last_frame(thread);
|
||||
ConstantPool* constants = last_frame.method()->constants();
|
||||
int i = last_frame.get_index_u2(Bytecodes::_multianewarray);
|
||||
Klass* klass = constants->klass_at(i, CHECK);
|
||||
int nof_dims = last_frame.number_of_dimensions();
|
||||
assert(klass->is_klass(), "not a class");
|
||||
assert(nof_dims >= 1, "multianewarray rank must be nonzero");
|
||||
|
||||
@ -216,8 +220,9 @@ IRT_END
|
||||
// Quicken instance-of and check-cast bytecodes
|
||||
IRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* thread))
|
||||
// Force resolving; quicken the bytecode
|
||||
int which = get_index_u2(thread, Bytecodes::_checkcast);
|
||||
ConstantPool* cpool = method(thread)->constants();
|
||||
LastFrameAccessor last_frame(thread);
|
||||
int which = last_frame.get_index_u2(Bytecodes::_checkcast);
|
||||
ConstantPool* cpool = last_frame.method()->constants();
|
||||
// We'd expect to assert that we're only here to quicken bytecodes, but in a multithreaded
|
||||
// program we might have seen an unquick'd bytecode in the interpreter but have another
|
||||
// thread quicken the bytecode before we get here.
|
||||
@ -256,8 +261,9 @@ void InterpreterRuntime::note_trap_inner(JavaThread* thread, int reason,
|
||||
// If necessary, create an MDO to hold the information, and record it.
|
||||
void InterpreterRuntime::note_trap(JavaThread* thread, int reason, TRAPS) {
|
||||
assert(ProfileTraps, "call me only if profiling");
|
||||
methodHandle trap_method(thread, method(thread));
|
||||
int trap_bci = trap_method->bci_from(bcp(thread));
|
||||
LastFrameAccessor last_frame(thread);
|
||||
methodHandle trap_method(thread, last_frame.method());
|
||||
int trap_bci = trap_method->bci_from(last_frame.bcp());
|
||||
note_trap_inner(thread, reason, trap_method, trap_bci, THREAD);
|
||||
}
|
||||
|
||||
@ -390,12 +396,13 @@ IRT_END
|
||||
// invoke w/o arguments (i.e., as if one were inside the call).
|
||||
IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception))
|
||||
|
||||
LastFrameAccessor last_frame(thread);
|
||||
Handle h_exception(thread, exception);
|
||||
methodHandle h_method (thread, method(thread));
|
||||
methodHandle h_method (thread, last_frame.method());
|
||||
constantPoolHandle h_constants(thread, h_method->constants());
|
||||
bool should_repeat;
|
||||
int handler_bci;
|
||||
int current_bci = bci(thread);
|
||||
int current_bci = last_frame.bci();
|
||||
|
||||
if (thread->frames_to_pop_failed_realloc() > 0) {
|
||||
// Allocation of scalar replaced object used in this frame
|
||||
@ -493,7 +500,7 @@ IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThrea
|
||||
// notify JVMTI of an exception throw; JVMTI will detect if this is a first
|
||||
// time throw or a stack unwinding throw and accordingly notify the debugger
|
||||
if (JvmtiExport::can_post_on_exceptions()) {
|
||||
JvmtiExport::post_exception_throw(thread, h_method(), bcp(thread), h_exception());
|
||||
JvmtiExport::post_exception_throw(thread, h_method(), last_frame.bcp(), h_exception());
|
||||
}
|
||||
|
||||
#ifdef CC_INTERP
|
||||
@ -556,20 +563,21 @@ void InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code byt
|
||||
Thread* THREAD = thread;
|
||||
// resolve field
|
||||
fieldDescriptor info;
|
||||
constantPoolHandle pool(thread, method(thread)->constants());
|
||||
methodHandle m(thread, method(thread));
|
||||
LastFrameAccessor last_frame(thread);
|
||||
constantPoolHandle pool(thread, last_frame.method()->constants());
|
||||
methodHandle m(thread, last_frame.method());
|
||||
bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_nofast_putfield ||
|
||||
bytecode == Bytecodes::_putstatic);
|
||||
bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
|
||||
|
||||
{
|
||||
JvmtiHideSingleStepping jhss(thread);
|
||||
LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode),
|
||||
LinkResolver::resolve_field_access(info, pool, last_frame.get_index_u2_cpcache(bytecode),
|
||||
m, bytecode, CHECK);
|
||||
} // end JvmtiHideSingleStepping
|
||||
|
||||
// check if link resolution caused cpCache to be updated
|
||||
ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
|
||||
ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
|
||||
if (cp_cache_entry->is_resolved(bytecode)) return;
|
||||
|
||||
// compute auxiliary field attributes
|
||||
@ -718,15 +726,15 @@ IRT_END
|
||||
|
||||
void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) {
|
||||
Thread* THREAD = thread;
|
||||
LastFrameAccessor last_frame(thread);
|
||||
// extract receiver from the outgoing argument list if necessary
|
||||
Handle receiver(thread, NULL);
|
||||
if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) {
|
||||
ResourceMark rm(thread);
|
||||
methodHandle m (thread, method(thread));
|
||||
Bytecode_invoke call(m, bci(thread));
|
||||
methodHandle m (thread, last_frame.method());
|
||||
Bytecode_invoke call(m, last_frame.bci());
|
||||
Symbol* signature = call.signature();
|
||||
receiver = Handle(thread,
|
||||
thread->last_frame().interpreter_callee_receiver(signature));
|
||||
receiver = Handle(thread, last_frame.callee_receiver(signature));
|
||||
assert(Universe::heap()->is_in_reserved_or_null(receiver()),
|
||||
"sanity check");
|
||||
assert(receiver.is_null() ||
|
||||
@ -736,12 +744,12 @@ void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code byte
|
||||
|
||||
// resolve method
|
||||
CallInfo info;
|
||||
constantPoolHandle pool(thread, method(thread)->constants());
|
||||
constantPoolHandle pool(thread, last_frame.method()->constants());
|
||||
|
||||
{
|
||||
JvmtiHideSingleStepping jhss(thread);
|
||||
LinkResolver::resolve_invoke(info, receiver, pool,
|
||||
get_index_u2_cpcache(thread, bytecode), bytecode,
|
||||
last_frame.get_index_u2_cpcache(bytecode), bytecode,
|
||||
CHECK);
|
||||
if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
|
||||
int retry_count = 0;
|
||||
@ -753,14 +761,14 @@ void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code byte
|
||||
"Could not resolve to latest version of redefined method");
|
||||
// method is redefined in the middle of resolve so re-try.
|
||||
LinkResolver::resolve_invoke(info, receiver, pool,
|
||||
get_index_u2_cpcache(thread, bytecode), bytecode,
|
||||
last_frame.get_index_u2_cpcache(bytecode), bytecode,
|
||||
CHECK);
|
||||
}
|
||||
}
|
||||
} // end JvmtiHideSingleStepping
|
||||
|
||||
// check if link resolution caused cpCache to be updated
|
||||
ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
|
||||
ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
|
||||
if (cp_cache_entry->is_resolved(bytecode)) return;
|
||||
|
||||
#ifdef ASSERT
|
||||
@ -815,33 +823,35 @@ void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code byte
|
||||
void InterpreterRuntime::resolve_invokehandle(JavaThread* thread) {
|
||||
Thread* THREAD = thread;
|
||||
const Bytecodes::Code bytecode = Bytecodes::_invokehandle;
|
||||
LastFrameAccessor last_frame(thread);
|
||||
|
||||
// resolve method
|
||||
CallInfo info;
|
||||
constantPoolHandle pool(thread, method(thread)->constants());
|
||||
constantPoolHandle pool(thread, last_frame.method()->constants());
|
||||
{
|
||||
JvmtiHideSingleStepping jhss(thread);
|
||||
LinkResolver::resolve_invoke(info, Handle(), pool,
|
||||
get_index_u2_cpcache(thread, bytecode), bytecode,
|
||||
last_frame.get_index_u2_cpcache(bytecode), bytecode,
|
||||
CHECK);
|
||||
} // end JvmtiHideSingleStepping
|
||||
|
||||
ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
|
||||
ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
|
||||
cp_cache_entry->set_method_handle(pool, info);
|
||||
}
|
||||
|
||||
// First time execution: Resolve symbols, create a permanent CallSite object.
|
||||
void InterpreterRuntime::resolve_invokedynamic(JavaThread* thread) {
|
||||
Thread* THREAD = thread;
|
||||
LastFrameAccessor last_frame(thread);
|
||||
const Bytecodes::Code bytecode = Bytecodes::_invokedynamic;
|
||||
|
||||
//TO DO: consider passing BCI to Java.
|
||||
// int caller_bci = method(thread)->bci_from(bcp(thread));
|
||||
// int caller_bci = last_frame.method()->bci_from(last_frame.bcp());
|
||||
|
||||
// resolve method
|
||||
CallInfo info;
|
||||
constantPoolHandle pool(thread, method(thread)->constants());
|
||||
int index = get_index_u4(thread, bytecode);
|
||||
constantPoolHandle pool(thread, last_frame.method()->constants());
|
||||
int index = last_frame.get_index_u4(bytecode);
|
||||
{
|
||||
JvmtiHideSingleStepping jhss(thread);
|
||||
LinkResolver::resolve_invoke(info, Handle(), pool,
|
||||
@ -895,9 +905,9 @@ nmethod* InterpreterRuntime::frequency_counter_overflow(JavaThread* thread, addr
|
||||
// nm could have been unloaded so look it up again. It's unsafe
|
||||
// to examine nm directly since it might have been freed and used
|
||||
// for something else.
|
||||
frame fr = thread->last_frame();
|
||||
Method* method = fr.interpreter_frame_method();
|
||||
int bci = method->bci_from(fr.interpreter_frame_bcp());
|
||||
LastFrameAccessor last_frame(thread);
|
||||
Method* method = last_frame.method();
|
||||
int bci = method->bci_from(last_frame.bcp());
|
||||
nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false);
|
||||
}
|
||||
#ifndef PRODUCT
|
||||
@ -917,11 +927,11 @@ IRT_ENTRY(nmethod*,
|
||||
// flag, in case this method triggers classloading which will call into Java.
|
||||
UnlockFlagSaver fs(thread);
|
||||
|
||||
frame fr = thread->last_frame();
|
||||
assert(fr.is_interpreted_frame(), "must come from interpreter");
|
||||
methodHandle method(thread, fr.interpreter_frame_method());
|
||||
LastFrameAccessor last_frame(thread);
|
||||
assert(last_frame.is_interpreted_frame(), "must come from interpreter");
|
||||
methodHandle method(thread, last_frame.method());
|
||||
const int branch_bci = branch_bcp != NULL ? method->bci_from(branch_bcp) : InvocationEntryBci;
|
||||
const int bci = branch_bcp != NULL ? method->bci_from(fr.interpreter_frame_bcp()) : InvocationEntryBci;
|
||||
const int bci = branch_bcp != NULL ? method->bci_from(last_frame.bcp()) : InvocationEntryBci;
|
||||
|
||||
assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending");
|
||||
nmethod* osr_nm = CompilationPolicy::policy()->event(method, method, branch_bci, bci, CompLevel_none, NULL, thread);
|
||||
@ -937,9 +947,9 @@ IRT_ENTRY(nmethod*,
|
||||
if (UseBiasedLocking) {
|
||||
ResourceMark rm;
|
||||
GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
|
||||
for( BasicObjectLock *kptr = fr.interpreter_frame_monitor_end();
|
||||
kptr < fr.interpreter_frame_monitor_begin();
|
||||
kptr = fr.next_monitor_in_interpreter_frame(kptr) ) {
|
||||
for( BasicObjectLock *kptr = last_frame.monitor_end();
|
||||
kptr < last_frame.monitor_begin();
|
||||
kptr = last_frame.next_monitor(kptr) ) {
|
||||
if( kptr->obj() != NULL ) {
|
||||
objects_to_revoke->append(Handle(THREAD, kptr->obj()));
|
||||
}
|
||||
@ -964,9 +974,9 @@ IRT_ENTRY(void, InterpreterRuntime::profile_method(JavaThread* thread))
|
||||
UnlockFlagSaver fs(thread);
|
||||
|
||||
assert(ProfileInterpreter, "must be profiling interpreter");
|
||||
frame fr = thread->last_frame();
|
||||
assert(fr.is_interpreted_frame(), "must come from interpreter");
|
||||
methodHandle method(thread, fr.interpreter_frame_method());
|
||||
LastFrameAccessor last_frame(thread);
|
||||
assert(last_frame.is_interpreted_frame(), "must come from interpreter");
|
||||
methodHandle method(thread, last_frame.method());
|
||||
Method::build_interpreter_method_data(method, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
|
||||
@ -1011,9 +1021,9 @@ IRT_ENTRY(void, InterpreterRuntime::update_mdp_for_ret(JavaThread* thread, int r
|
||||
assert(ProfileInterpreter, "must be profiling interpreter");
|
||||
ResourceMark rm(thread);
|
||||
HandleMark hm(thread);
|
||||
frame fr = thread->last_frame();
|
||||
assert(fr.is_interpreted_frame(), "must come from interpreter");
|
||||
MethodData* h_mdo = fr.interpreter_frame_method()->method_data();
|
||||
LastFrameAccessor last_frame(thread);
|
||||
assert(last_frame.is_interpreted_frame(), "must come from interpreter");
|
||||
MethodData* h_mdo = last_frame.method()->method_data();
|
||||
|
||||
// Grab a lock to ensure atomic access to setting the return bci and
|
||||
// the displacement. This can block and GC, invalidating all naked oops.
|
||||
@ -1021,10 +1031,10 @@ IRT_ENTRY(void, InterpreterRuntime::update_mdp_for_ret(JavaThread* thread, int r
|
||||
|
||||
// ProfileData is essentially a wrapper around a derived oop, so we
|
||||
// need to take the lock before making any ProfileData structures.
|
||||
ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(fr.interpreter_frame_mdp()));
|
||||
ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(last_frame.mdp()));
|
||||
RetData* rdata = data->as_RetData();
|
||||
address new_mdp = rdata->fixup_ret(return_bci, h_mdo);
|
||||
fr.interpreter_frame_set_mdp(new_mdp);
|
||||
last_frame.set_mdp(new_mdp);
|
||||
IRT_END
|
||||
|
||||
IRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m))
|
||||
@ -1049,7 +1059,8 @@ IRT_ENTRY(void, InterpreterRuntime::at_safepoint(JavaThread* thread))
|
||||
// We are called during regular safepoints and when the VM is
|
||||
// single stepping. If any thread is marked for single stepping,
|
||||
// then we may have JVMTI work to do.
|
||||
JvmtiExport::at_single_stepping_point(thread, method(thread), bcp(thread));
|
||||
LastFrameAccessor last_frame(thread);
|
||||
JvmtiExport::at_single_stepping_point(thread, last_frame.method(), last_frame.bcp());
|
||||
}
|
||||
IRT_END
|
||||
|
||||
@ -1072,7 +1083,8 @@ ConstantPoolCacheEntry *cp_entry))
|
||||
}
|
||||
InstanceKlass* cp_entry_f1 = InstanceKlass::cast(cp_entry->f1_as_klass());
|
||||
jfieldID fid = jfieldIDWorkaround::to_jfieldID(cp_entry_f1, cp_entry->f2_as_index(), is_static);
|
||||
JvmtiExport::post_field_access(thread, method(thread), bcp(thread), cp_entry_f1, h_obj, fid);
|
||||
LastFrameAccessor last_frame(thread);
|
||||
JvmtiExport::post_field_access(thread, last_frame.method(), last_frame.bcp(), cp_entry_f1, h_obj, fid);
|
||||
IRT_END
|
||||
|
||||
IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread,
|
||||
@ -1127,17 +1139,20 @@ IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread,
|
||||
h_obj = Handle(thread, obj);
|
||||
}
|
||||
|
||||
JvmtiExport::post_raw_field_modification(thread, method(thread), bcp(thread), ik, h_obj,
|
||||
LastFrameAccessor last_frame(thread);
|
||||
JvmtiExport::post_raw_field_modification(thread, last_frame.method(), last_frame.bcp(), ik, h_obj,
|
||||
fid, sig_type, &fvalue);
|
||||
IRT_END
|
||||
|
||||
IRT_ENTRY(void, InterpreterRuntime::post_method_entry(JavaThread *thread))
|
||||
JvmtiExport::post_method_entry(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread));
|
||||
LastFrameAccessor last_frame(thread);
|
||||
JvmtiExport::post_method_entry(thread, last_frame.method(), last_frame.get_frame());
|
||||
IRT_END
|
||||
|
||||
|
||||
IRT_ENTRY(void, InterpreterRuntime::post_method_exit(JavaThread *thread))
|
||||
JvmtiExport::post_method_exit(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread));
|
||||
LastFrameAccessor last_frame(thread);
|
||||
JvmtiExport::post_method_exit(thread, last_frame.method(), last_frame.get_frame());
|
||||
IRT_END
|
||||
|
||||
IRT_LEAF(int, InterpreterRuntime::interpreter_contains(address pc))
|
||||
@ -1362,10 +1377,10 @@ IRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* threa
|
||||
ResetNoHandleMark rnm; // In a LEAF entry.
|
||||
HandleMark hm;
|
||||
ResourceMark rm;
|
||||
frame fr = thread->last_frame();
|
||||
assert(fr.is_interpreted_frame(), "");
|
||||
jint bci = fr.interpreter_frame_bci();
|
||||
methodHandle mh(thread, fr.interpreter_frame_method());
|
||||
LastFrameAccessor last_frame(thread);
|
||||
assert(last_frame.is_interpreted_frame(), "");
|
||||
jint bci = last_frame.bci();
|
||||
methodHandle mh(thread, last_frame.method());
|
||||
Bytecode_invoke invoke(mh, bci);
|
||||
ArgumentSizeComputer asc(invoke.signature());
|
||||
int size_of_arguments = (asc.size() + (invoke.has_receiver() ? 1 : 0)); // receiver
|
||||
@ -1411,10 +1426,10 @@ IRT_END
|
||||
// The generated code still uses call_VM because that will set up the frame pointer for
|
||||
// bcp and method.
|
||||
IRT_LEAF(intptr_t, InterpreterRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
|
||||
const frame f = thread->last_frame();
|
||||
assert(f.is_interpreted_frame(), "must be an interpreted frame");
|
||||
methodHandle mh(thread, f.interpreter_frame_method());
|
||||
BytecodeTracer::trace(mh, f.interpreter_frame_bcp(), tos, tos2);
|
||||
LastFrameAccessor last_frame(thread);
|
||||
assert(last_frame.is_interpreted_frame(), "must be an interpreted frame");
|
||||
methodHandle mh(thread, last_frame.method());
|
||||
BytecodeTracer::trace(mh, last_frame.bcp(), tos, tos2);
|
||||
return preserve_this_value;
|
||||
IRT_END
|
||||
#endif // !PRODUCT
|
||||
|
@ -42,29 +42,54 @@ class InterpreterRuntime: AllStatic {
|
||||
friend class PrintingClosure; // for method and bcp
|
||||
|
||||
private:
|
||||
// Helper functions to access current interpreter state
|
||||
static frame last_frame(JavaThread *thread) { return thread->last_frame(); }
|
||||
static Method* method(JavaThread *thread) { return last_frame(thread).interpreter_frame_method(); }
|
||||
static address bcp(JavaThread *thread) { return last_frame(thread).interpreter_frame_bcp(); }
|
||||
static int bci(JavaThread *thread) { return last_frame(thread).interpreter_frame_bci(); }
|
||||
static void set_bcp_and_mdp(address bcp, JavaThread*thread);
|
||||
static Bytecodes::Code code(JavaThread *thread) {
|
||||
// pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
|
||||
return Bytecodes::code_at(method(thread), bcp(thread));
|
||||
}
|
||||
static Bytecode bytecode(JavaThread *thread) { return Bytecode(method(thread), bcp(thread)); }
|
||||
static int get_index_u1(JavaThread *thread, Bytecodes::Code bc)
|
||||
{ return bytecode(thread).get_index_u1(bc); }
|
||||
static int get_index_u2(JavaThread *thread, Bytecodes::Code bc)
|
||||
{ return bytecode(thread).get_index_u2(bc); }
|
||||
static int get_index_u2_cpcache(JavaThread *thread, Bytecodes::Code bc)
|
||||
{ return bytecode(thread).get_index_u2_cpcache(bc); }
|
||||
static int get_index_u4(JavaThread *thread, Bytecodes::Code bc)
|
||||
{ return bytecode(thread).get_index_u4(bc); }
|
||||
static int number_of_dimensions(JavaThread *thread) { return bcp(thread)[3]; }
|
||||
// Helper class to access current interpreter state
|
||||
class LastFrameAccessor : public StackObj {
|
||||
frame _last_frame;
|
||||
public:
|
||||
LastFrameAccessor(JavaThread* thread) {
|
||||
assert(thread == Thread::current(), "sanity");
|
||||
_last_frame = thread->last_frame();
|
||||
}
|
||||
bool is_interpreted_frame() const { return _last_frame.is_interpreted_frame(); }
|
||||
Method* method() const { return _last_frame.interpreter_frame_method(); }
|
||||
address bcp() const { return _last_frame.interpreter_frame_bcp(); }
|
||||
int bci() const { return _last_frame.interpreter_frame_bci(); }
|
||||
address mdp() const { return _last_frame.interpreter_frame_mdp(); }
|
||||
|
||||
static ConstantPoolCacheEntry* cache_entry_at(JavaThread *thread, int i) { return method(thread)->constants()->cache()->entry_at(i); }
|
||||
static ConstantPoolCacheEntry* cache_entry(JavaThread *thread) { return cache_entry_at(thread, Bytes::get_native_u2(bcp(thread) + 1)); }
|
||||
void set_bcp(address bcp) { _last_frame.interpreter_frame_set_bcp(bcp); }
|
||||
void set_mdp(address dp) { _last_frame.interpreter_frame_set_mdp(dp); }
|
||||
|
||||
// pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
|
||||
Bytecodes::Code code() const { return Bytecodes::code_at(method(), bcp()); }
|
||||
|
||||
Bytecode bytecode() const { return Bytecode(method(), bcp()); }
|
||||
int get_index_u1(Bytecodes::Code bc) const { return bytecode().get_index_u1(bc); }
|
||||
int get_index_u2(Bytecodes::Code bc) const { return bytecode().get_index_u2(bc); }
|
||||
int get_index_u2_cpcache(Bytecodes::Code bc) const
|
||||
{ return bytecode().get_index_u2_cpcache(bc); }
|
||||
int get_index_u4(Bytecodes::Code bc) const { return bytecode().get_index_u4(bc); }
|
||||
int number_of_dimensions() const { return bcp()[3]; }
|
||||
ConstantPoolCacheEntry* cache_entry_at(int i) const
|
||||
{ return method()->constants()->cache()->entry_at(i); }
|
||||
ConstantPoolCacheEntry* cache_entry() const { return cache_entry_at(Bytes::get_native_u2(bcp() + 1)); }
|
||||
|
||||
oop callee_receiver(Symbol* signature) {
|
||||
return _last_frame.interpreter_callee_receiver(signature);
|
||||
}
|
||||
BasicObjectLock* monitor_begin() const {
|
||||
return _last_frame.interpreter_frame_monitor_end();
|
||||
}
|
||||
BasicObjectLock* monitor_end() const {
|
||||
return _last_frame.interpreter_frame_monitor_begin();
|
||||
}
|
||||
BasicObjectLock* next_monitor(BasicObjectLock* current) const {
|
||||
return _last_frame.next_monitor_in_interpreter_frame(current);
|
||||
}
|
||||
|
||||
frame& get_frame() { return _last_frame; }
|
||||
};
|
||||
|
||||
static void set_bcp_and_mdp(address bcp, JavaThread*thread);
|
||||
static void note_trap_inner(JavaThread* thread, int reason,
|
||||
methodHandle trap_method, int trap_bci, TRAPS);
|
||||
static void note_trap(JavaThread *thread, int reason, TRAPS);
|
||||
@ -139,7 +164,7 @@ class InterpreterRuntime: AllStatic {
|
||||
static void _breakpoint(JavaThread* thread, Method* method, address bcp);
|
||||
static Bytecodes::Code get_original_bytecode_at(JavaThread* thread, Method* method, address bcp);
|
||||
static void set_original_bytecode_at(JavaThread* thread, Method* method, address bcp, Bytecodes::Code new_code);
|
||||
static bool is_breakpoint(JavaThread *thread) { return Bytecodes::code_or_bp_at(bcp(thread)) == Bytecodes::_breakpoint; }
|
||||
static bool is_breakpoint(JavaThread *thread) { return Bytecodes::code_or_bp_at(LastFrameAccessor(thread).bcp()) == Bytecodes::_breakpoint; }
|
||||
|
||||
// Safepoints
|
||||
static void at_safepoint(JavaThread* thread);
|
||||
|
Loading…
Reference in New Issue
Block a user