< prev index next >
src/hotspot/share/interpreter/interpreterRuntime.cpp
Print this page
*** 85,114 ****
//------------------------------------------------------------------------------------------------------------------------
// State accessors
void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {
! last_frame(thread).interpreter_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();
if (mdo != NULL) {
NEEDS_CLEANUP;
! last_frame(thread).interpreter_frame_set_mdp(mdo->bci_to_dp(last_frame(thread).interpreter_frame_bci()));
}
}
}
//------------------------------------------------------------------------------------------------------------------------
// Constants
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);
constantTag tag = pool->tag_at(index);
assert (tag.is_unresolved_klass() || tag.is_klass(), "wrong ldc call");
Klass* klass = pool->klass_at(index, CHECK);
oop java_class = klass->java_mirror();
--- 85,116 ----
//------------------------------------------------------------------------------------------------------------------------
// State accessors
void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {
! 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.method()->method_data();
if (mdo != NULL) {
NEEDS_CLEANUP;
! last_frame.set_mdp(mdo->bci_to_dp(last_frame.bci()));
}
}
}
//------------------------------------------------------------------------------------------------------------------------
// Constants
IRT_ENTRY(void, InterpreterRuntime::ldc(JavaThread* thread, bool wide))
// access constant pool
! 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");
Klass* klass = pool->klass_at(index, CHECK);
oop java_class = klass->java_mirror();
*** 117,133 ****
IRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* thread, Bytecodes::Code bytecode)) {
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));
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));
oop coop = m->constants()->resolved_references()->obj_at(ldc2.cache_index());
assert(result == coop, "expected result for assembly code");
}
#endif
thread->set_vm_result(result);
--- 119,136 ----
IRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* thread, Bytecodes::Code bytecode)) {
assert(bytecode == Bytecodes::_fast_aldc ||
bytecode == Bytecodes::_fast_aldc_w, "wrong bc");
ResourceMark rm(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, last_frame.bci());
oop coop = m->constants()->resolved_references()->obj_at(ldc2.cache_index());
assert(result == coop, "expected result for assembly code");
}
#endif
thread->set_vm_result(result);
*** 180,193 ****
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);
assert(klass->is_klass(), "not a class");
assert(nof_dims >= 1, "multianewarray rank must be nonzero");
// We must create an array of jints to pass to multi_allocate.
ResourceMark rm(thread);
--- 183,197 ----
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
! 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");
// We must create an array of jints to pass to multi_allocate.
ResourceMark rm(thread);
*** 215,226 ****
// 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();
// 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.
// assert( cpool->tag_at(which).is_unresolved_klass(), "should only come here to quicken bytecodes" );
Klass* klass = cpool->klass_at(which, CHECK);
--- 219,231 ----
// Quicken instance-of and check-cast bytecodes
IRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* thread))
// Force resolving; quicken the bytecode
! 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.
// assert( cpool->tag_at(which).is_unresolved_klass(), "should only come here to quicken bytecodes" );
Klass* klass = cpool->klass_at(which, CHECK);
*** 255,266 ****
// Assume the compiler is (or will be) interested in this event.
// 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));
note_trap_inner(thread, reason, trap_method, trap_bci, THREAD);
}
#ifdef CC_INTERP
// As legacy note_trap, but we have more arguments.
--- 260,272 ----
// Assume the compiler is (or will be) interested in this event.
// 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");
! 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);
}
#ifdef CC_INTERP
// As legacy note_trap, but we have more arguments.
*** 389,404 ****
// bci where the exception happened. If the exception was propagated back
// from a call, the expression stack contains the values for the bci at the
// 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))
Handle h_exception(thread, exception);
! methodHandle h_method (thread, method(thread));
constantPoolHandle h_constants(thread, h_method->constants());
bool should_repeat;
int handler_bci;
! int current_bci = bci(thread);
if (thread->frames_to_pop_failed_realloc() > 0) {
// Allocation of scalar replaced object used in this frame
// failed. Unconditionally pop the frame.
thread->dec_frames_to_pop_failed_realloc();
--- 395,411 ----
// bci where the exception happened. If the exception was propagated back
// from a call, the expression stack contains the values for the bci at the
// 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, last_frame.method());
constantPoolHandle h_constants(thread, h_method->constants());
bool should_repeat;
int handler_bci;
! int current_bci = last_frame.bci();
if (thread->frames_to_pop_failed_realloc() > 0) {
// Allocation of scalar replaced object used in this frame
// failed. Unconditionally pop the frame.
thread->dec_frames_to_pop_failed_realloc();
*** 491,501 ****
#endif
// 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());
}
#ifdef CC_INTERP
address continuation = (address)(intptr_t) handler_bci;
#else
--- 498,508 ----
#endif
// 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(), last_frame.bcp(), h_exception());
}
#ifdef CC_INTERP
address continuation = (address)(intptr_t) handler_bci;
#else
*** 554,577 ****
void InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode) {
Thread* THREAD = thread;
// resolve field
fieldDescriptor info;
! constantPoolHandle pool(thread, method(thread)->constants());
! methodHandle m(thread, method(thread));
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),
m, bytecode, CHECK);
} // end JvmtiHideSingleStepping
// check if link resolution caused cpCache to be updated
! ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
if (cp_cache_entry->is_resolved(bytecode)) return;
// compute auxiliary field attributes
TosState state = as_TosState(info.field_type());
--- 561,585 ----
void InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode) {
Thread* THREAD = thread;
// resolve field
fieldDescriptor info;
! 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, 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 = last_frame.cache_entry();
if (cp_cache_entry->is_resolved(bytecode)) return;
// compute auxiliary field attributes
TosState state = as_TosState(info.field_type());
*** 716,750 ****
JvmtiExport::post_raw_breakpoint(thread, method, bcp);
IRT_END
void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) {
Thread* THREAD = thread;
// extract receiver from the outgoing argument list if necessary
Handle receiver(thread, NULL);
if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface ||
bytecode == Bytecodes::_invokespecial) {
ResourceMark rm(thread);
! methodHandle m (thread, method(thread));
! Bytecode_invoke call(m, bci(thread));
Symbol* signature = call.signature();
! receiver = Handle(thread,
! thread->last_frame().interpreter_callee_receiver(signature));
assert(Universe::heap()->is_in_reserved_or_null(receiver()),
"sanity check");
assert(receiver.is_null() ||
!Universe::heap()->is_in_reserved(receiver->klass()),
"sanity check");
}
// resolve method
CallInfo info;
! constantPoolHandle pool(thread, method(thread)->constants());
{
JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_invoke(info, receiver, pool,
! get_index_u2_cpcache(thread, bytecode), bytecode,
CHECK);
if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
int retry_count = 0;
while (info.resolved_method()->is_old()) {
// It is very unlikely that method is redefined more than 100 times
--- 724,759 ----
JvmtiExport::post_raw_breakpoint(thread, method, bcp);
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 ||
bytecode == Bytecodes::_invokespecial) {
ResourceMark rm(thread);
! methodHandle m (thread, last_frame.method());
! Bytecode_invoke call(m, last_frame.bci());
Symbol* signature = call.signature();
! receiver = Handle(thread, last_frame.callee_receiver(signature));
!
assert(Universe::heap()->is_in_reserved_or_null(receiver()),
"sanity check");
assert(receiver.is_null() ||
!Universe::heap()->is_in_reserved(receiver->klass()),
"sanity check");
}
// resolve method
CallInfo info;
! constantPoolHandle pool(thread, last_frame.method()->constants());
{
JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_invoke(info, receiver, pool,
! last_frame.get_index_u2_cpcache(bytecode), bytecode,
CHECK);
if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
int retry_count = 0;
while (info.resolved_method()->is_old()) {
// It is very unlikely that method is redefined more than 100 times
*** 752,769 ****
// means then there could be a bug here.
guarantee((retry_count++ < 100),
"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,
CHECK);
}
}
} // end JvmtiHideSingleStepping
// check if link resolution caused cpCache to be updated
! ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
if (cp_cache_entry->is_resolved(bytecode)) return;
#ifdef ASSERT
if (bytecode == Bytecodes::_invokeinterface) {
if (info.resolved_method()->method_holder() ==
--- 761,778 ----
// means then there could be a bug here.
guarantee((retry_count++ < 100),
"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,
! last_frame.get_index_u2_cpcache(bytecode), bytecode,
CHECK);
}
}
} // end JvmtiHideSingleStepping
// check if link resolution caused cpCache to be updated
! ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
if (cp_cache_entry->is_resolved(bytecode)) return;
#ifdef ASSERT
if (bytecode == Bytecodes::_invokeinterface) {
if (info.resolved_method()->method_holder() ==
*** 823,859 ****
// First time execution: Resolve symbols, create a permanent MethodType object.
void InterpreterRuntime::resolve_invokehandle(JavaThread* thread) {
Thread* THREAD = thread;
const Bytecodes::Code bytecode = Bytecodes::_invokehandle;
// resolve method
CallInfo info;
! constantPoolHandle pool(thread, method(thread)->constants());
{
JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_invoke(info, Handle(), pool,
! get_index_u2_cpcache(thread, bytecode), bytecode,
CHECK);
} // end JvmtiHideSingleStepping
! ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
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;
const Bytecodes::Code bytecode = Bytecodes::_invokedynamic;
//TO DO: consider passing BCI to Java.
! // int caller_bci = method(thread)->bci_from(bcp(thread));
// resolve method
CallInfo info;
! constantPoolHandle pool(thread, method(thread)->constants());
! int index = get_index_u4(thread, bytecode);
{
JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_invoke(info, Handle(), pool,
index, bytecode, CHECK);
} // end JvmtiHideSingleStepping
--- 832,870 ----
// First time execution: Resolve symbols, create a permanent MethodType object.
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, last_frame.method()->constants());
{
JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_invoke(info, Handle(), pool,
! last_frame.get_index_u2_cpcache(bytecode), bytecode,
CHECK);
} // end JvmtiHideSingleStepping
! 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 = last_frame.method()->bci_from(last_frame.bcp());
// resolve method
CallInfo info;
! constantPoolHandle pool(thread, last_frame.method()->constants());
! int index = last_frame.get_index_u4(bytecode);
{
JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_invoke(info, Handle(), pool,
index, bytecode, CHECK);
} // end JvmtiHideSingleStepping
*** 903,915 ****
// This was a successful request for an OSR nmethod. Because
// frequency_counter_overflow_inner ends with a safepoint check,
// 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());
nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false);
}
#ifndef PRODUCT
if (TraceOnStackReplacement) {
if (nm != NULL) {
--- 914,926 ----
// This was a successful request for an OSR nmethod. Because
// frequency_counter_overflow_inner ends with a safepoint check,
// 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.
! 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
if (TraceOnStackReplacement) {
if (nm != NULL) {
*** 925,939 ****
InterpreterRuntime::frequency_counter_overflow_inner(JavaThread* thread, address branch_bcp))
// use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized
// 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());
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;
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);
assert(!HAS_PENDING_EXCEPTION, "Event handler should not throw any exceptions");
--- 936,950 ----
InterpreterRuntime::frequency_counter_overflow_inner(JavaThread* thread, address branch_bcp))
// use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized
// flag, in case this method triggers classloading which will call into Java.
UnlockFlagSaver fs(thread);
! 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(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);
assert(!HAS_PENDING_EXCEPTION, "Event handler should not throw any exceptions");
*** 945,957 ****
// the OSR nmethod might be invalidated) because we don't have a
// safepoint opportunity later once the migration begins.
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) ) {
if( kptr->obj() != NULL ) {
objects_to_revoke->append(Handle(THREAD, kptr->obj()));
}
}
BiasedLocking::revoke(objects_to_revoke);
--- 956,968 ----
// the OSR nmethod might be invalidated) because we don't have a
// safepoint opportunity later once the migration begins.
if (UseBiasedLocking) {
ResourceMark rm;
GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
! 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()));
}
}
BiasedLocking::revoke(objects_to_revoke);
*** 972,984 ****
// use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized
// flag, in case this method triggers classloading which will call into Java.
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());
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");
CLEAR_PENDING_EXCEPTION;
// and fall through...
--- 983,995 ----
// use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized
// flag, in case this method triggers classloading which will call into Java.
UnlockFlagSaver fs(thread);
assert(ProfileInterpreter, "must be profiling interpreter");
! 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");
CLEAR_PENDING_EXCEPTION;
// and fall through...
*** 1019,1043 ****
IRT_ENTRY(void, InterpreterRuntime::update_mdp_for_ret(JavaThread* thread, int return_bci))
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();
// Grab a lock to ensure atomic access to setting the return bci and
// the displacement. This can block and GC, invalidating all naked oops.
MutexLocker ml(RetData_lock);
// 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()));
guarantee(data != NULL, "profile data must be valid");
RetData* rdata = data->as_RetData();
address new_mdp = rdata->fixup_ret(return_bci, h_mdo);
! fr.interpreter_frame_set_mdp(new_mdp);
IRT_END
IRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m))
MethodCounters* mcs = Method::build_method_counters(m, thread);
if (HAS_PENDING_EXCEPTION) {
--- 1030,1054 ----
IRT_ENTRY(void, InterpreterRuntime::update_mdp_for_ret(JavaThread* thread, int return_bci))
assert(ProfileInterpreter, "must be profiling interpreter");
ResourceMark rm(thread);
HandleMark hm(thread);
! 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.
MutexLocker ml(RetData_lock);
// 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(last_frame.mdp()));
guarantee(data != NULL, "profile data must be valid");
RetData* rdata = data->as_RetData();
address new_mdp = rdata->fixup_ret(return_bci, h_mdo);
! last_frame.set_mdp(new_mdp);
IRT_END
IRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m))
MethodCounters* mcs = Method::build_method_counters(m, thread);
if (HAS_PENDING_EXCEPTION) {
*** 1058,1068 ****
if (JvmtiExport::should_post_single_step()) {
// 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));
}
IRT_END
IRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread *thread, oopDesc* obj,
ConstantPoolCacheEntry *cp_entry))
--- 1069,1080 ----
if (JvmtiExport::should_post_single_step()) {
// 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.
! LastFrameAccessor last_frame(thread);
! JvmtiExport::at_single_stepping_point(thread, last_frame.method(), last_frame.bcp());
}
IRT_END
IRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread *thread, oopDesc* obj,
ConstantPoolCacheEntry *cp_entry))
*** 1081,1091 ****
// non-static field accessors have an object, but we need a handle
h_obj = Handle(thread, obj);
}
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);
IRT_END
IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread,
oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value))
--- 1093,1104 ----
// non-static field accessors have an object, but we need a handle
h_obj = Handle(thread, obj);
}
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);
! 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,
oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value))
*** 1136,1156 ****
if (!is_static) {
// non-static field accessors have an object, but we need a handle
h_obj = Handle(thread, obj);
}
! JvmtiExport::post_raw_field_modification(thread, method(thread), bcp(thread), 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));
IRT_END
IRT_ENTRY(void, InterpreterRuntime::post_method_exit(JavaThread *thread))
! JvmtiExport::post_method_exit(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread));
IRT_END
IRT_LEAF(int, InterpreterRuntime::interpreter_contains(address pc))
{
return (Interpreter::contains(pc) ? 1 : 0);
--- 1149,1172 ----
if (!is_static) {
// non-static field accessors have an object, but we need a handle
h_obj = Handle(thread, 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))
! 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))
! 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))
{
return (Interpreter::contains(pc) ? 1 : 0);
*** 1370,1383 ****
return;
}
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());
Bytecode_invoke invoke(mh, bci);
ArgumentSizeComputer asc(invoke.signature());
int size_of_arguments = (asc.size() + (invoke.has_receiver() ? 1 : 0)); // receiver
Copy::conjoint_jbytes(src_address, dest_address,
size_of_arguments * Interpreter::stackElementSize);
--- 1386,1399 ----
return;
}
ResetNoHandleMark rnm; // In a LEAF entry.
HandleMark hm;
ResourceMark rm;
! 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
Copy::conjoint_jbytes(src_address, dest_address,
size_of_arguments * Interpreter::stackElementSize);
*** 1419,1430 ****
// This must be a IRT_LEAF function because the interpreter must save registers on x86 to
// call this, which changes rsp and makes the interpreter's expression stack not walkable.
// 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);
return preserve_this_value;
IRT_END
#endif // !PRODUCT
--- 1435,1446 ----
// This must be a IRT_LEAF function because the interpreter must save registers on x86 to
// call this, which changes rsp and makes the interpreter's expression stack not walkable.
// 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))
! 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
< prev index next >