changeset 8536:f8a45a60bc6b

8174962: Better interface invocations Reviewed-by: jrose, coleenp, ahgross, acorn, vlivanov
author dbuck
date Fri, 29 Sep 2017 14:30:05 -0400
parents 2667e5c45e24
children 432f92e99174
files agent/src/share/classes/sun/jvm/hotspot/oops/CompiledICHolder.java src/cpu/ppc/vm/sharedRuntime_ppc.cpp src/cpu/sparc/vm/macroAssembler_sparc.cpp src/cpu/sparc/vm/macroAssembler_sparc.hpp src/cpu/sparc/vm/sharedRuntime_sparc.cpp src/cpu/sparc/vm/templateTable_sparc.cpp src/cpu/sparc/vm/vtableStubs_sparc.cpp src/cpu/x86/vm/macroAssembler_x86.cpp src/cpu/x86/vm/macroAssembler_x86.hpp src/cpu/x86/vm/sharedRuntime_x86_32.cpp src/cpu/x86/vm/sharedRuntime_x86_64.cpp src/cpu/x86/vm/templateTable_x86_32.cpp src/cpu/x86/vm/templateTable_x86_64.cpp src/cpu/x86/vm/vtableStubs_x86_32.cpp src/cpu/x86/vm/vtableStubs_x86_64.cpp src/share/vm/code/compiledIC.cpp src/share/vm/code/compiledIC.hpp src/share/vm/code/nmethod.cpp src/share/vm/interpreter/interpreterRuntime.cpp src/share/vm/oops/compiledICHolder.cpp src/share/vm/oops/compiledICHolder.hpp src/share/vm/oops/cpCache.cpp src/share/vm/oops/cpCache.hpp src/share/vm/oops/klassVtable.cpp src/share/vm/oops/method.hpp src/share/vm/runtime/vmStructs.cpp test/runtime/RedefineTests/RedefineInterfaceCall.java
diffstat 27 files changed, 431 insertions(+), 244 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/CompiledICHolder.java	Tue Aug 08 12:02:01 2017 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/CompiledICHolder.java	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -40,10 +40,10 @@
   }
 
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
-    Type type    = db.lookupType("CompiledICHolder");
-    holderMethod = new MetadataField(type.getAddressField("_holder_method"), 0);
-    holderKlass  = new MetadataField(type.getAddressField("_holder_klass"), 0);
-    headerSize   = type.getSize();
+    Type type      = db.lookupType("CompiledICHolder");
+    holderMetadata = new MetadataField(type.getAddressField("_holder_metadata"), 0);
+    holderKlass    = new MetadataField(type.getAddressField("_holder_klass"), 0);
+    headerSize     = type.getSize();
   }
 
   public CompiledICHolder(Address addr) {
@@ -55,12 +55,12 @@
   private static long headerSize;
 
   // Fields
-  private static MetadataField holderMethod;
+  private static MetadataField holderMetadata;
   private static MetadataField holderKlass;
 
   // Accessors for declared fields
-  public Method getHolderMethod() { return (Method) holderMethod.getValue(this); }
-  public Klass  getHolderKlass()  { return (Klass)  holderKlass.getValue(this); }
+  public Metadata getHolderMetadata() { return (Metadata) holderMetadata.getValue(this); }
+  public Klass    getHolderKlass()    { return (Klass)    holderKlass.getValue(this); }
 
   public void printValueOn(PrintStream tty) {
     tty.print("CompiledICHolder");
--- a/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012, 2014 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -1193,7 +1193,7 @@
   // Argument is valid and klass is as expected, continue.
 
   // Extract method from inline cache, verified entry point needs it.
-  __ ld(R19_method, CompiledICHolder::holder_method_offset(), ic);
+  __ ld(R19_method, CompiledICHolder::holder_metadata_offset(), ic);
   assert(R19_method == ic, "the inline cache register is dead here");
 
   __ ld(code, method_(code));
--- a/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -2183,9 +2183,10 @@
                                              Register method_result,
                                              Register scan_temp,
                                              Register sethi_temp,
-                                             Label& L_no_such_interface) {
+                                             Label& L_no_such_interface,
+                                             bool return_method) {
   assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
-  assert(itable_index.is_constant() || itable_index.as_register() == method_result,
+  assert(!return_method || itable_index.is_constant() || itable_index.as_register() == method_result,
          "caller must use same register for non-constant itable index as for method");
 
   Label L_no_such_interface_restore;
@@ -2229,11 +2230,13 @@
   }
   add(recv_klass, scan_temp, scan_temp);
 
-  // Adjust recv_klass by scaled itable_index, so we can free itable_index.
-  RegisterOrConstant itable_offset = itable_index;
-  itable_offset = regcon_sll_ptr(itable_index, exact_log2(itableMethodEntry::size() * wordSize), itable_offset);
-  itable_offset = regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes(), itable_offset);
-  add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass);
+  if (return_method) {
+    // Adjust recv_klass by scaled itable_index, so we can free itable_index.
+    RegisterOrConstant itable_offset = itable_index;
+    itable_offset = regcon_sll_ptr(itable_index, exact_log2(itableMethodEntry::size() * wordSize), itable_offset);
+    itable_offset = regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes(), itable_offset);
+    add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass);
+  }
 
   // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
   //   if (scan->interface() == intf) {
@@ -2268,12 +2271,14 @@
 
   bind(L_found_method);
 
-  // Got a hit.
-  int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
-  // scan_temp[-scan_step] points to the vtable offset we need
-  ito_offset -= scan_step;
-  lduw(scan_temp, ito_offset, scan_temp);
-  ld_ptr(recv_klass, scan_temp, method_result);
+  if (return_method) {
+    // Got a hit.
+    int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
+    // scan_temp[-scan_step] points to the vtable offset we need
+    ito_offset -= scan_step;
+    lduw(scan_temp, ito_offset, scan_temp);
+    ld_ptr(recv_klass, scan_temp, method_result);
+  }
 
   if (did_save) {
     Label L_done;
--- a/src/cpu/sparc/vm/macroAssembler_sparc.hpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/sparc/vm/macroAssembler_sparc.hpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -1347,7 +1347,8 @@
                                RegisterOrConstant itable_index,
                                Register method_result,
                                Register temp_reg, Register temp2_reg,
-                               Label& no_such_interface);
+                               Label& no_such_interface,
+                               bool return_method = true);
 
   // virtual method calling
   void lookup_virtual_method(Register recv_klass,
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -1045,7 +1045,7 @@
 
     Label ok, ok2;
     __ brx(Assembler::equal, false, Assembler::pt, ok);
-    __ delayed()->ld_ptr(G5_method, CompiledICHolder::holder_method_offset(), G5_method);
+    __ delayed()->ld_ptr(G5_method, CompiledICHolder::holder_metadata_offset(), G5_method);
     __ jump_to(ic_miss, G3_scratch);
     __ delayed()->nop();
 
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -3165,15 +3165,15 @@
   assert(byte_no == f1_byte, "use this argument");
 
   const Register Rinterface  = G1_scratch;
+  const Register Rmethod     = Lscratch;
   const Register Rret        = G3_scratch;
-  const Register Rindex      = Lscratch;
   const Register O0_recv     = O0;
   const Register O1_flags    = O1;
   const Register O2_Klass    = O2;
   const Register Rscratch    = G4_scratch;
   assert_different_registers(Rscratch, G5_method);
 
-  prepare_invoke(byte_no, Rinterface, Rret, Rindex, O0_recv, O1_flags);
+  prepare_invoke(byte_no, Rinterface, Rret, Rmethod, O0_recv, O1_flags);
 
   // get receiver klass
   __ null_check(O0_recv, oopDesc::klass_offset_in_bytes());
@@ -3193,58 +3193,40 @@
 
   __ bind(notMethod);
 
+  Register Rtemp = O1_flags;
+
+  Label L_no_such_interface;
+
+  // Receiver subtype check against REFC.
+  __ lookup_interface_method(// inputs: rec. class, interface, itable index
+                             O2_Klass, Rinterface, noreg,
+                             // outputs: temp reg1, temp reg2, temp reg3
+                             G5_method, Rscratch, Rtemp,
+                             L_no_such_interface,
+                             /*return_method=*/false);
+
   __ profile_virtual_call(O2_Klass, O4);
 
   //
   // find entry point to call
   //
 
-  // compute start of first itableOffsetEntry (which is at end of vtable)
-  const int base = InstanceKlass::vtable_start_offset() * wordSize;
-  Label search;
-  Register Rtemp = O1_flags;
-
-  __ ld(O2_Klass, InstanceKlass::vtable_length_offset() * wordSize, Rtemp);
-  if (align_object_offset(1) > 1) {
-    __ round_to(Rtemp, align_object_offset(1));
-  }
-  __ sll(Rtemp, LogBytesPerWord, Rtemp);   // Rscratch *= 4;
-  if (Assembler::is_simm13(base)) {
-    __ add(Rtemp, base, Rtemp);
-  } else {
-    __ set(base, Rscratch);
-    __ add(Rscratch, Rtemp, Rtemp);
-  }
-  __ add(O2_Klass, Rtemp, Rscratch);
-
-  __ bind(search);
-
-  __ ld_ptr(Rscratch, itableOffsetEntry::interface_offset_in_bytes(), Rtemp);
-  {
-    Label ok;
-
-    // Check that entry is non-null.  Null entries are probably a bytecode
-    // problem.  If the interface isn't implemented by the receiver class,
-    // the VM should throw IncompatibleClassChangeError.  linkResolver checks
-    // this too but that's only if the entry isn't already resolved, so we
-    // need to check again.
-    __ br_notnull_short( Rtemp, Assembler::pt, ok);
-    call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
-    __ should_not_reach_here();
-    __ bind(ok);
-  }
-
-  __ cmp(Rinterface, Rtemp);
-  __ brx(Assembler::notEqual, true, Assembler::pn, search);
-  __ delayed()->add(Rscratch, itableOffsetEntry::size() * wordSize, Rscratch);
-
-  // entry found and Rscratch points to it
-  __ ld(Rscratch, itableOffsetEntry::offset_offset_in_bytes(), Rscratch);
-
-  assert(itableMethodEntry::method_offset_in_bytes() == 0, "adjust instruction below");
-  __ sll(Rindex, exact_log2(itableMethodEntry::size() * wordSize), Rindex);       // Rindex *= 8;
-  __ add(Rscratch, Rindex, Rscratch);
-  __ ld_ptr(O2_Klass, Rscratch, G5_method);
+  // Get declaring interface class from method
+  __ ld_ptr(Rmethod, Method::const_offset(), Rinterface);
+  __ ld_ptr(Rinterface, ConstMethod::constants_offset(), Rinterface);
+  __ ld_ptr(Rinterface, ConstantPool::pool_holder_offset_in_bytes(), Rinterface);
+
+  // Get itable index from method
+  const Register Rindex = G5_method;
+  __ ld(Rmethod, Method::itable_index_offset(), Rindex);
+  __ sub(Rindex, Method::itable_index_max, Rindex);
+  __ neg(Rindex);
+
+  __ lookup_interface_method(// inputs: rec. class, interface, itable index
+                             O2_Klass, Rinterface, Rindex,
+                             // outputs: method, scan temp reg, temp reg
+                             G5_method, Rscratch, Rtemp,
+                             L_no_such_interface);
 
   // Check for abstract method error.
   {
@@ -3260,6 +3242,10 @@
 
   __ profile_arguments_type(G5_method, Rcall, Gargs, true);
   __ call_from_interpreter(Rcall, Gargs, Rret);
+
+  __ bind(L_no_such_interface);
+  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
+  __ should_not_reach_here();
 }
 
 void TemplateTable::invokehandle(int byte_no) {
--- a/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -27,6 +27,7 @@
 #include "code/vtableStubs.hpp"
 #include "interp_masm_sparc.hpp"
 #include "memory/resourceArea.hpp"
+#include "oops/compiledICHolder.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/klassVtable.hpp"
 #include "runtime/sharedRuntime.hpp"
@@ -140,7 +141,8 @@
   MacroAssembler* masm = new MacroAssembler(&cb);
 
   Register G3_Klass = G3_scratch;
-  Register G5_interface = G5;  // Passed in as an argument
+  Register G5_icholder = G5;  // Passed in as an argument
+  Register G4_interface = G4_scratch;
   Label search;
 
   // Entry arguments:
@@ -164,14 +166,26 @@
   }
 #endif /* PRODUCT */
 
-  Label throw_icce;
+  Label L_no_such_interface;
 
   Register L5_method = L5;
+
+  // Receiver subtype check against REFC.
+  __ ld_ptr(G5_icholder, CompiledICHolder::holder_klass_offset(), G4_interface);
   __ lookup_interface_method(// inputs: rec. class, interface, itable index
-                             G3_Klass, G5_interface, itable_index,
+                             G3_Klass, G4_interface, itable_index,
+                             // outputs: scan temp. reg1, scan temp. reg2
+                             L5_method, L2, L3,
+                             L_no_such_interface,
+                             /*return_method=*/ false);
+
+  // Get Method* and entrypoint for compiler
+  __ ld_ptr(G5_icholder, CompiledICHolder::holder_metadata_offset(), G4_interface);
+  __ lookup_interface_method(// inputs: rec. class, interface, itable index
+                             G3_Klass, G4_interface, itable_index,
                              // outputs: method, scan temp. reg
                              L5_method, L2, L3,
-                             throw_icce);
+                             L_no_such_interface);
 
 #ifndef PRODUCT
   if (DebugVtables) {
@@ -197,7 +211,7 @@
   __ JMP(G3_scratch, 0);
   __ delayed()->nop();
 
-  __ bind(throw_icce);
+  __ bind(L_no_such_interface);
   AddressLiteral icce(StubRoutines::throw_IncompatibleClassChangeError_entry());
   __ jump_to(icce, G3_scratch);
   __ delayed()->restore();
@@ -232,7 +246,7 @@
                           MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
       return basic + slop;
     } else {
-      const int basic = (28 LP64_ONLY(+ 6)) * BytesPerInstWord +
+      const int basic = (48 LP64_ONLY(+ 6)) * BytesPerInstWord +
                         // shift;add for load_klass (only shift with zero heap based)
                         (UseCompressedClassPointers ?
                           MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
--- a/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/x86/vm/macroAssembler_x86.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -4853,8 +4853,13 @@
                                              RegisterOrConstant itable_index,
                                              Register method_result,
                                              Register scan_temp,
-                                             Label& L_no_such_interface) {
-  assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
+                                             Label& L_no_such_interface,
+                                             bool return_method) {
+  assert_different_registers(recv_klass, intf_klass, scan_temp);
+  assert_different_registers(method_result, intf_klass, scan_temp);
+  assert(recv_klass != method_result || !return_method,
+         "recv_klass can be destroyed when method isn't needed");
+
   assert(itable_index.is_constant() || itable_index.as_register() == method_result,
          "caller must use same register for non-constant itable index as for method");
 
@@ -4876,9 +4881,11 @@
     round_to(scan_temp, BytesPerLong);
   }
 
-  // Adjust recv_klass by scaled itable_index, so we can free itable_index.
-  assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
-  lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
+  if (return_method) {
+    // Adjust recv_klass by scaled itable_index, so we can free itable_index.
+    assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
+    lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
+  }
 
   // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
   //   if (scan->interface() == intf) {
@@ -4912,9 +4919,11 @@
 
   bind(found_method);
 
-  // Got a hit.
-  movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
-  movptr(method_result, Address(recv_klass, scan_temp, Address::times_1));
+  if (return_method) {
+    // Got a hit.
+    movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
+    movptr(method_result, Address(recv_klass, scan_temp, Address::times_1));
+  }
 }
 
 
--- a/src/cpu/x86/vm/macroAssembler_x86.hpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/x86/vm/macroAssembler_x86.hpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -525,7 +525,8 @@
                                RegisterOrConstant itable_index,
                                Register method_result,
                                Register scan_temp,
-                               Label& no_such_interface);
+                               Label& no_such_interface,
+                               bool return_method = true);
 
   // virtual method calling
   void lookup_virtual_method(Register recv_klass,
--- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -955,7 +955,7 @@
     Label missed;
     __ movptr(temp, Address(receiver, oopDesc::klass_offset_in_bytes()));
     __ cmpptr(temp, Address(holder, CompiledICHolder::holder_klass_offset()));
-    __ movptr(rbx, Address(holder, CompiledICHolder::holder_method_offset()));
+    __ movptr(rbx, Address(holder, CompiledICHolder::holder_metadata_offset()));
     __ jcc(Assembler::notEqual, missed);
     // Method might have been compiled since the call site was patched to
     // interpreted if that is the case treat it as a miss so we can get
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -869,7 +869,7 @@
   {
     __ load_klass(temp, receiver);
     __ cmpptr(temp, Address(holder, CompiledICHolder::holder_klass_offset()));
-    __ movptr(rbx, Address(holder, CompiledICHolder::holder_method_offset()));
+    __ movptr(rbx, Address(holder, CompiledICHolder::holder_metadata_offset()));
     __ jcc(Assembler::equal, ok);
     __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
 
--- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -3099,11 +3099,11 @@
 void TemplateTable::invokeinterface(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f1_byte, "use this argument");
-  prepare_invoke(byte_no, rax, rbx,  // get f1 Klass*, f2 itable index
+  prepare_invoke(byte_no, rax, rbx,  // get f1 Klass*, f2 Method*
                  rcx, rdx); // recv, flags
 
-  // rax: interface klass (from f1)
-  // rbx: itable index (from f2)
+  // rax: reference klass (from f1)
+  // rbx: method (from f2)
   // rcx: receiver
   // rdx: flags
 
@@ -3124,10 +3124,29 @@
   __ null_check(rcx, oopDesc::klass_offset_in_bytes());
   __ load_klass(rdx, rcx);
 
+  Label no_such_interface, no_such_method;
+
+  // Receiver subtype check against REFC.
+  // Superklass in rax. Subklass in rdx. Blows rcx, rdi.
+  __ lookup_interface_method(// inputs: rec. class, interface, itable index
+                             rdx, rax, noreg,
+                             // outputs: scan temp. reg, scan temp. reg
+                             rsi, rdi,
+                             no_such_interface,
+                             /*return_method=*/false);
+
+
   // profile this call
+  __ restore_bcp(); // rbcp was destroyed by receiver type check
   __ profile_virtual_call(rdx, rsi, rdi);
 
-  Label no_such_interface, no_such_method;
+  // Get declaring interface class from method, and itable index
+  __ movptr(rax, Address(rbx, Method::const_offset()));
+  __ movptr(rax, Address(rax, ConstMethod::constants_offset()));
+  __ movptr(rax, Address(rax, ConstantPool::pool_holder_offset_in_bytes()));
+  __ movl(rbx, Address(rbx, Method::itable_index_offset()));
+  __ subl(rbx, Method::itable_index_max);
+  __ negl(rbx);
 
   __ lookup_interface_method(// inputs: rec. class, interface, itable index
                              rdx, rax, rbx,
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -3150,11 +3150,11 @@
 void TemplateTable::invokeinterface(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f1_byte, "use this argument");
-  prepare_invoke(byte_no, rax, rbx,  // get f1 Klass*, f2 itable index
+  prepare_invoke(byte_no, rax, rbx,  // get f1 Klass*, f2 Method*
                  rcx, rdx); // recv, flags
 
-  // rax: interface klass (from f1)
-  // rbx: itable index (from f2)
+  // rax: reference klass (from f1)
+  // rbx: method (from f2)
   // rcx: receiver
   // rdx: flags
 
@@ -3175,10 +3175,28 @@
   __ null_check(rcx, oopDesc::klass_offset_in_bytes());
   __ load_klass(rdx, rcx);
 
+  Label no_such_interface, no_such_method;
+
+  // Receiver subtype check against REFC.
+  // Superklass in rax. Subklass in rdx. Blows rcx, rdi.
+  __ lookup_interface_method(// inputs: rec. class, interface, itable index
+                             rdx, rax, noreg,
+                             // outputs: scan temp. reg, scan temp. reg
+                             r13, r14,
+                             no_such_interface,
+                             /*return_method=*/false);
+
   // profile this call
+  __ restore_bcp(); // rbcp was destroyed by receiver type check
   __ profile_virtual_call(rdx, r13, r14);
 
-  Label no_such_interface, no_such_method;
+  // Get declaring interface class from method, and itable index
+  __ movptr(rax, Address(rbx, Method::const_offset()));
+  __ movptr(rax, Address(rax, ConstMethod::constants_offset()));
+  __ movptr(rax, Address(rax, ConstantPool::pool_holder_offset_in_bytes()));
+  __ movl(rbx, Address(rbx, Method::itable_index_offset()));
+  __ subl(rbx, Method::itable_index_max);
+  __ negl(rbx);
 
   __ lookup_interface_method(// inputs: rec. class, interface, itable index
                              rdx, rax, rbx,
--- a/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -27,6 +27,7 @@
 #include "code/vtableStubs.hpp"
 #include "interp_masm_x86.hpp"
 #include "memory/resourceArea.hpp"
+#include "oops/compiledICHolder.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/klassVtable.hpp"
 #include "runtime/sharedRuntime.hpp"
@@ -147,7 +148,7 @@
   MacroAssembler* masm = new MacroAssembler(&cb);
 
   // Entry arguments:
-  //  rax,: Interface
+  //  rax: CompiledICHolder
   //  rcx: Receiver
 
 #ifndef PRODUCT
@@ -155,25 +156,42 @@
     __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
   }
 #endif /* PRODUCT */
-  // get receiver (need to skip return address on top of stack)
 
-  assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx");
+  // Most registers are in use; we'll use rax, rbx, rsi, rdi
+  // (If we need to make rsi, rdi callee-save, do a push/pop here.)
+  const Register recv_klass_reg     = rsi;
+  const Register holder_klass_reg   = rax; // declaring interface klass (DECC)
+  const Register resolved_klass_reg = rbx; // resolved interface klass (REFC)
+  const Register temp_reg           = rdi;
+
+  const Register icholder_reg = rax;
+  __ movptr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset()));
+  __ movptr(holder_klass_reg,   Address(icholder_reg, CompiledICHolder::holder_metadata_offset()));
+
+  Label L_no_such_interface;
 
   // get receiver klass (also an implicit null-check)
   address npe_addr = __ pc();
-  __ movptr(rsi, Address(rcx, oopDesc::klass_offset_in_bytes()));
+  assert(VtableStub::receiver_location() ==  rcx->as_VMReg(), "receiver expected in  rcx");
+  __ load_klass(recv_klass_reg, rcx);
 
-  // Most registers are in use; we'll use rax, rbx, rsi, rdi
-  // (If we need to make rsi, rdi callee-save, do a push/pop here.)
+  // Receiver subtype check against REFC.
+  // Destroys recv_klass_reg value.
+  __ lookup_interface_method(// inputs: rec. class, interface
+                             recv_klass_reg, resolved_klass_reg, noreg,
+                             // outputs:  scan temp. reg1, scan temp. reg2
+                             recv_klass_reg, temp_reg,
+                             L_no_such_interface,
+                             /*return_method=*/false);
+
+  // Get selected method from declaring class and itable index
   const Register method = rbx;
-  Label throw_icce;
-
-  // Get Method* and entrypoint for compiler
+  __ load_klass(recv_klass_reg, rcx); // restore recv_klass_reg
   __ lookup_interface_method(// inputs: rec. class, interface, itable index
-                             rsi, rax, itable_index,
+                             recv_klass_reg, holder_klass_reg, itable_index,
                              // outputs: method, scan temp. reg
-                             method, rdi,
-                             throw_icce);
+                             method, temp_reg,
+                             L_no_such_interface);
 
   // method (rbx): Method*
   // rcx: receiver
@@ -193,9 +211,10 @@
   address ame_addr = __ pc();
   __ jmp(Address(method, Method::from_compiled_offset()));
 
-  __ bind(throw_icce);
+  __ bind(L_no_such_interface);
   __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
-  masm->flush();
+
+  __ flush();
 
   if (PrintMiscellaneous && (WizardMode || Verbose)) {
     tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
@@ -220,7 +239,7 @@
     return (DebugVtables ? 210 : 16) + (CountCompiledCalls ? 6 : 0);
   } else {
     // Itable stub size
-    return (DebugVtables ? 256 : 66) + (CountCompiledCalls ? 6 : 0);
+    return (DebugVtables ? 256 : 116) + (CountCompiledCalls ? 6 : 0);
   }
   // In order to tune these parameters, run the JVM with VM options
   // +PrintMiscellaneous and +WizardMode to see information about
--- a/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -27,6 +27,7 @@
 #include "code/vtableStubs.hpp"
 #include "interp_masm_x86.hpp"
 #include "memory/resourceArea.hpp"
+#include "oops/compiledICHolder.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/klassVtable.hpp"
 #include "runtime/sharedRuntime.hpp"
@@ -149,36 +150,50 @@
 #endif
 
   // Entry arguments:
-  //  rax: Interface
+  //  rax: CompiledICHolder
   //  j_rarg0: Receiver
 
-  // Free registers (non-args) are rax (interface), rbx
-
-  // get receiver (need to skip return address on top of stack)
-
-  assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
-  // get receiver klass (also an implicit null-check)
-  address npe_addr = __ pc();
-
   // Most registers are in use; we'll use rax, rbx, r10, r11
   // (various calling sequences use r[cd]x, r[sd]i, r[89]; stay away from them)
-  __ load_klass(r10, j_rarg0);
+  const Register recv_klass_reg     = r10;
+  const Register holder_klass_reg   = rax; // declaring interface klass (DECC)
+  const Register resolved_klass_reg = rbx; // resolved interface klass (REFC)
+  const Register temp_reg           = r11;
+
+  Label L_no_such_interface;
+
+  const Register icholder_reg = rax;
+  __ movptr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset()));
+  __ movptr(holder_klass_reg,   Address(icholder_reg, CompiledICHolder::holder_metadata_offset()));
+
+  // get receiver klass (also an implicit null-check)
+  assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
+  address npe_addr = __ pc();
+  __ load_klass(recv_klass_reg, j_rarg0);
+
+  // Receiver subtype check against REFC.
+  // Destroys recv_klass_reg value.
+  __ lookup_interface_method(// inputs: rec. class, interface
+                             recv_klass_reg, resolved_klass_reg, noreg,
+                             // outputs:  scan temp. reg1, scan temp. reg2
+                             recv_klass_reg, temp_reg,
+                             L_no_such_interface,
+                             /*return_method=*/false);
+
+  // Get selected method from declaring class and itable index
+  const Register method = rbx;
+  __ load_klass(recv_klass_reg, j_rarg0);   // restore recv_klass_reg
+  __ lookup_interface_method(// inputs: rec. class, interface, itable index
+                       recv_klass_reg, holder_klass_reg, itable_index,
+                       // outputs: method, scan temp. reg
+                       method, temp_reg,
+                       L_no_such_interface);
 
   // If we take a trap while this arg is on the stack we will not
   // be able to walk the stack properly. This is not an issue except
   // when there are mistakes in this assembly code that could generate
   // a spurious fault. Ask me how I know...
 
-  const Register method = rbx;
-  Label throw_icce;
-
-  // Get Method* and entrypoint for compiler
-  __ lookup_interface_method(// inputs: rec. class, interface, itable index
-                             r10, rax, itable_index,
-                             // outputs: method, scan temp. reg
-                             method, r11,
-                             throw_icce);
-
   // method (rbx): Method*
   // j_rarg0: receiver
 
@@ -199,7 +214,7 @@
   address ame_addr = __ pc();
   __ jmp(Address(method, Method::from_compiled_offset()));
 
-  __ bind(throw_icce);
+  __ bind(L_no_such_interface);
   __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
 
   __ flush();
@@ -226,8 +241,8 @@
            (UseCompressedClassPointers ?  MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
   } else {
     // Itable stub size
-    return (DebugVtables ? 512 : 74) + (CountCompiledCalls ? 13 : 0) +
-           (UseCompressedClassPointers ?  MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
+    return (DebugVtables ? 512 : 140) + (CountCompiledCalls ? 13 : 0) +
+           (UseCompressedClassPointers ? 2 * MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
   }
   // In order to tune these parameters, run the JVM with VM options
   // +PrintMiscellaneous and +WizardMode to see information about
--- a/src/share/vm/code/compiledIC.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/share/vm/code/compiledIC.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -228,10 +228,13 @@
 #ifdef ASSERT
     int index = call_info->resolved_method()->itable_index();
     assert(index == itable_index, "CallInfo pre-computes this");
-#endif //ASSERT
     InstanceKlass* k = call_info->resolved_method()->method_holder();
     assert(k->verify_itable_index(itable_index), "sanity check");
-    InlineCacheBuffer::create_transition_stub(this, k, entry);
+#endif //ASSERT
+    CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(),
+                                                    call_info->resolved_klass()());
+    holder->claim();
+    InlineCacheBuffer::create_transition_stub(this, holder, entry);
   } else {
     assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable");
     // Can be different than selected_method->vtable_index(), due to package-private etc.
@@ -527,7 +530,14 @@
 
 bool CompiledIC::is_icholder_entry(address entry) {
   CodeBlob* cb = CodeCache::find_blob_unsafe(entry);
-  return (cb != NULL && cb->is_adapter_blob());
+  if (cb != NULL && cb->is_adapter_blob()) {
+    return true;
+  }
+  // itable stubs also use CompiledICHolder
+  if (VtableStubs::is_entry_point(entry) && VtableStubs::stub_containing(entry)->is_itable_stub()) {
+    return true;
+  }
+  return false;
 }
 
 // ----------------------------------------------------------------------------
--- a/src/share/vm/code/compiledIC.hpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/share/vm/code/compiledIC.hpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -59,11 +59,11 @@
 //          \                        /   \     /
 //       [4] \                      / [4] \->-/
 //            \->-  Megamorphic -<-/
-//                  (Method*)
+//              (CompiledICHolder*)
 //
-// The text in paranteses () refere to the value of the inline cache receiver (mov instruction)
+// The text in parentheses () refers to the value of the inline cache receiver (mov instruction)
 //
-// The numbers in square brackets refere to the kind of transition:
+// The numbers in square brackets refer to the kind of transition:
 // [1]: Initial fixup. Receiver it found from debug information
 // [2]: Compilation of a method
 // [3]: Recompilation of a method (note: only entry is changed. The Klass* must stay the same)
--- a/src/share/vm/code/nmethod.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/share/vm/code/nmethod.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1748,12 +1748,11 @@
     CompiledICHolder* cichk_oop = ic->cached_icholder();
 
     if (mark_on_stack) {
-      Metadata::mark_on_stack(cichk_oop->holder_method());
+      Metadata::mark_on_stack(cichk_oop->holder_metadata());
       Metadata::mark_on_stack(cichk_oop->holder_klass());
     }
 
-    if (cichk_oop->holder_method()->method_holder()->is_loader_alive(is_alive) &&
-        cichk_oop->holder_klass()->is_loader_alive(is_alive)) {
+    if (cichk_oop->is_loader_alive(is_alive)) {
       return;
     }
   } else {
@@ -2180,7 +2179,7 @@
         CompiledIC *ic = CompiledIC_at(&iter);
         if (ic->is_icholder_call()) {
           CompiledICHolder* cichk = ic->cached_icholder();
-          f(cichk->holder_method());
+          f(cichk->holder_metadata());
           f(cichk->holder_klass());
         } else {
           Metadata* ic_oop = ic->cached_metadata();
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -786,6 +786,7 @@
   case CallInfo::itable_call:
     cache_entry(thread)->set_itable_call(
       bytecode,
+      info.resolved_klass(),
       info.resolved_method(),
       info.itable_index());
     break;
--- a/src/share/vm/oops/compiledICHolder.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/share/vm/oops/compiledICHolder.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -32,12 +32,28 @@
 volatile int CompiledICHolder::_live_not_claimed_count;
 
 
+bool CompiledICHolder::is_loader_alive(BoolObjectClosure* is_alive) {
+  if (_holder_metadata->is_method()) {
+    if (!((Method*)_holder_metadata)->method_holder()->is_loader_alive(is_alive)) {
+      return false;
+    }
+  } else if (_holder_metadata->is_klass()) {
+    if (!((Klass*)_holder_metadata)->is_loader_alive(is_alive)) {
+      return false;
+    }
+  }
+  if (!_holder_klass->is_loader_alive(is_alive)) {
+    return false;
+  }
+  return true;
+}
+
 // Printing
 
 void CompiledICHolder::print_on(outputStream* st) const {
   st->print("%s", internal_name());
-  st->print(" - method: "); holder_method()->print_value_on(st); st->cr();
-  st->print(" - klass:  "); holder_klass()->print_value_on(st); st->cr();
+  st->print(" - metadata: "); holder_metadata()->print_value_on(st); st->cr();
+  st->print(" - klass:    "); holder_klass()->print_value_on(st); st->cr();
 }
 
 void CompiledICHolder::print_value_on(outputStream* st) const {
@@ -48,6 +64,6 @@
 // Verification
 
 void CompiledICHolder::verify_on(outputStream* st) {
-  guarantee(holder_method()->is_method(), "should be method");
+  guarantee(holder_metadata()->is_method() || holder_metadata()->is_klass(), "should be method or klass");
   guarantee(holder_klass()->is_klass(),   "should be klass");
 }
--- a/src/share/vm/oops/compiledICHolder.hpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/share/vm/oops/compiledICHolder.hpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -28,8 +28,9 @@
 #include "oops/oop.hpp"
 
 // A CompiledICHolder* is a helper object for the inline cache implementation.
-// It holds an intermediate value (method+klass pair) used when converting from
-// compiled to an interpreted call.
+// It holds:
+//   (1) (method+klass pair) when converting from compiled to an interpreted call
+//   (2) (klass+klass pair) when calling itable stub from megamorphic compiled call
 //
 // These are always allocated in the C heap and are freed during a
 // safepoint by the ICBuffer logic.  It's unsafe to free them earlier
@@ -44,14 +45,14 @@
   static volatile int _live_not_claimed_count; // allocated but not yet in use so not
                                                // reachable by iterating over nmethods
 
-  Method* _holder_method;
+  Metadata* _holder_metadata;
   Klass*    _holder_klass;    // to avoid name conflict with oopDesc::_klass
   CompiledICHolder* _next;
 
  public:
   // Constructor
-  CompiledICHolder(Method* method, Klass* klass)
-      : _holder_method(method), _holder_klass(klass) {
+  CompiledICHolder(Metadata* metadata, Klass* klass)
+      : _holder_metadata(metadata), _holder_klass(klass) {
 #ifdef ASSERT
     Atomic::inc(&_live_count);
     Atomic::inc(&_live_not_claimed_count);
@@ -69,19 +70,20 @@
   static int live_not_claimed_count() { return _live_not_claimed_count; }
 
   // accessors
-  Method* holder_method() const     { return _holder_method; }
   Klass*    holder_klass()  const     { return _holder_klass; }
+  Metadata* holder_metadata() const   { return _holder_metadata; }
 
-  void set_holder_method(Method* m) { _holder_method = m; }
-  void set_holder_klass(Klass* k)   { _holder_klass = k; }
+  void set_holder_metadata(Metadata* m) { _holder_metadata = m; }
+  void set_holder_klass(Klass* k)     { _holder_klass = k; }
 
-  // interpreter support (offsets in bytes)
-  static int holder_method_offset()   { return offset_of(CompiledICHolder, _holder_method); }
+  static int holder_metadata_offset() { return offset_of(CompiledICHolder, _holder_metadata); }
   static int holder_klass_offset()    { return offset_of(CompiledICHolder, _holder_klass); }
 
   CompiledICHolder* next()     { return _next; }
   void set_next(CompiledICHolder* n) { _next = n; }
 
+  bool is_loader_alive(BoolObjectClosure* is_alive);
+
   // Verify
   void verify_on(outputStream* st);
 
--- a/src/share/vm/oops/cpCache.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/share/vm/oops/cpCache.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -259,14 +259,16 @@
   set_direct_or_vtable_call(invoke_code, method, index, false);
 }
 
-void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
+void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code,
+                                                        KlassHandle referenced_klass,
+                                                        methodHandle method, int index) {
   assert(method->method_holder()->verify_itable_index(index), "");
   assert(invoke_code == Bytecodes::_invokeinterface, "");
   InstanceKlass* interf = method->method_holder();
   assert(interf->is_interface(), "must be an interface");
   assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");
-  set_f1(interf);
-  set_f2(index);
+  set_f1(referenced_klass());
+  set_f2((intx)method());
   set_method_flags(as_TosState(method->result_type()),
                    0,  // no option bits
                    method()->size_of_parameters());
@@ -433,10 +435,27 @@
 
 
 #if INCLUDE_JVMTI
+
+void log_adjust(const char* entry_type, Method* old_method, Method* new_method, bool* trace_name_printed) {
+  if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+    if (!(*trace_name_printed)) {
+      // RC_TRACE_MESG macro has an embedded ResourceMark
+      RC_TRACE_MESG(("adjust: name=%s",
+        old_method->method_holder()->external_name()));
+      *trace_name_printed = true;
+    }
+    // RC_TRACE macro has an embedded ResourceMark
+    RC_TRACE(0x00400000, ("cpc %s entry update: %s(%s)",
+      entry_type,
+      new_method->name()->as_C_string(),
+      new_method->signature()->as_C_string()));
+  }
+}
+
 // RedefineClasses() API support:
 // If this ConstantPoolCacheEntry refers to old_method then update it
 // to refer to new_method.
-bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
+void ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
        Method* new_method, bool * trace_name_printed) {
 
   if (is_vfinal()) {
@@ -445,69 +464,34 @@
       // match old_method so need an update
       // NOTE: can't use set_f2_as_vfinal_method as it asserts on different values
       _f2 = (intptr_t)new_method;
-      if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
-        if (!(*trace_name_printed)) {
-          // RC_TRACE_MESG macro has an embedded ResourceMark
-          RC_TRACE_MESG(("adjust: name=%s",
-            old_method->method_holder()->external_name()));
-          *trace_name_printed = true;
-        }
-        // RC_TRACE macro has an embedded ResourceMark
-        RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)",
-          new_method->name()->as_C_string(),
-          new_method->signature()->as_C_string()));
-      }
-      return true;
     }
-
-    // f1() is not used with virtual entries so bail out
-    return false;
+    return;
   }
 
-  if (_f1 == NULL) {
-    // NULL f1() means this is a virtual entry so bail out
-    // We are assuming that the vtable index does not need change.
-    return false;
+  assert (_f1 != NULL, "should not call with uninteresting entry");
+
+  if (!(_f1->is_method())) {
+    // _f1 is a Klass* for an interface, _f2 is the method
+    if (f2_as_interface_method() == old_method) {
+      _f2 = (intptr_t)new_method;
+      log_adjust("interface", old_method, new_method, trace_name_printed);
+    }
+  } else if (_f1 == old_method) {
+    _f1 = new_method;
+    log_adjust("special, static or dynamic", old_method, new_method, trace_name_printed);
   }
-
-  if (_f1 == old_method) {
-    _f1 = new_method;
-    if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
-      if (!(*trace_name_printed)) {
-        // RC_TRACE_MESG macro has an embedded ResourceMark
-        RC_TRACE_MESG(("adjust: name=%s",
-          old_method->method_holder()->external_name()));
-        *trace_name_printed = true;
-      }
-      // RC_TRACE macro has an embedded ResourceMark
-      RC_TRACE(0x00400000, ("cpc entry update: %s(%s)",
-        new_method->name()->as_C_string(),
-        new_method->signature()->as_C_string()));
-    }
-    return true;
-  }
-
-  return false;
 }
 
 // a constant pool cache entry should never contain old or obsolete methods
 bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() {
-  if (is_vfinal()) {
-    // virtual and final so _f2 contains method ptr instead of vtable index
-    Metadata* f2 = (Metadata*)_f2;
-    // Return false if _f2 refers to an old or an obsolete method.
-    // _f2 == NULL || !_f2->is_method() are just as unexpected here.
-    return (f2 != NULL NOT_PRODUCT(&& f2->is_valid()) && f2->is_method() &&
-            !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete());
-  } else if (_f1 == NULL ||
-             (NOT_PRODUCT(_f1->is_valid() &&) !_f1->is_method())) {
-    // _f1 == NULL || !_f1->is_method() are OK here
+  Method* m = get_interesting_method_entry(NULL);
+  // return false if m refers to a non-deleted old or obsolete method
+  if (m != NULL) {
+    assert(m->is_valid() && m->is_method(), "m is a valid method");
+    return !m->is_old() && !m->is_obsolete(); // old is always set for old and obsolete
+  } else {
     return true;
   }
-  // return false if _f1 refers to a non-deleted old or obsolete method
-  return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() &&
-          (f1_as_method()->is_deleted() ||
-          (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete())));
 }
 
 Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) {
@@ -524,10 +508,11 @@
     return NULL;
   } else {
     if (!(_f1->is_method())) {
-      // _f1 can also contain a Klass* for an interface
-      return NULL;
+      // _f1 is a Klass* for an interface
+      m = f2_as_interface_method();
+    } else {
+      m = f1_as_method();
     }
-    m = f1_as_method();
   }
   assert(m != NULL && m->is_method(), "sanity check");
   if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {
--- a/src/share/vm/oops/cpCache.hpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/share/vm/oops/cpCache.hpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -248,6 +248,7 @@
 
   void set_itable_call(
     Bytecodes::Code invoke_code,                 // the bytecode used; must be invokeinterface
+    KlassHandle referenced_klass,                // the referenced klass in the InterfaceMethodref
     methodHandle method,                         // the resolved interface method
     int itable_index                             // index into itable for the method
   );
@@ -344,6 +345,7 @@
   bool      is_f1_null() const                   { Metadata* f1 = f1_ord(); return f1 == NULL; }  // classifies a CPC entry as unbound
   int       f2_as_index() const                  { assert(!is_vfinal(), ""); return (int) _f2; }
   Method*   f2_as_vfinal_method() const          { assert(is_vfinal(), ""); return (Method*)_f2; }
+  Method*   f2_as_interface_method() const       { assert(bytecode_1() == Bytecodes::_invokeinterface, ""); return (Method*)_f2; }
   int  field_index() const                       { assert(is_field_entry(),  ""); return (_flags & field_index_mask); }
   int  parameter_size() const                    { assert(is_method_entry(), ""); return (_flags & parameter_size_mask); }
   bool is_volatile() const                       { return (_flags & (1 << is_volatile_shift))       != 0; }
@@ -374,7 +376,7 @@
   // trace_name_printed is set to true if the current call has
   // printed the klass name so that other routines in the adjust_*
   // group don't print the klass name.
-  bool adjust_method_entry(Method* old_method, Method* new_method,
+  void adjust_method_entry(Method* old_method, Method* new_method,
          bool* trace_name_printed);
   bool check_no_old_or_obsolete_entries();
   Method* get_interesting_method_entry(Klass* k);
--- a/src/share/vm/oops/klassVtable.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/share/vm/oops/klassVtable.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1204,7 +1204,6 @@
   Array<Method*>* methods = InstanceKlass::cast(interf_h())->methods();
   int nof_methods = methods->length();
   HandleMark hm;
-  assert(nof_methods > 0, "at least one method must exist for interface to be in vtable");
   Handle interface_loader (THREAD, InstanceKlass::cast(interf_h())->class_loader());
 
   int ime_count = method_count_for_interface(interf_h());
@@ -1386,8 +1385,10 @@
       }
     }
 
-    // Only count interfaces with at least one method
-    if (method_count > 0) {
+    // Visit all interfaces which either have any methods or can participate in receiver type check.
+    // We do not bother to count methods in transitive interfaces, although that would allow us to skip
+    // this step in the rare case of a zero-method interface extending another zero-method interface.
+    if (method_count > 0 || InstanceKlass::cast(intf)->transitive_interfaces()->length() > 0) {
       blk->doit(intf, method_count);
     }
   }
--- a/src/share/vm/oops/method.hpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/share/vm/oops/method.hpp	Fri Sep 29 14:30:05 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -661,6 +661,7 @@
   static ByteSize from_interpreted_offset()      { return byte_offset_of(Method, _from_interpreted_entry ); }
   static ByteSize interpreter_entry_offset()     { return byte_offset_of(Method, _i2i_entry ); }
   static ByteSize signature_handler_offset()     { return in_ByteSize(sizeof(Method) + wordSize);      }
+  static ByteSize itable_index_offset()          { return byte_offset_of(Method, _vtable_index ); }
 
   // for code generation
   static int method_data_offset_in_bytes()       { return offset_of(Method, _method_data); }
--- a/src/share/vm/runtime/vmStructs.cpp	Tue Aug 08 12:02:01 2017 +0100
+++ b/src/share/vm/runtime/vmStructs.cpp	Fri Sep 29 14:30:05 2017 -0400
@@ -278,7 +278,7 @@
   volatile_nonstatic_field(ArrayKlass,         _lower_dimension,                              Klass*)                                \
   nonstatic_field(ArrayKlass,                  _vtable_len,                                   int)                                   \
   nonstatic_field(ArrayKlass,                  _component_mirror,                             oop)                                   \
-  nonstatic_field(CompiledICHolder,     _holder_method,                                Method*)                               \
+  nonstatic_field(CompiledICHolder,     _holder_metadata,                              Metadata*)                             \
   nonstatic_field(CompiledICHolder,     _holder_klass,                                 Klass*)                                \
   nonstatic_field(ConstantPool,         _tags,                                         Array<u1>*)                            \
   nonstatic_field(ConstantPool,         _cache,                                        ConstantPoolCache*)                    \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/RedefineTests/RedefineInterfaceCall.java	Fri Sep 29 14:30:05 2017 -0400
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8174962
+ * @summary Redefine class with interface method call
+ * @library /testlibrary /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.compiler
+ *          java.instrument
+ *          jdk.jartool/sun.tools.jar
+ * @run main RedefineClassHelper
+ * @run main/othervm -javaagent:redefineagent.jar RedefineInterfaceCall
+ */
+
+import static jdk.testlibrary.Asserts.assertEquals;
+
+interface I1 { default int m() { return 0; } }
+interface I2 extends I1 {}
+
+public class RedefineInterfaceCall {
+
+    public static class C implements I2 {
+        public int test(I2 i) {
+            return i.m(); // invokeinterface cpCacheEntry
+        }
+    }
+
+    static String newI1 =
+      "interface I1 { default int m() { return 1; } }";
+
+    static String newC =
+        "public class RedefineInterfaceCall$C implements I2 { " +
+        "  public int test(I2 i) { " +
+        "    return i.m(); " +
+        "  } " +
+        "} ";
+
+    static int test(I2 i) {
+        return i.m(); // invokeinterface cpCacheEntry
+    }
+
+    public static void main(String[] args) throws Exception {
+        C c = new C();
+
+        assertEquals(test(c),   0);
+        assertEquals(c.test(c), 0);
+
+        RedefineClassHelper.redefineClass(C.class, newC);
+
+        assertEquals(c.test(c), 0);
+
+        RedefineClassHelper.redefineClass(I1.class, newI1);
+
+        assertEquals(test(c),   1);
+        assertEquals(c.test(c), 1);
+
+        RedefineClassHelper.redefineClass(C.class, newC);
+
+        assertEquals(c.test(c), 1);
+    }
+}