mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8076492: Make common code from template interpreter code
Move case statement out of assembly code Reviewed-by: minqi, sspitsyn, dholmes
This commit is contained in:
parent
d350f07d51
commit
f0035b701e
7 changed files with 74 additions and 107 deletions
|
@ -2138,30 +2138,7 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
|
|||
__ br(Assembler::EQ, resolved);
|
||||
|
||||
// resolve first time through
|
||||
address entry;
|
||||
switch (bytecode()) {
|
||||
case Bytecodes::_getstatic:
|
||||
case Bytecodes::_putstatic:
|
||||
case Bytecodes::_getfield:
|
||||
case Bytecodes::_putfield:
|
||||
entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put);
|
||||
break;
|
||||
case Bytecodes::_invokevirtual:
|
||||
case Bytecodes::_invokespecial:
|
||||
case Bytecodes::_invokestatic:
|
||||
case Bytecodes::_invokeinterface:
|
||||
entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
|
||||
break;
|
||||
case Bytecodes::_invokehandle:
|
||||
entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle);
|
||||
break;
|
||||
case Bytecodes::_invokedynamic:
|
||||
entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
|
||||
break;
|
||||
default:
|
||||
fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
|
||||
break;
|
||||
}
|
||||
address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
|
||||
__ mov(temp, (int) bytecode());
|
||||
__ call_VM(noreg, entry, temp);
|
||||
|
||||
|
|
|
@ -2177,22 +2177,7 @@ void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Regist
|
|||
__ cmpdi(CCR0, Rscratch, (int)code);
|
||||
__ beq(CCR0, Lresolved);
|
||||
|
||||
address entry = NULL;
|
||||
switch (code) {
|
||||
case Bytecodes::_getstatic : // fall through
|
||||
case Bytecodes::_putstatic : // fall through
|
||||
case Bytecodes::_getfield : // fall through
|
||||
case Bytecodes::_putfield : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
|
||||
case Bytecodes::_invokevirtual : // fall through
|
||||
case Bytecodes::_invokespecial : // fall through
|
||||
case Bytecodes::_invokestatic : // fall through
|
||||
case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break;
|
||||
case Bytecodes::_invokehandle : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); break;
|
||||
case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
|
||||
default :
|
||||
fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(code)));
|
||||
break;
|
||||
}
|
||||
address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
|
||||
__ li(R4_ARG2, code);
|
||||
__ call_VM(noreg, entry, R4_ARG2, true);
|
||||
|
||||
|
|
|
@ -2070,23 +2070,7 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
|
|||
__ br(Assembler::equal, false, Assembler::pt, resolved);
|
||||
__ delayed()->set(code, O1);
|
||||
|
||||
address entry;
|
||||
|
||||
switch (code) {
|
||||
case Bytecodes::_getstatic : // fall through
|
||||
case Bytecodes::_putstatic : // fall through
|
||||
case Bytecodes::_getfield : // fall through
|
||||
case Bytecodes::_putfield : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
|
||||
case Bytecodes::_invokevirtual : // fall through
|
||||
case Bytecodes::_invokespecial : // fall through
|
||||
case Bytecodes::_invokestatic : // fall through
|
||||
case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break;
|
||||
case Bytecodes::_invokehandle : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); break;
|
||||
case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
|
||||
default:
|
||||
fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(code)));
|
||||
break;
|
||||
}
|
||||
address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
|
||||
// first time invocation - must resolve first
|
||||
__ call_VM(noreg, entry, O1);
|
||||
// Update registers with resolved info
|
||||
|
|
|
@ -2520,22 +2520,7 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
|
|||
__ jcc(Assembler::equal, resolved);
|
||||
|
||||
// resolve first time through
|
||||
address entry;
|
||||
switch (code) {
|
||||
case Bytecodes::_getstatic : // fall through
|
||||
case Bytecodes::_putstatic : // fall through
|
||||
case Bytecodes::_getfield : // fall through
|
||||
case Bytecodes::_putfield : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
|
||||
case Bytecodes::_invokevirtual : // fall through
|
||||
case Bytecodes::_invokespecial : // fall through
|
||||
case Bytecodes::_invokestatic : // fall through
|
||||
case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break;
|
||||
case Bytecodes::_invokehandle : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); break;
|
||||
case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
|
||||
default:
|
||||
fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(code)));
|
||||
break;
|
||||
}
|
||||
address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
|
||||
__ movl(temp, code);
|
||||
__ call_VM(noreg, entry, temp);
|
||||
// Update registers with resolved info
|
||||
|
|
|
@ -1942,7 +1942,7 @@ run:
|
|||
|
||||
cache = cp->entry_at(index);
|
||||
if (!cache->is_resolved((Bytecodes::Code)opcode)) {
|
||||
CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode),
|
||||
CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
|
||||
handle_exception);
|
||||
cache = cp->entry_at(index);
|
||||
}
|
||||
|
@ -2040,7 +2040,7 @@ run:
|
|||
u2 index = Bytes::get_native_u2(pc+1);
|
||||
ConstantPoolCacheEntry* cache = cp->entry_at(index);
|
||||
if (!cache->is_resolved((Bytecodes::Code)opcode)) {
|
||||
CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode),
|
||||
CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
|
||||
handle_exception);
|
||||
cache = cp->entry_at(index);
|
||||
}
|
||||
|
@ -2416,7 +2416,7 @@ run:
|
|||
// This kind of CP cache entry does not need to match the flags byte, because
|
||||
// there is a 1-1 relation between bytecode type and CP entry type.
|
||||
if (! cache->is_resolved((Bytecodes::Code) opcode)) {
|
||||
CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD),
|
||||
CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
|
||||
handle_exception);
|
||||
cache = cp->constant_pool()->invokedynamic_cp_cache_entry_at(index);
|
||||
}
|
||||
|
@ -2447,7 +2447,7 @@ run:
|
|||
ConstantPoolCacheEntry* cache = cp->entry_at(index);
|
||||
|
||||
if (! cache->is_resolved((Bytecodes::Code) opcode)) {
|
||||
CALL_VM(InterpreterRuntime::resolve_invokehandle(THREAD),
|
||||
CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
|
||||
handle_exception);
|
||||
cache = cp->entry_at(index);
|
||||
}
|
||||
|
@ -2480,7 +2480,7 @@ run:
|
|||
|
||||
ConstantPoolCacheEntry* cache = cp->entry_at(index);
|
||||
if (!cache->is_resolved((Bytecodes::Code)opcode)) {
|
||||
CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode),
|
||||
CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
|
||||
handle_exception);
|
||||
cache = cp->entry_at(index);
|
||||
}
|
||||
|
@ -2571,7 +2571,7 @@ run:
|
|||
// out so c++ compiler has a chance for constant prop to fold everything possible away.
|
||||
|
||||
if (!cache->is_resolved((Bytecodes::Code)opcode)) {
|
||||
CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode),
|
||||
CALL_VM(InterpreterRuntime::resolve_from_cache(THREAD, (Bytecodes::Code)opcode),
|
||||
handle_exception);
|
||||
cache = cp->entry_at(index);
|
||||
}
|
||||
|
|
|
@ -537,7 +537,8 @@ IRT_END
|
|||
// Fields
|
||||
//
|
||||
|
||||
IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode))
|
||||
void InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode) {
|
||||
Thread* THREAD = thread;
|
||||
// resolve field
|
||||
fieldDescriptor info;
|
||||
constantPoolHandle pool(thread, method(thread)->constants());
|
||||
|
@ -552,7 +553,8 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode
|
|||
} // end JvmtiHideSingleStepping
|
||||
|
||||
// check if link resolution caused cpCache to be updated
|
||||
if (already_resolved(thread)) return;
|
||||
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());
|
||||
|
@ -580,7 +582,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode
|
|||
}
|
||||
}
|
||||
|
||||
cache_entry(thread)->set_field(
|
||||
cp_cache_entry->set_field(
|
||||
get_code,
|
||||
put_code,
|
||||
info.field_holder(),
|
||||
|
@ -591,7 +593,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode
|
|||
info.access_flags().is_volatile(),
|
||||
pool->pool_holder()
|
||||
);
|
||||
IRT_END
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -686,7 +688,8 @@ IRT_ENTRY(void, InterpreterRuntime::_breakpoint(JavaThread* thread, Method* meth
|
|||
JvmtiExport::post_raw_breakpoint(thread, method, bcp);
|
||||
IRT_END
|
||||
|
||||
IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) {
|
||||
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) {
|
||||
|
@ -710,7 +713,8 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
|
|||
{
|
||||
JvmtiHideSingleStepping jhss(thread);
|
||||
LinkResolver::resolve_invoke(info, receiver, pool,
|
||||
get_index_u2_cpcache(thread, bytecode), bytecode, CHECK);
|
||||
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()) {
|
||||
|
@ -721,13 +725,15 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
|
|||
"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);
|
||||
get_index_u2_cpcache(thread, bytecode), bytecode,
|
||||
CHECK);
|
||||
}
|
||||
}
|
||||
} // end JvmtiHideSingleStepping
|
||||
|
||||
// check if link resolution caused cpCache to be updated
|
||||
if (already_resolved(thread)) return;
|
||||
ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
|
||||
if (cp_cache_entry->is_resolved(bytecode)) return;
|
||||
|
||||
if (bytecode == Bytecodes::_invokeinterface) {
|
||||
if (TraceItables && Verbose) {
|
||||
|
@ -762,18 +768,18 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
|
|||
#endif
|
||||
switch (info.call_kind()) {
|
||||
case CallInfo::direct_call:
|
||||
cache_entry(thread)->set_direct_call(
|
||||
cp_cache_entry->set_direct_call(
|
||||
bytecode,
|
||||
info.resolved_method());
|
||||
break;
|
||||
case CallInfo::vtable_call:
|
||||
cache_entry(thread)->set_vtable_call(
|
||||
cp_cache_entry->set_vtable_call(
|
||||
bytecode,
|
||||
info.resolved_method(),
|
||||
info.vtable_index());
|
||||
break;
|
||||
case CallInfo::itable_call:
|
||||
cache_entry(thread)->set_itable_call(
|
||||
cp_cache_entry->set_itable_call(
|
||||
bytecode,
|
||||
info.resolved_method(),
|
||||
info.itable_index());
|
||||
|
@ -781,30 +787,30 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
|
|||
default: ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
IRT_END
|
||||
|
||||
|
||||
// First time execution: Resolve symbols, create a permanent MethodType object.
|
||||
IRT_ENTRY(void, InterpreterRuntime::resolve_invokehandle(JavaThread* thread)) {
|
||||
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);
|
||||
get_index_u2_cpcache(thread, bytecode), bytecode,
|
||||
CHECK);
|
||||
} // end JvmtiHideSingleStepping
|
||||
|
||||
cache_entry(thread)->set_method_handle(pool, info);
|
||||
ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
|
||||
cp_cache_entry->set_method_handle(pool, info);
|
||||
}
|
||||
IRT_END
|
||||
|
||||
|
||||
// First time execution: Resolve symbols, create a permanent CallSite object.
|
||||
IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) {
|
||||
void InterpreterRuntime::resolve_invokedynamic(JavaThread* thread) {
|
||||
Thread* THREAD = thread;
|
||||
const Bytecodes::Code bytecode = Bytecodes::_invokedynamic;
|
||||
|
||||
//TO DO: consider passing BCI to Java.
|
||||
|
@ -823,8 +829,36 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) {
|
|||
ConstantPoolCacheEntry* cp_cache_entry = pool->invokedynamic_cp_cache_entry_at(index);
|
||||
cp_cache_entry->set_dynamic_call(pool, info);
|
||||
}
|
||||
IRT_END
|
||||
|
||||
// This function is the interface to the assembly code. It returns the resolved
|
||||
// cpCache entry. This doesn't safepoint, but the helper routines safepoint.
|
||||
// This function will check for redefinition!
|
||||
IRT_ENTRY(void, InterpreterRuntime::resolve_from_cache(JavaThread* thread, Bytecodes::Code bytecode)) {
|
||||
switch (bytecode) {
|
||||
case Bytecodes::_getstatic:
|
||||
case Bytecodes::_putstatic:
|
||||
case Bytecodes::_getfield:
|
||||
case Bytecodes::_putfield:
|
||||
resolve_get_put(thread, bytecode);
|
||||
break;
|
||||
case Bytecodes::_invokevirtual:
|
||||
case Bytecodes::_invokespecial:
|
||||
case Bytecodes::_invokestatic:
|
||||
case Bytecodes::_invokeinterface:
|
||||
resolve_invoke(thread, bytecode);
|
||||
break;
|
||||
case Bytecodes::_invokehandle:
|
||||
resolve_invokehandle(thread);
|
||||
break;
|
||||
case Bytecodes::_invokedynamic:
|
||||
resolve_invokedynamic(thread);
|
||||
break;
|
||||
default:
|
||||
fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
IRT_END
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
// Miscellaneous
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -52,7 +52,6 @@ class InterpreterRuntime: AllStatic {
|
|||
// pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
|
||||
return Bytecodes::code_at(method(thread), bcp(thread));
|
||||
}
|
||||
static bool already_resolved(JavaThread *thread) { return cache_entry(thread)->is_resolved(code(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); }
|
||||
|
@ -117,9 +116,17 @@ class InterpreterRuntime: AllStatic {
|
|||
static void note_no_trap(JavaThread* thread, Method *method, int trap_bci) {}
|
||||
#endif // CC_INTERP
|
||||
|
||||
static void resolve_from_cache(JavaThread* thread, Bytecodes::Code bytecode);
|
||||
private:
|
||||
// Statics & fields
|
||||
static void resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode);
|
||||
|
||||
// Calls
|
||||
static void resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode);
|
||||
static void resolve_invokehandle (JavaThread* thread);
|
||||
static void resolve_invokedynamic(JavaThread* thread);
|
||||
|
||||
public:
|
||||
// Synchronization
|
||||
static void monitorenter(JavaThread* thread, BasicObjectLock* elem);
|
||||
static void monitorexit (JavaThread* thread, BasicObjectLock* elem);
|
||||
|
@ -127,11 +134,6 @@ class InterpreterRuntime: AllStatic {
|
|||
static void throw_illegal_monitor_state_exception(JavaThread* thread);
|
||||
static void new_illegal_monitor_state_exception(JavaThread* thread);
|
||||
|
||||
// Calls
|
||||
static void resolve_invoke (JavaThread* thread, Bytecodes::Code bytecode);
|
||||
static void resolve_invokehandle (JavaThread* thread);
|
||||
static void resolve_invokedynamic(JavaThread* thread);
|
||||
|
||||
// Breakpoints
|
||||
static void _breakpoint(JavaThread* thread, Method* method, address bcp);
|
||||
static Bytecodes::Code get_original_bytecode_at(JavaThread* thread, Method* method, address bcp);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue