8076492: Make common code from template interpreter code
authorcoleenp
Wed, 01 Apr 2015 22:03:17 -0400
changeset 30132 1f788eb36811
parent 30130 386d3e9878bc
child 30133 232561e6df52
8076492: Make common code from template interpreter code Summary: Move case statement out of assembly code Reviewed-by: minqi, sspitsyn, dholmes
hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp
hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp
hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
hotspot/src/cpu/x86/vm/templateTable_x86.cpp
hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
hotspot/src/share/vm/interpreter/interpreterRuntime.hpp
--- a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Wed Apr 01 15:27:04 2015 +0200
+++ b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Wed Apr 01 22:03:17 2015 -0400
@@ -2138,30 +2138,7 @@
   __ 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);
 
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Wed Apr 01 15:27:04 2015 +0200
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Wed Apr 01 22:03:17 2015 -0400
@@ -2177,22 +2177,7 @@
   __ 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);
 
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Apr 01 15:27:04 2015 +0200
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Apr 01 22:03:17 2015 -0400
@@ -2070,23 +2070,7 @@
   __ 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
--- a/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Wed Apr 01 15:27:04 2015 +0200
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Wed Apr 01 22:03:17 2015 -0400
@@ -2520,22 +2520,7 @@
   __ 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
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed Apr 01 15:27:04 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed Apr 01 22:03:17 2015 -0400
@@ -1942,7 +1942,7 @@
 
           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 @@
           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 @@
         // 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 @@
         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 @@
 
         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 @@
         // 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);
         }
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Apr 01 15:27:04 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Apr 01 22:03:17 2015 -0400
@@ -537,7 +537,8 @@
 // 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 @@
   } // 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 @@
     }
   }
 
-  cache_entry(thread)->set_field(
+  cp_cache_entry->set_field(
     get_code,
     put_code,
     info.field_holder(),
@@ -591,7 +593,7 @@
     info.access_flags().is_volatile(),
     pool->pool_holder()
   );
-IRT_END
+}
 
 
 //------------------------------------------------------------------------------------------------------------------------
@@ -686,7 +688,8 @@
   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 @@
   {
     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 @@
                   "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 @@
 #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 @@
   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,9 +829,37 @@
   ConstantPoolCacheEntry* cp_cache_entry = pool->invokedynamic_cp_cache_entry_at(index);
   cp_cache_entry->set_dynamic_call(pool, info);
 }
+
+// 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
 
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Wed Apr 01 15:27:04 2015 +0200
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Wed Apr 01 22:03:17 2015 -0400
@@ -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 @@
     // 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 @@
   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);
+  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 @@
   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);