8174962: Better interface invocations

Fri, 29 Sep 2017 14:30:05 -0400

author
dbuck
date
Fri, 29 Sep 2017 14:30:05 -0400
changeset 8997
f8a45a60bc6b
parent 8996
2667e5c45e24
child 9008
432f92e99174

8174962: Better interface invocations
Reviewed-by: jrose, coleenp, ahgross, acorn, vlivanov

agent/src/share/classes/sun/jvm/hotspot/oops/CompiledICHolder.java file | annotate | diff | comparison | revisions
src/cpu/ppc/vm/sharedRuntime_ppc.cpp file | annotate | diff | comparison | revisions
src/cpu/sparc/vm/macroAssembler_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/sparc/vm/macroAssembler_sparc.hpp file | annotate | diff | comparison | revisions
src/cpu/sparc/vm/sharedRuntime_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/sparc/vm/templateTable_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/sparc/vm/vtableStubs_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/macroAssembler_x86.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/macroAssembler_x86.hpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/sharedRuntime_x86_32.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/sharedRuntime_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/templateTable_x86_32.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/templateTable_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/vtableStubs_x86_32.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/vtableStubs_x86_64.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/compiledIC.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/compiledIC.hpp file | annotate | diff | comparison | revisions
src/share/vm/code/nmethod.cpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/interpreterRuntime.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/compiledICHolder.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/compiledICHolder.hpp file | annotate | diff | comparison | revisions
src/share/vm/oops/cpCache.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/cpCache.hpp file | annotate | diff | comparison | revisions
src/share/vm/oops/klassVtable.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/method.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/vmStructs.cpp file | annotate | diff | comparison | revisions
test/runtime/RedefineTests/RedefineInterfaceCall.java file | annotate | diff | comparison | revisions
     1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/CompiledICHolder.java	Tue Aug 08 12:02:01 2017 +0100
     1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/CompiledICHolder.java	Fri Sep 29 14:30:05 2017 -0400
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -40,10 +40,10 @@
    1.11    }
    1.12  
    1.13    private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
    1.14 -    Type type    = db.lookupType("CompiledICHolder");
    1.15 -    holderMethod = new MetadataField(type.getAddressField("_holder_method"), 0);
    1.16 -    holderKlass  = new MetadataField(type.getAddressField("_holder_klass"), 0);
    1.17 -    headerSize   = type.getSize();
    1.18 +    Type type      = db.lookupType("CompiledICHolder");
    1.19 +    holderMetadata = new MetadataField(type.getAddressField("_holder_metadata"), 0);
    1.20 +    holderKlass    = new MetadataField(type.getAddressField("_holder_klass"), 0);
    1.21 +    headerSize     = type.getSize();
    1.22    }
    1.23  
    1.24    public CompiledICHolder(Address addr) {
    1.25 @@ -55,12 +55,12 @@
    1.26    private static long headerSize;
    1.27  
    1.28    // Fields
    1.29 -  private static MetadataField holderMethod;
    1.30 +  private static MetadataField holderMetadata;
    1.31    private static MetadataField holderKlass;
    1.32  
    1.33    // Accessors for declared fields
    1.34 -  public Method getHolderMethod() { return (Method) holderMethod.getValue(this); }
    1.35 -  public Klass  getHolderKlass()  { return (Klass)  holderKlass.getValue(this); }
    1.36 +  public Metadata getHolderMetadata() { return (Metadata) holderMetadata.getValue(this); }
    1.37 +  public Klass    getHolderKlass()    { return (Klass)    holderKlass.getValue(this); }
    1.38  
    1.39    public void printValueOn(PrintStream tty) {
    1.40      tty.print("CompiledICHolder");
     2.1 --- a/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Tue Aug 08 12:02:01 2017 +0100
     2.2 +++ b/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Fri Sep 29 14:30:05 2017 -0400
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     2.7   * Copyright 2012, 2014 SAP AG. All rights reserved.
     2.8   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.9   *
    2.10 @@ -1193,7 +1193,7 @@
    2.11    // Argument is valid and klass is as expected, continue.
    2.12  
    2.13    // Extract method from inline cache, verified entry point needs it.
    2.14 -  __ ld(R19_method, CompiledICHolder::holder_method_offset(), ic);
    2.15 +  __ ld(R19_method, CompiledICHolder::holder_metadata_offset(), ic);
    2.16    assert(R19_method == ic, "the inline cache register is dead here");
    2.17  
    2.18    __ ld(code, method_(code));
     3.1 --- a/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Tue Aug 08 12:02:01 2017 +0100
     3.2 +++ b/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Fri Sep 29 14:30:05 2017 -0400
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -2183,9 +2183,10 @@
    3.11                                               Register method_result,
    3.12                                               Register scan_temp,
    3.13                                               Register sethi_temp,
    3.14 -                                             Label& L_no_such_interface) {
    3.15 +                                             Label& L_no_such_interface,
    3.16 +                                             bool return_method) {
    3.17    assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
    3.18 -  assert(itable_index.is_constant() || itable_index.as_register() == method_result,
    3.19 +  assert(!return_method || itable_index.is_constant() || itable_index.as_register() == method_result,
    3.20           "caller must use same register for non-constant itable index as for method");
    3.21  
    3.22    Label L_no_such_interface_restore;
    3.23 @@ -2229,11 +2230,13 @@
    3.24    }
    3.25    add(recv_klass, scan_temp, scan_temp);
    3.26  
    3.27 -  // Adjust recv_klass by scaled itable_index, so we can free itable_index.
    3.28 -  RegisterOrConstant itable_offset = itable_index;
    3.29 -  itable_offset = regcon_sll_ptr(itable_index, exact_log2(itableMethodEntry::size() * wordSize), itable_offset);
    3.30 -  itable_offset = regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes(), itable_offset);
    3.31 -  add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass);
    3.32 +  if (return_method) {
    3.33 +    // Adjust recv_klass by scaled itable_index, so we can free itable_index.
    3.34 +    RegisterOrConstant itable_offset = itable_index;
    3.35 +    itable_offset = regcon_sll_ptr(itable_index, exact_log2(itableMethodEntry::size() * wordSize), itable_offset);
    3.36 +    itable_offset = regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes(), itable_offset);
    3.37 +    add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass);
    3.38 +  }
    3.39  
    3.40    // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
    3.41    //   if (scan->interface() == intf) {
    3.42 @@ -2268,12 +2271,14 @@
    3.43  
    3.44    bind(L_found_method);
    3.45  
    3.46 -  // Got a hit.
    3.47 -  int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
    3.48 -  // scan_temp[-scan_step] points to the vtable offset we need
    3.49 -  ito_offset -= scan_step;
    3.50 -  lduw(scan_temp, ito_offset, scan_temp);
    3.51 -  ld_ptr(recv_klass, scan_temp, method_result);
    3.52 +  if (return_method) {
    3.53 +    // Got a hit.
    3.54 +    int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
    3.55 +    // scan_temp[-scan_step] points to the vtable offset we need
    3.56 +    ito_offset -= scan_step;
    3.57 +    lduw(scan_temp, ito_offset, scan_temp);
    3.58 +    ld_ptr(recv_klass, scan_temp, method_result);
    3.59 +  }
    3.60  
    3.61    if (did_save) {
    3.62      Label L_done;
     4.1 --- a/src/cpu/sparc/vm/macroAssembler_sparc.hpp	Tue Aug 08 12:02:01 2017 +0100
     4.2 +++ b/src/cpu/sparc/vm/macroAssembler_sparc.hpp	Fri Sep 29 14:30:05 2017 -0400
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     4.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -1347,7 +1347,8 @@
    4.11                                 RegisterOrConstant itable_index,
    4.12                                 Register method_result,
    4.13                                 Register temp_reg, Register temp2_reg,
    4.14 -                               Label& no_such_interface);
    4.15 +                               Label& no_such_interface,
    4.16 +                               bool return_method = true);
    4.17  
    4.18    // virtual method calling
    4.19    void lookup_virtual_method(Register recv_klass,
     5.1 --- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Tue Aug 08 12:02:01 2017 +0100
     5.2 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Fri Sep 29 14:30:05 2017 -0400
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -1045,7 +1045,7 @@
    5.11  
    5.12      Label ok, ok2;
    5.13      __ brx(Assembler::equal, false, Assembler::pt, ok);
    5.14 -    __ delayed()->ld_ptr(G5_method, CompiledICHolder::holder_method_offset(), G5_method);
    5.15 +    __ delayed()->ld_ptr(G5_method, CompiledICHolder::holder_metadata_offset(), G5_method);
    5.16      __ jump_to(ic_miss, G3_scratch);
    5.17      __ delayed()->nop();
    5.18  
     6.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Tue Aug 08 12:02:01 2017 +0100
     6.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Fri Sep 29 14:30:05 2017 -0400
     6.3 @@ -1,5 +1,5 @@
     6.4  /*
     6.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     6.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     6.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.8   *
     6.9   * This code is free software; you can redistribute it and/or modify it
    6.10 @@ -3165,15 +3165,15 @@
    6.11    assert(byte_no == f1_byte, "use this argument");
    6.12  
    6.13    const Register Rinterface  = G1_scratch;
    6.14 +  const Register Rmethod     = Lscratch;
    6.15    const Register Rret        = G3_scratch;
    6.16 -  const Register Rindex      = Lscratch;
    6.17    const Register O0_recv     = O0;
    6.18    const Register O1_flags    = O1;
    6.19    const Register O2_Klass    = O2;
    6.20    const Register Rscratch    = G4_scratch;
    6.21    assert_different_registers(Rscratch, G5_method);
    6.22  
    6.23 -  prepare_invoke(byte_no, Rinterface, Rret, Rindex, O0_recv, O1_flags);
    6.24 +  prepare_invoke(byte_no, Rinterface, Rret, Rmethod, O0_recv, O1_flags);
    6.25  
    6.26    // get receiver klass
    6.27    __ null_check(O0_recv, oopDesc::klass_offset_in_bytes());
    6.28 @@ -3193,58 +3193,40 @@
    6.29  
    6.30    __ bind(notMethod);
    6.31  
    6.32 +  Register Rtemp = O1_flags;
    6.33 +
    6.34 +  Label L_no_such_interface;
    6.35 +
    6.36 +  // Receiver subtype check against REFC.
    6.37 +  __ lookup_interface_method(// inputs: rec. class, interface, itable index
    6.38 +                             O2_Klass, Rinterface, noreg,
    6.39 +                             // outputs: temp reg1, temp reg2, temp reg3
    6.40 +                             G5_method, Rscratch, Rtemp,
    6.41 +                             L_no_such_interface,
    6.42 +                             /*return_method=*/false);
    6.43 +
    6.44    __ profile_virtual_call(O2_Klass, O4);
    6.45  
    6.46    //
    6.47    // find entry point to call
    6.48    //
    6.49  
    6.50 -  // compute start of first itableOffsetEntry (which is at end of vtable)
    6.51 -  const int base = InstanceKlass::vtable_start_offset() * wordSize;
    6.52 -  Label search;
    6.53 -  Register Rtemp = O1_flags;
    6.54 -
    6.55 -  __ ld(O2_Klass, InstanceKlass::vtable_length_offset() * wordSize, Rtemp);
    6.56 -  if (align_object_offset(1) > 1) {
    6.57 -    __ round_to(Rtemp, align_object_offset(1));
    6.58 -  }
    6.59 -  __ sll(Rtemp, LogBytesPerWord, Rtemp);   // Rscratch *= 4;
    6.60 -  if (Assembler::is_simm13(base)) {
    6.61 -    __ add(Rtemp, base, Rtemp);
    6.62 -  } else {
    6.63 -    __ set(base, Rscratch);
    6.64 -    __ add(Rscratch, Rtemp, Rtemp);
    6.65 -  }
    6.66 -  __ add(O2_Klass, Rtemp, Rscratch);
    6.67 -
    6.68 -  __ bind(search);
    6.69 -
    6.70 -  __ ld_ptr(Rscratch, itableOffsetEntry::interface_offset_in_bytes(), Rtemp);
    6.71 -  {
    6.72 -    Label ok;
    6.73 -
    6.74 -    // Check that entry is non-null.  Null entries are probably a bytecode
    6.75 -    // problem.  If the interface isn't implemented by the receiver class,
    6.76 -    // the VM should throw IncompatibleClassChangeError.  linkResolver checks
    6.77 -    // this too but that's only if the entry isn't already resolved, so we
    6.78 -    // need to check again.
    6.79 -    __ br_notnull_short( Rtemp, Assembler::pt, ok);
    6.80 -    call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
    6.81 -    __ should_not_reach_here();
    6.82 -    __ bind(ok);
    6.83 -  }
    6.84 -
    6.85 -  __ cmp(Rinterface, Rtemp);
    6.86 -  __ brx(Assembler::notEqual, true, Assembler::pn, search);
    6.87 -  __ delayed()->add(Rscratch, itableOffsetEntry::size() * wordSize, Rscratch);
    6.88 -
    6.89 -  // entry found and Rscratch points to it
    6.90 -  __ ld(Rscratch, itableOffsetEntry::offset_offset_in_bytes(), Rscratch);
    6.91 -
    6.92 -  assert(itableMethodEntry::method_offset_in_bytes() == 0, "adjust instruction below");
    6.93 -  __ sll(Rindex, exact_log2(itableMethodEntry::size() * wordSize), Rindex);       // Rindex *= 8;
    6.94 -  __ add(Rscratch, Rindex, Rscratch);
    6.95 -  __ ld_ptr(O2_Klass, Rscratch, G5_method);
    6.96 +  // Get declaring interface class from method
    6.97 +  __ ld_ptr(Rmethod, Method::const_offset(), Rinterface);
    6.98 +  __ ld_ptr(Rinterface, ConstMethod::constants_offset(), Rinterface);
    6.99 +  __ ld_ptr(Rinterface, ConstantPool::pool_holder_offset_in_bytes(), Rinterface);
   6.100 +
   6.101 +  // Get itable index from method
   6.102 +  const Register Rindex = G5_method;
   6.103 +  __ ld(Rmethod, Method::itable_index_offset(), Rindex);
   6.104 +  __ sub(Rindex, Method::itable_index_max, Rindex);
   6.105 +  __ neg(Rindex);
   6.106 +
   6.107 +  __ lookup_interface_method(// inputs: rec. class, interface, itable index
   6.108 +                             O2_Klass, Rinterface, Rindex,
   6.109 +                             // outputs: method, scan temp reg, temp reg
   6.110 +                             G5_method, Rscratch, Rtemp,
   6.111 +                             L_no_such_interface);
   6.112  
   6.113    // Check for abstract method error.
   6.114    {
   6.115 @@ -3260,6 +3242,10 @@
   6.116  
   6.117    __ profile_arguments_type(G5_method, Rcall, Gargs, true);
   6.118    __ call_from_interpreter(Rcall, Gargs, Rret);
   6.119 +
   6.120 +  __ bind(L_no_such_interface);
   6.121 +  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
   6.122 +  __ should_not_reach_here();
   6.123  }
   6.124  
   6.125  void TemplateTable::invokehandle(int byte_no) {
     7.1 --- a/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Tue Aug 08 12:02:01 2017 +0100
     7.2 +++ b/src/cpu/sparc/vm/vtableStubs_sparc.cpp	Fri Sep 29 14:30:05 2017 -0400
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     7.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     7.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.8   *
     7.9   * This code is free software; you can redistribute it and/or modify it
    7.10 @@ -27,6 +27,7 @@
    7.11  #include "code/vtableStubs.hpp"
    7.12  #include "interp_masm_sparc.hpp"
    7.13  #include "memory/resourceArea.hpp"
    7.14 +#include "oops/compiledICHolder.hpp"
    7.15  #include "oops/instanceKlass.hpp"
    7.16  #include "oops/klassVtable.hpp"
    7.17  #include "runtime/sharedRuntime.hpp"
    7.18 @@ -140,7 +141,8 @@
    7.19    MacroAssembler* masm = new MacroAssembler(&cb);
    7.20  
    7.21    Register G3_Klass = G3_scratch;
    7.22 -  Register G5_interface = G5;  // Passed in as an argument
    7.23 +  Register G5_icholder = G5;  // Passed in as an argument
    7.24 +  Register G4_interface = G4_scratch;
    7.25    Label search;
    7.26  
    7.27    // Entry arguments:
    7.28 @@ -164,14 +166,26 @@
    7.29    }
    7.30  #endif /* PRODUCT */
    7.31  
    7.32 -  Label throw_icce;
    7.33 +  Label L_no_such_interface;
    7.34  
    7.35    Register L5_method = L5;
    7.36 +
    7.37 +  // Receiver subtype check against REFC.
    7.38 +  __ ld_ptr(G5_icholder, CompiledICHolder::holder_klass_offset(), G4_interface);
    7.39    __ lookup_interface_method(// inputs: rec. class, interface, itable index
    7.40 -                             G3_Klass, G5_interface, itable_index,
    7.41 +                             G3_Klass, G4_interface, itable_index,
    7.42 +                             // outputs: scan temp. reg1, scan temp. reg2
    7.43 +                             L5_method, L2, L3,
    7.44 +                             L_no_such_interface,
    7.45 +                             /*return_method=*/ false);
    7.46 +
    7.47 +  // Get Method* and entrypoint for compiler
    7.48 +  __ ld_ptr(G5_icholder, CompiledICHolder::holder_metadata_offset(), G4_interface);
    7.49 +  __ lookup_interface_method(// inputs: rec. class, interface, itable index
    7.50 +                             G3_Klass, G4_interface, itable_index,
    7.51                               // outputs: method, scan temp. reg
    7.52                               L5_method, L2, L3,
    7.53 -                             throw_icce);
    7.54 +                             L_no_such_interface);
    7.55  
    7.56  #ifndef PRODUCT
    7.57    if (DebugVtables) {
    7.58 @@ -197,7 +211,7 @@
    7.59    __ JMP(G3_scratch, 0);
    7.60    __ delayed()->nop();
    7.61  
    7.62 -  __ bind(throw_icce);
    7.63 +  __ bind(L_no_such_interface);
    7.64    AddressLiteral icce(StubRoutines::throw_IncompatibleClassChangeError_entry());
    7.65    __ jump_to(icce, G3_scratch);
    7.66    __ delayed()->restore();
    7.67 @@ -232,7 +246,7 @@
    7.68                            MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
    7.69        return basic + slop;
    7.70      } else {
    7.71 -      const int basic = (28 LP64_ONLY(+ 6)) * BytesPerInstWord +
    7.72 +      const int basic = (48 LP64_ONLY(+ 6)) * BytesPerInstWord +
    7.73                          // shift;add for load_klass (only shift with zero heap based)
    7.74                          (UseCompressedClassPointers ?
    7.75                            MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
     8.1 --- a/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Aug 08 12:02:01 2017 +0100
     8.2 +++ b/src/cpu/x86/vm/macroAssembler_x86.cpp	Fri Sep 29 14:30:05 2017 -0400
     8.3 @@ -1,5 +1,5 @@
     8.4  /*
     8.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     8.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     8.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.8   *
     8.9   * This code is free software; you can redistribute it and/or modify it
    8.10 @@ -4853,8 +4853,13 @@
    8.11                                               RegisterOrConstant itable_index,
    8.12                                               Register method_result,
    8.13                                               Register scan_temp,
    8.14 -                                             Label& L_no_such_interface) {
    8.15 -  assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
    8.16 +                                             Label& L_no_such_interface,
    8.17 +                                             bool return_method) {
    8.18 +  assert_different_registers(recv_klass, intf_klass, scan_temp);
    8.19 +  assert_different_registers(method_result, intf_klass, scan_temp);
    8.20 +  assert(recv_klass != method_result || !return_method,
    8.21 +         "recv_klass can be destroyed when method isn't needed");
    8.22 +
    8.23    assert(itable_index.is_constant() || itable_index.as_register() == method_result,
    8.24           "caller must use same register for non-constant itable index as for method");
    8.25  
    8.26 @@ -4876,9 +4881,11 @@
    8.27      round_to(scan_temp, BytesPerLong);
    8.28    }
    8.29  
    8.30 -  // Adjust recv_klass by scaled itable_index, so we can free itable_index.
    8.31 -  assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
    8.32 -  lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
    8.33 +  if (return_method) {
    8.34 +    // Adjust recv_klass by scaled itable_index, so we can free itable_index.
    8.35 +    assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
    8.36 +    lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
    8.37 +  }
    8.38  
    8.39    // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
    8.40    //   if (scan->interface() == intf) {
    8.41 @@ -4912,9 +4919,11 @@
    8.42  
    8.43    bind(found_method);
    8.44  
    8.45 -  // Got a hit.
    8.46 -  movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
    8.47 -  movptr(method_result, Address(recv_klass, scan_temp, Address::times_1));
    8.48 +  if (return_method) {
    8.49 +    // Got a hit.
    8.50 +    movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
    8.51 +    movptr(method_result, Address(recv_klass, scan_temp, Address::times_1));
    8.52 +  }
    8.53  }
    8.54  
    8.55  
     9.1 --- a/src/cpu/x86/vm/macroAssembler_x86.hpp	Tue Aug 08 12:02:01 2017 +0100
     9.2 +++ b/src/cpu/x86/vm/macroAssembler_x86.hpp	Fri Sep 29 14:30:05 2017 -0400
     9.3 @@ -1,5 +1,5 @@
     9.4  /*
     9.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     9.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     9.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.8   *
     9.9   * This code is free software; you can redistribute it and/or modify it
    9.10 @@ -525,7 +525,8 @@
    9.11                                 RegisterOrConstant itable_index,
    9.12                                 Register method_result,
    9.13                                 Register scan_temp,
    9.14 -                               Label& no_such_interface);
    9.15 +                               Label& no_such_interface,
    9.16 +                               bool return_method = true);
    9.17  
    9.18    // virtual method calling
    9.19    void lookup_virtual_method(Register recv_klass,
    10.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Tue Aug 08 12:02:01 2017 +0100
    10.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Fri Sep 29 14:30:05 2017 -0400
    10.3 @@ -1,5 +1,5 @@
    10.4  /*
    10.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
    10.6 + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
    10.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.8   *
    10.9   * This code is free software; you can redistribute it and/or modify it
   10.10 @@ -955,7 +955,7 @@
   10.11      Label missed;
   10.12      __ movptr(temp, Address(receiver, oopDesc::klass_offset_in_bytes()));
   10.13      __ cmpptr(temp, Address(holder, CompiledICHolder::holder_klass_offset()));
   10.14 -    __ movptr(rbx, Address(holder, CompiledICHolder::holder_method_offset()));
   10.15 +    __ movptr(rbx, Address(holder, CompiledICHolder::holder_metadata_offset()));
   10.16      __ jcc(Assembler::notEqual, missed);
   10.17      // Method might have been compiled since the call site was patched to
   10.18      // interpreted if that is the case treat it as a miss so we can get
    11.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Tue Aug 08 12:02:01 2017 +0100
    11.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Sep 29 14:30:05 2017 -0400
    11.3 @@ -1,5 +1,5 @@
    11.4  /*
    11.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
    11.6 + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
    11.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.8   *
    11.9   * This code is free software; you can redistribute it and/or modify it
   11.10 @@ -869,7 +869,7 @@
   11.11    {
   11.12      __ load_klass(temp, receiver);
   11.13      __ cmpptr(temp, Address(holder, CompiledICHolder::holder_klass_offset()));
   11.14 -    __ movptr(rbx, Address(holder, CompiledICHolder::holder_method_offset()));
   11.15 +    __ movptr(rbx, Address(holder, CompiledICHolder::holder_metadata_offset()));
   11.16      __ jcc(Assembler::equal, ok);
   11.17      __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
   11.18  
    12.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Tue Aug 08 12:02:01 2017 +0100
    12.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Fri Sep 29 14:30:05 2017 -0400
    12.3 @@ -1,5 +1,5 @@
    12.4  /*
    12.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
    12.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
    12.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.8   *
    12.9   * This code is free software; you can redistribute it and/or modify it
   12.10 @@ -3099,11 +3099,11 @@
   12.11  void TemplateTable::invokeinterface(int byte_no) {
   12.12    transition(vtos, vtos);
   12.13    assert(byte_no == f1_byte, "use this argument");
   12.14 -  prepare_invoke(byte_no, rax, rbx,  // get f1 Klass*, f2 itable index
   12.15 +  prepare_invoke(byte_no, rax, rbx,  // get f1 Klass*, f2 Method*
   12.16                   rcx, rdx); // recv, flags
   12.17  
   12.18 -  // rax: interface klass (from f1)
   12.19 -  // rbx: itable index (from f2)
   12.20 +  // rax: reference klass (from f1)
   12.21 +  // rbx: method (from f2)
   12.22    // rcx: receiver
   12.23    // rdx: flags
   12.24  
   12.25 @@ -3124,10 +3124,29 @@
   12.26    __ null_check(rcx, oopDesc::klass_offset_in_bytes());
   12.27    __ load_klass(rdx, rcx);
   12.28  
   12.29 +  Label no_such_interface, no_such_method;
   12.30 +
   12.31 +  // Receiver subtype check against REFC.
   12.32 +  // Superklass in rax. Subklass in rdx. Blows rcx, rdi.
   12.33 +  __ lookup_interface_method(// inputs: rec. class, interface, itable index
   12.34 +                             rdx, rax, noreg,
   12.35 +                             // outputs: scan temp. reg, scan temp. reg
   12.36 +                             rsi, rdi,
   12.37 +                             no_such_interface,
   12.38 +                             /*return_method=*/false);
   12.39 +
   12.40 +
   12.41    // profile this call
   12.42 +  __ restore_bcp(); // rbcp was destroyed by receiver type check
   12.43    __ profile_virtual_call(rdx, rsi, rdi);
   12.44  
   12.45 -  Label no_such_interface, no_such_method;
   12.46 +  // Get declaring interface class from method, and itable index
   12.47 +  __ movptr(rax, Address(rbx, Method::const_offset()));
   12.48 +  __ movptr(rax, Address(rax, ConstMethod::constants_offset()));
   12.49 +  __ movptr(rax, Address(rax, ConstantPool::pool_holder_offset_in_bytes()));
   12.50 +  __ movl(rbx, Address(rbx, Method::itable_index_offset()));
   12.51 +  __ subl(rbx, Method::itable_index_max);
   12.52 +  __ negl(rbx);
   12.53  
   12.54    __ lookup_interface_method(// inputs: rec. class, interface, itable index
   12.55                               rdx, rax, rbx,
    13.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Tue Aug 08 12:02:01 2017 +0100
    13.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Fri Sep 29 14:30:05 2017 -0400
    13.3 @@ -1,5 +1,5 @@
    13.4  /*
    13.5 - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
    13.6 + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
    13.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.8   *
    13.9   * This code is free software; you can redistribute it and/or modify it
   13.10 @@ -3150,11 +3150,11 @@
   13.11  void TemplateTable::invokeinterface(int byte_no) {
   13.12    transition(vtos, vtos);
   13.13    assert(byte_no == f1_byte, "use this argument");
   13.14 -  prepare_invoke(byte_no, rax, rbx,  // get f1 Klass*, f2 itable index
   13.15 +  prepare_invoke(byte_no, rax, rbx,  // get f1 Klass*, f2 Method*
   13.16                   rcx, rdx); // recv, flags
   13.17  
   13.18 -  // rax: interface klass (from f1)
   13.19 -  // rbx: itable index (from f2)
   13.20 +  // rax: reference klass (from f1)
   13.21 +  // rbx: method (from f2)
   13.22    // rcx: receiver
   13.23    // rdx: flags
   13.24  
   13.25 @@ -3175,10 +3175,28 @@
   13.26    __ null_check(rcx, oopDesc::klass_offset_in_bytes());
   13.27    __ load_klass(rdx, rcx);
   13.28  
   13.29 +  Label no_such_interface, no_such_method;
   13.30 +
   13.31 +  // Receiver subtype check against REFC.
   13.32 +  // Superklass in rax. Subklass in rdx. Blows rcx, rdi.
   13.33 +  __ lookup_interface_method(// inputs: rec. class, interface, itable index
   13.34 +                             rdx, rax, noreg,
   13.35 +                             // outputs: scan temp. reg, scan temp. reg
   13.36 +                             r13, r14,
   13.37 +                             no_such_interface,
   13.38 +                             /*return_method=*/false);
   13.39 +
   13.40    // profile this call
   13.41 +  __ restore_bcp(); // rbcp was destroyed by receiver type check
   13.42    __ profile_virtual_call(rdx, r13, r14);
   13.43  
   13.44 -  Label no_such_interface, no_such_method;
   13.45 +  // Get declaring interface class from method, and itable index
   13.46 +  __ movptr(rax, Address(rbx, Method::const_offset()));
   13.47 +  __ movptr(rax, Address(rax, ConstMethod::constants_offset()));
   13.48 +  __ movptr(rax, Address(rax, ConstantPool::pool_holder_offset_in_bytes()));
   13.49 +  __ movl(rbx, Address(rbx, Method::itable_index_offset()));
   13.50 +  __ subl(rbx, Method::itable_index_max);
   13.51 +  __ negl(rbx);
   13.52  
   13.53    __ lookup_interface_method(// inputs: rec. class, interface, itable index
   13.54                               rdx, rax, rbx,
    14.1 --- a/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Tue Aug 08 12:02:01 2017 +0100
    14.2 +++ b/src/cpu/x86/vm/vtableStubs_x86_32.cpp	Fri Sep 29 14:30:05 2017 -0400
    14.3 @@ -1,5 +1,5 @@
    14.4  /*
    14.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
    14.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
    14.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.8   *
    14.9   * This code is free software; you can redistribute it and/or modify it
   14.10 @@ -27,6 +27,7 @@
   14.11  #include "code/vtableStubs.hpp"
   14.12  #include "interp_masm_x86.hpp"
   14.13  #include "memory/resourceArea.hpp"
   14.14 +#include "oops/compiledICHolder.hpp"
   14.15  #include "oops/instanceKlass.hpp"
   14.16  #include "oops/klassVtable.hpp"
   14.17  #include "runtime/sharedRuntime.hpp"
   14.18 @@ -147,7 +148,7 @@
   14.19    MacroAssembler* masm = new MacroAssembler(&cb);
   14.20  
   14.21    // Entry arguments:
   14.22 -  //  rax,: Interface
   14.23 +  //  rax: CompiledICHolder
   14.24    //  rcx: Receiver
   14.25  
   14.26  #ifndef PRODUCT
   14.27 @@ -155,25 +156,42 @@
   14.28      __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
   14.29    }
   14.30  #endif /* PRODUCT */
   14.31 -  // get receiver (need to skip return address on top of stack)
   14.32  
   14.33 -  assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx");
   14.34 +  // Most registers are in use; we'll use rax, rbx, rsi, rdi
   14.35 +  // (If we need to make rsi, rdi callee-save, do a push/pop here.)
   14.36 +  const Register recv_klass_reg     = rsi;
   14.37 +  const Register holder_klass_reg   = rax; // declaring interface klass (DECC)
   14.38 +  const Register resolved_klass_reg = rbx; // resolved interface klass (REFC)
   14.39 +  const Register temp_reg           = rdi;
   14.40 +
   14.41 +  const Register icholder_reg = rax;
   14.42 +  __ movptr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset()));
   14.43 +  __ movptr(holder_klass_reg,   Address(icholder_reg, CompiledICHolder::holder_metadata_offset()));
   14.44 +
   14.45 +  Label L_no_such_interface;
   14.46  
   14.47    // get receiver klass (also an implicit null-check)
   14.48    address npe_addr = __ pc();
   14.49 -  __ movptr(rsi, Address(rcx, oopDesc::klass_offset_in_bytes()));
   14.50 +  assert(VtableStub::receiver_location() ==  rcx->as_VMReg(), "receiver expected in  rcx");
   14.51 +  __ load_klass(recv_klass_reg, rcx);
   14.52  
   14.53 -  // Most registers are in use; we'll use rax, rbx, rsi, rdi
   14.54 -  // (If we need to make rsi, rdi callee-save, do a push/pop here.)
   14.55 +  // Receiver subtype check against REFC.
   14.56 +  // Destroys recv_klass_reg value.
   14.57 +  __ lookup_interface_method(// inputs: rec. class, interface
   14.58 +                             recv_klass_reg, resolved_klass_reg, noreg,
   14.59 +                             // outputs:  scan temp. reg1, scan temp. reg2
   14.60 +                             recv_klass_reg, temp_reg,
   14.61 +                             L_no_such_interface,
   14.62 +                             /*return_method=*/false);
   14.63 +
   14.64 +  // Get selected method from declaring class and itable index
   14.65    const Register method = rbx;
   14.66 -  Label throw_icce;
   14.67 -
   14.68 -  // Get Method* and entrypoint for compiler
   14.69 +  __ load_klass(recv_klass_reg, rcx); // restore recv_klass_reg
   14.70    __ lookup_interface_method(// inputs: rec. class, interface, itable index
   14.71 -                             rsi, rax, itable_index,
   14.72 +                             recv_klass_reg, holder_klass_reg, itable_index,
   14.73                               // outputs: method, scan temp. reg
   14.74 -                             method, rdi,
   14.75 -                             throw_icce);
   14.76 +                             method, temp_reg,
   14.77 +                             L_no_such_interface);
   14.78  
   14.79    // method (rbx): Method*
   14.80    // rcx: receiver
   14.81 @@ -193,9 +211,10 @@
   14.82    address ame_addr = __ pc();
   14.83    __ jmp(Address(method, Method::from_compiled_offset()));
   14.84  
   14.85 -  __ bind(throw_icce);
   14.86 +  __ bind(L_no_such_interface);
   14.87    __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
   14.88 -  masm->flush();
   14.89 +
   14.90 +  __ flush();
   14.91  
   14.92    if (PrintMiscellaneous && (WizardMode || Verbose)) {
   14.93      tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
   14.94 @@ -220,7 +239,7 @@
   14.95      return (DebugVtables ? 210 : 16) + (CountCompiledCalls ? 6 : 0);
   14.96    } else {
   14.97      // Itable stub size
   14.98 -    return (DebugVtables ? 256 : 66) + (CountCompiledCalls ? 6 : 0);
   14.99 +    return (DebugVtables ? 256 : 116) + (CountCompiledCalls ? 6 : 0);
  14.100    }
  14.101    // In order to tune these parameters, run the JVM with VM options
  14.102    // +PrintMiscellaneous and +WizardMode to see information about
    15.1 --- a/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Tue Aug 08 12:02:01 2017 +0100
    15.2 +++ b/src/cpu/x86/vm/vtableStubs_x86_64.cpp	Fri Sep 29 14:30:05 2017 -0400
    15.3 @@ -1,5 +1,5 @@
    15.4  /*
    15.5 - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
    15.6 + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
    15.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.8   *
    15.9   * This code is free software; you can redistribute it and/or modify it
   15.10 @@ -27,6 +27,7 @@
   15.11  #include "code/vtableStubs.hpp"
   15.12  #include "interp_masm_x86.hpp"
   15.13  #include "memory/resourceArea.hpp"
   15.14 +#include "oops/compiledICHolder.hpp"
   15.15  #include "oops/instanceKlass.hpp"
   15.16  #include "oops/klassVtable.hpp"
   15.17  #include "runtime/sharedRuntime.hpp"
   15.18 @@ -149,36 +150,50 @@
   15.19  #endif
   15.20  
   15.21    // Entry arguments:
   15.22 -  //  rax: Interface
   15.23 +  //  rax: CompiledICHolder
   15.24    //  j_rarg0: Receiver
   15.25  
   15.26 -  // Free registers (non-args) are rax (interface), rbx
   15.27 -
   15.28 -  // get receiver (need to skip return address on top of stack)
   15.29 -
   15.30 -  assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
   15.31 -  // get receiver klass (also an implicit null-check)
   15.32 -  address npe_addr = __ pc();
   15.33 -
   15.34    // Most registers are in use; we'll use rax, rbx, r10, r11
   15.35    // (various calling sequences use r[cd]x, r[sd]i, r[89]; stay away from them)
   15.36 -  __ load_klass(r10, j_rarg0);
   15.37 +  const Register recv_klass_reg     = r10;
   15.38 +  const Register holder_klass_reg   = rax; // declaring interface klass (DECC)
   15.39 +  const Register resolved_klass_reg = rbx; // resolved interface klass (REFC)
   15.40 +  const Register temp_reg           = r11;
   15.41 +
   15.42 +  Label L_no_such_interface;
   15.43 +
   15.44 +  const Register icholder_reg = rax;
   15.45 +  __ movptr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset()));
   15.46 +  __ movptr(holder_klass_reg,   Address(icholder_reg, CompiledICHolder::holder_metadata_offset()));
   15.47 +
   15.48 +  // get receiver klass (also an implicit null-check)
   15.49 +  assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
   15.50 +  address npe_addr = __ pc();
   15.51 +  __ load_klass(recv_klass_reg, j_rarg0);
   15.52 +
   15.53 +  // Receiver subtype check against REFC.
   15.54 +  // Destroys recv_klass_reg value.
   15.55 +  __ lookup_interface_method(// inputs: rec. class, interface
   15.56 +                             recv_klass_reg, resolved_klass_reg, noreg,
   15.57 +                             // outputs:  scan temp. reg1, scan temp. reg2
   15.58 +                             recv_klass_reg, temp_reg,
   15.59 +                             L_no_such_interface,
   15.60 +                             /*return_method=*/false);
   15.61 +
   15.62 +  // Get selected method from declaring class and itable index
   15.63 +  const Register method = rbx;
   15.64 +  __ load_klass(recv_klass_reg, j_rarg0);   // restore recv_klass_reg
   15.65 +  __ lookup_interface_method(// inputs: rec. class, interface, itable index
   15.66 +                       recv_klass_reg, holder_klass_reg, itable_index,
   15.67 +                       // outputs: method, scan temp. reg
   15.68 +                       method, temp_reg,
   15.69 +                       L_no_such_interface);
   15.70  
   15.71    // If we take a trap while this arg is on the stack we will not
   15.72    // be able to walk the stack properly. This is not an issue except
   15.73    // when there are mistakes in this assembly code that could generate
   15.74    // a spurious fault. Ask me how I know...
   15.75  
   15.76 -  const Register method = rbx;
   15.77 -  Label throw_icce;
   15.78 -
   15.79 -  // Get Method* and entrypoint for compiler
   15.80 -  __ lookup_interface_method(// inputs: rec. class, interface, itable index
   15.81 -                             r10, rax, itable_index,
   15.82 -                             // outputs: method, scan temp. reg
   15.83 -                             method, r11,
   15.84 -                             throw_icce);
   15.85 -
   15.86    // method (rbx): Method*
   15.87    // j_rarg0: receiver
   15.88  
   15.89 @@ -199,7 +214,7 @@
   15.90    address ame_addr = __ pc();
   15.91    __ jmp(Address(method, Method::from_compiled_offset()));
   15.92  
   15.93 -  __ bind(throw_icce);
   15.94 +  __ bind(L_no_such_interface);
   15.95    __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
   15.96  
   15.97    __ flush();
   15.98 @@ -226,8 +241,8 @@
   15.99             (UseCompressedClassPointers ?  MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
  15.100    } else {
  15.101      // Itable stub size
  15.102 -    return (DebugVtables ? 512 : 74) + (CountCompiledCalls ? 13 : 0) +
  15.103 -           (UseCompressedClassPointers ?  MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
  15.104 +    return (DebugVtables ? 512 : 140) + (CountCompiledCalls ? 13 : 0) +
  15.105 +           (UseCompressedClassPointers ? 2 * MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
  15.106    }
  15.107    // In order to tune these parameters, run the JVM with VM options
  15.108    // +PrintMiscellaneous and +WizardMode to see information about
    16.1 --- a/src/share/vm/code/compiledIC.cpp	Tue Aug 08 12:02:01 2017 +0100
    16.2 +++ b/src/share/vm/code/compiledIC.cpp	Fri Sep 29 14:30:05 2017 -0400
    16.3 @@ -1,5 +1,5 @@
    16.4  /*
    16.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
    16.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
    16.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.8   *
    16.9   * This code is free software; you can redistribute it and/or modify it
   16.10 @@ -228,10 +228,13 @@
   16.11  #ifdef ASSERT
   16.12      int index = call_info->resolved_method()->itable_index();
   16.13      assert(index == itable_index, "CallInfo pre-computes this");
   16.14 -#endif //ASSERT
   16.15      InstanceKlass* k = call_info->resolved_method()->method_holder();
   16.16      assert(k->verify_itable_index(itable_index), "sanity check");
   16.17 -    InlineCacheBuffer::create_transition_stub(this, k, entry);
   16.18 +#endif //ASSERT
   16.19 +    CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(),
   16.20 +                                                    call_info->resolved_klass()());
   16.21 +    holder->claim();
   16.22 +    InlineCacheBuffer::create_transition_stub(this, holder, entry);
   16.23    } else {
   16.24      assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable");
   16.25      // Can be different than selected_method->vtable_index(), due to package-private etc.
   16.26 @@ -527,7 +530,14 @@
   16.27  
   16.28  bool CompiledIC::is_icholder_entry(address entry) {
   16.29    CodeBlob* cb = CodeCache::find_blob_unsafe(entry);
   16.30 -  return (cb != NULL && cb->is_adapter_blob());
   16.31 +  if (cb != NULL && cb->is_adapter_blob()) {
   16.32 +    return true;
   16.33 +  }
   16.34 +  // itable stubs also use CompiledICHolder
   16.35 +  if (VtableStubs::is_entry_point(entry) && VtableStubs::stub_containing(entry)->is_itable_stub()) {
   16.36 +    return true;
   16.37 +  }
   16.38 +  return false;
   16.39  }
   16.40  
   16.41  // ----------------------------------------------------------------------------
    17.1 --- a/src/share/vm/code/compiledIC.hpp	Tue Aug 08 12:02:01 2017 +0100
    17.2 +++ b/src/share/vm/code/compiledIC.hpp	Fri Sep 29 14:30:05 2017 -0400
    17.3 @@ -1,5 +1,5 @@
    17.4  /*
    17.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
    17.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
    17.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    17.8   *
    17.9   * This code is free software; you can redistribute it and/or modify it
   17.10 @@ -59,11 +59,11 @@
   17.11  //          \                        /   \     /
   17.12  //       [4] \                      / [4] \->-/
   17.13  //            \->-  Megamorphic -<-/
   17.14 -//                  (Method*)
   17.15 +//              (CompiledICHolder*)
   17.16  //
   17.17 -// The text in paranteses () refere to the value of the inline cache receiver (mov instruction)
   17.18 +// The text in parentheses () refers to the value of the inline cache receiver (mov instruction)
   17.19  //
   17.20 -// The numbers in square brackets refere to the kind of transition:
   17.21 +// The numbers in square brackets refer to the kind of transition:
   17.22  // [1]: Initial fixup. Receiver it found from debug information
   17.23  // [2]: Compilation of a method
   17.24  // [3]: Recompilation of a method (note: only entry is changed. The Klass* must stay the same)
    18.1 --- a/src/share/vm/code/nmethod.cpp	Tue Aug 08 12:02:01 2017 +0100
    18.2 +++ b/src/share/vm/code/nmethod.cpp	Fri Sep 29 14:30:05 2017 -0400
    18.3 @@ -1748,12 +1748,11 @@
    18.4      CompiledICHolder* cichk_oop = ic->cached_icholder();
    18.5  
    18.6      if (mark_on_stack) {
    18.7 -      Metadata::mark_on_stack(cichk_oop->holder_method());
    18.8 +      Metadata::mark_on_stack(cichk_oop->holder_metadata());
    18.9        Metadata::mark_on_stack(cichk_oop->holder_klass());
   18.10      }
   18.11  
   18.12 -    if (cichk_oop->holder_method()->method_holder()->is_loader_alive(is_alive) &&
   18.13 -        cichk_oop->holder_klass()->is_loader_alive(is_alive)) {
   18.14 +    if (cichk_oop->is_loader_alive(is_alive)) {
   18.15        return;
   18.16      }
   18.17    } else {
   18.18 @@ -2180,7 +2179,7 @@
   18.19          CompiledIC *ic = CompiledIC_at(&iter);
   18.20          if (ic->is_icholder_call()) {
   18.21            CompiledICHolder* cichk = ic->cached_icholder();
   18.22 -          f(cichk->holder_method());
   18.23 +          f(cichk->holder_metadata());
   18.24            f(cichk->holder_klass());
   18.25          } else {
   18.26            Metadata* ic_oop = ic->cached_metadata();
    19.1 --- a/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Aug 08 12:02:01 2017 +0100
    19.2 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Sep 29 14:30:05 2017 -0400
    19.3 @@ -786,6 +786,7 @@
    19.4    case CallInfo::itable_call:
    19.5      cache_entry(thread)->set_itable_call(
    19.6        bytecode,
    19.7 +      info.resolved_klass(),
    19.8        info.resolved_method(),
    19.9        info.itable_index());
   19.10      break;
    20.1 --- a/src/share/vm/oops/compiledICHolder.cpp	Tue Aug 08 12:02:01 2017 +0100
    20.2 +++ b/src/share/vm/oops/compiledICHolder.cpp	Fri Sep 29 14:30:05 2017 -0400
    20.3 @@ -1,5 +1,5 @@
    20.4  /*
    20.5 - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
    20.6 + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
    20.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    20.8   *
    20.9   * This code is free software; you can redistribute it and/or modify it
   20.10 @@ -32,12 +32,28 @@
   20.11  volatile int CompiledICHolder::_live_not_claimed_count;
   20.12  
   20.13  
   20.14 +bool CompiledICHolder::is_loader_alive(BoolObjectClosure* is_alive) {
   20.15 +  if (_holder_metadata->is_method()) {
   20.16 +    if (!((Method*)_holder_metadata)->method_holder()->is_loader_alive(is_alive)) {
   20.17 +      return false;
   20.18 +    }
   20.19 +  } else if (_holder_metadata->is_klass()) {
   20.20 +    if (!((Klass*)_holder_metadata)->is_loader_alive(is_alive)) {
   20.21 +      return false;
   20.22 +    }
   20.23 +  }
   20.24 +  if (!_holder_klass->is_loader_alive(is_alive)) {
   20.25 +    return false;
   20.26 +  }
   20.27 +  return true;
   20.28 +}
   20.29 +
   20.30  // Printing
   20.31  
   20.32  void CompiledICHolder::print_on(outputStream* st) const {
   20.33    st->print("%s", internal_name());
   20.34 -  st->print(" - method: "); holder_method()->print_value_on(st); st->cr();
   20.35 -  st->print(" - klass:  "); holder_klass()->print_value_on(st); st->cr();
   20.36 +  st->print(" - metadata: "); holder_metadata()->print_value_on(st); st->cr();
   20.37 +  st->print(" - klass:    "); holder_klass()->print_value_on(st); st->cr();
   20.38  }
   20.39  
   20.40  void CompiledICHolder::print_value_on(outputStream* st) const {
   20.41 @@ -48,6 +64,6 @@
   20.42  // Verification
   20.43  
   20.44  void CompiledICHolder::verify_on(outputStream* st) {
   20.45 -  guarantee(holder_method()->is_method(), "should be method");
   20.46 +  guarantee(holder_metadata()->is_method() || holder_metadata()->is_klass(), "should be method or klass");
   20.47    guarantee(holder_klass()->is_klass(),   "should be klass");
   20.48  }
    21.1 --- a/src/share/vm/oops/compiledICHolder.hpp	Tue Aug 08 12:02:01 2017 +0100
    21.2 +++ b/src/share/vm/oops/compiledICHolder.hpp	Fri Sep 29 14:30:05 2017 -0400
    21.3 @@ -1,5 +1,5 @@
    21.4  /*
    21.5 - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
    21.6 + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
    21.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    21.8   *
    21.9   * This code is free software; you can redistribute it and/or modify it
   21.10 @@ -28,8 +28,9 @@
   21.11  #include "oops/oop.hpp"
   21.12  
   21.13  // A CompiledICHolder* is a helper object for the inline cache implementation.
   21.14 -// It holds an intermediate value (method+klass pair) used when converting from
   21.15 -// compiled to an interpreted call.
   21.16 +// It holds:
   21.17 +//   (1) (method+klass pair) when converting from compiled to an interpreted call
   21.18 +//   (2) (klass+klass pair) when calling itable stub from megamorphic compiled call
   21.19  //
   21.20  // These are always allocated in the C heap and are freed during a
   21.21  // safepoint by the ICBuffer logic.  It's unsafe to free them earlier
   21.22 @@ -44,14 +45,14 @@
   21.23    static volatile int _live_not_claimed_count; // allocated but not yet in use so not
   21.24                                                 // reachable by iterating over nmethods
   21.25  
   21.26 -  Method* _holder_method;
   21.27 +  Metadata* _holder_metadata;
   21.28    Klass*    _holder_klass;    // to avoid name conflict with oopDesc::_klass
   21.29    CompiledICHolder* _next;
   21.30  
   21.31   public:
   21.32    // Constructor
   21.33 -  CompiledICHolder(Method* method, Klass* klass)
   21.34 -      : _holder_method(method), _holder_klass(klass) {
   21.35 +  CompiledICHolder(Metadata* metadata, Klass* klass)
   21.36 +      : _holder_metadata(metadata), _holder_klass(klass) {
   21.37  #ifdef ASSERT
   21.38      Atomic::inc(&_live_count);
   21.39      Atomic::inc(&_live_not_claimed_count);
   21.40 @@ -69,19 +70,20 @@
   21.41    static int live_not_claimed_count() { return _live_not_claimed_count; }
   21.42  
   21.43    // accessors
   21.44 -  Method* holder_method() const     { return _holder_method; }
   21.45    Klass*    holder_klass()  const     { return _holder_klass; }
   21.46 +  Metadata* holder_metadata() const   { return _holder_metadata; }
   21.47  
   21.48 -  void set_holder_method(Method* m) { _holder_method = m; }
   21.49 -  void set_holder_klass(Klass* k)   { _holder_klass = k; }
   21.50 +  void set_holder_metadata(Metadata* m) { _holder_metadata = m; }
   21.51 +  void set_holder_klass(Klass* k)     { _holder_klass = k; }
   21.52  
   21.53 -  // interpreter support (offsets in bytes)
   21.54 -  static int holder_method_offset()   { return offset_of(CompiledICHolder, _holder_method); }
   21.55 +  static int holder_metadata_offset() { return offset_of(CompiledICHolder, _holder_metadata); }
   21.56    static int holder_klass_offset()    { return offset_of(CompiledICHolder, _holder_klass); }
   21.57  
   21.58    CompiledICHolder* next()     { return _next; }
   21.59    void set_next(CompiledICHolder* n) { _next = n; }
   21.60  
   21.61 +  bool is_loader_alive(BoolObjectClosure* is_alive);
   21.62 +
   21.63    // Verify
   21.64    void verify_on(outputStream* st);
   21.65  
    22.1 --- a/src/share/vm/oops/cpCache.cpp	Tue Aug 08 12:02:01 2017 +0100
    22.2 +++ b/src/share/vm/oops/cpCache.cpp	Fri Sep 29 14:30:05 2017 -0400
    22.3 @@ -1,5 +1,5 @@
    22.4  /*
    22.5 - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
    22.6 + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
    22.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.8   *
    22.9   * This code is free software; you can redistribute it and/or modify it
   22.10 @@ -259,14 +259,16 @@
   22.11    set_direct_or_vtable_call(invoke_code, method, index, false);
   22.12  }
   22.13  
   22.14 -void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
   22.15 +void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code,
   22.16 +                                                        KlassHandle referenced_klass,
   22.17 +                                                        methodHandle method, int index) {
   22.18    assert(method->method_holder()->verify_itable_index(index), "");
   22.19    assert(invoke_code == Bytecodes::_invokeinterface, "");
   22.20    InstanceKlass* interf = method->method_holder();
   22.21    assert(interf->is_interface(), "must be an interface");
   22.22    assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");
   22.23 -  set_f1(interf);
   22.24 -  set_f2(index);
   22.25 +  set_f1(referenced_klass());
   22.26 +  set_f2((intx)method());
   22.27    set_method_flags(as_TosState(method->result_type()),
   22.28                     0,  // no option bits
   22.29                     method()->size_of_parameters());
   22.30 @@ -433,10 +435,27 @@
   22.31  
   22.32  
   22.33  #if INCLUDE_JVMTI
   22.34 +
   22.35 +void log_adjust(const char* entry_type, Method* old_method, Method* new_method, bool* trace_name_printed) {
   22.36 +  if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
   22.37 +    if (!(*trace_name_printed)) {
   22.38 +      // RC_TRACE_MESG macro has an embedded ResourceMark
   22.39 +      RC_TRACE_MESG(("adjust: name=%s",
   22.40 +        old_method->method_holder()->external_name()));
   22.41 +      *trace_name_printed = true;
   22.42 +    }
   22.43 +    // RC_TRACE macro has an embedded ResourceMark
   22.44 +    RC_TRACE(0x00400000, ("cpc %s entry update: %s(%s)",
   22.45 +      entry_type,
   22.46 +      new_method->name()->as_C_string(),
   22.47 +      new_method->signature()->as_C_string()));
   22.48 +  }
   22.49 +}
   22.50 +
   22.51  // RedefineClasses() API support:
   22.52  // If this ConstantPoolCacheEntry refers to old_method then update it
   22.53  // to refer to new_method.
   22.54 -bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
   22.55 +void ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
   22.56         Method* new_method, bool * trace_name_printed) {
   22.57  
   22.58    if (is_vfinal()) {
   22.59 @@ -445,69 +464,34 @@
   22.60        // match old_method so need an update
   22.61        // NOTE: can't use set_f2_as_vfinal_method as it asserts on different values
   22.62        _f2 = (intptr_t)new_method;
   22.63 -      if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
   22.64 -        if (!(*trace_name_printed)) {
   22.65 -          // RC_TRACE_MESG macro has an embedded ResourceMark
   22.66 -          RC_TRACE_MESG(("adjust: name=%s",
   22.67 -            old_method->method_holder()->external_name()));
   22.68 -          *trace_name_printed = true;
   22.69 -        }
   22.70 -        // RC_TRACE macro has an embedded ResourceMark
   22.71 -        RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)",
   22.72 -          new_method->name()->as_C_string(),
   22.73 -          new_method->signature()->as_C_string()));
   22.74 -      }
   22.75 -      return true;
   22.76      }
   22.77 -
   22.78 -    // f1() is not used with virtual entries so bail out
   22.79 -    return false;
   22.80 +    return;
   22.81    }
   22.82  
   22.83 -  if (_f1 == NULL) {
   22.84 -    // NULL f1() means this is a virtual entry so bail out
   22.85 -    // We are assuming that the vtable index does not need change.
   22.86 -    return false;
   22.87 +  assert (_f1 != NULL, "should not call with uninteresting entry");
   22.88 +
   22.89 +  if (!(_f1->is_method())) {
   22.90 +    // _f1 is a Klass* for an interface, _f2 is the method
   22.91 +    if (f2_as_interface_method() == old_method) {
   22.92 +      _f2 = (intptr_t)new_method;
   22.93 +      log_adjust("interface", old_method, new_method, trace_name_printed);
   22.94 +    }
   22.95 +  } else if (_f1 == old_method) {
   22.96 +    _f1 = new_method;
   22.97 +    log_adjust("special, static or dynamic", old_method, new_method, trace_name_printed);
   22.98    }
   22.99 -
  22.100 -  if (_f1 == old_method) {
  22.101 -    _f1 = new_method;
  22.102 -    if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
  22.103 -      if (!(*trace_name_printed)) {
  22.104 -        // RC_TRACE_MESG macro has an embedded ResourceMark
  22.105 -        RC_TRACE_MESG(("adjust: name=%s",
  22.106 -          old_method->method_holder()->external_name()));
  22.107 -        *trace_name_printed = true;
  22.108 -      }
  22.109 -      // RC_TRACE macro has an embedded ResourceMark
  22.110 -      RC_TRACE(0x00400000, ("cpc entry update: %s(%s)",
  22.111 -        new_method->name()->as_C_string(),
  22.112 -        new_method->signature()->as_C_string()));
  22.113 -    }
  22.114 -    return true;
  22.115 -  }
  22.116 -
  22.117 -  return false;
  22.118  }
  22.119  
  22.120  // a constant pool cache entry should never contain old or obsolete methods
  22.121  bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() {
  22.122 -  if (is_vfinal()) {
  22.123 -    // virtual and final so _f2 contains method ptr instead of vtable index
  22.124 -    Metadata* f2 = (Metadata*)_f2;
  22.125 -    // Return false if _f2 refers to an old or an obsolete method.
  22.126 -    // _f2 == NULL || !_f2->is_method() are just as unexpected here.
  22.127 -    return (f2 != NULL NOT_PRODUCT(&& f2->is_valid()) && f2->is_method() &&
  22.128 -            !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete());
  22.129 -  } else if (_f1 == NULL ||
  22.130 -             (NOT_PRODUCT(_f1->is_valid() &&) !_f1->is_method())) {
  22.131 -    // _f1 == NULL || !_f1->is_method() are OK here
  22.132 +  Method* m = get_interesting_method_entry(NULL);
  22.133 +  // return false if m refers to a non-deleted old or obsolete method
  22.134 +  if (m != NULL) {
  22.135 +    assert(m->is_valid() && m->is_method(), "m is a valid method");
  22.136 +    return !m->is_old() && !m->is_obsolete(); // old is always set for old and obsolete
  22.137 +  } else {
  22.138      return true;
  22.139    }
  22.140 -  // return false if _f1 refers to a non-deleted old or obsolete method
  22.141 -  return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() &&
  22.142 -          (f1_as_method()->is_deleted() ||
  22.143 -          (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete())));
  22.144  }
  22.145  
  22.146  Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) {
  22.147 @@ -524,10 +508,11 @@
  22.148      return NULL;
  22.149    } else {
  22.150      if (!(_f1->is_method())) {
  22.151 -      // _f1 can also contain a Klass* for an interface
  22.152 -      return NULL;
  22.153 +      // _f1 is a Klass* for an interface
  22.154 +      m = f2_as_interface_method();
  22.155 +    } else {
  22.156 +      m = f1_as_method();
  22.157      }
  22.158 -    m = f1_as_method();
  22.159    }
  22.160    assert(m != NULL && m->is_method(), "sanity check");
  22.161    if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {
    23.1 --- a/src/share/vm/oops/cpCache.hpp	Tue Aug 08 12:02:01 2017 +0100
    23.2 +++ b/src/share/vm/oops/cpCache.hpp	Fri Sep 29 14:30:05 2017 -0400
    23.3 @@ -1,5 +1,5 @@
    23.4  /*
    23.5 - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
    23.6 + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
    23.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    23.8   *
    23.9   * This code is free software; you can redistribute it and/or modify it
   23.10 @@ -248,6 +248,7 @@
   23.11  
   23.12    void set_itable_call(
   23.13      Bytecodes::Code invoke_code,                 // the bytecode used; must be invokeinterface
   23.14 +    KlassHandle referenced_klass,                // the referenced klass in the InterfaceMethodref
   23.15      methodHandle method,                         // the resolved interface method
   23.16      int itable_index                             // index into itable for the method
   23.17    );
   23.18 @@ -344,6 +345,7 @@
   23.19    bool      is_f1_null() const                   { Metadata* f1 = f1_ord(); return f1 == NULL; }  // classifies a CPC entry as unbound
   23.20    int       f2_as_index() const                  { assert(!is_vfinal(), ""); return (int) _f2; }
   23.21    Method*   f2_as_vfinal_method() const          { assert(is_vfinal(), ""); return (Method*)_f2; }
   23.22 +  Method*   f2_as_interface_method() const       { assert(bytecode_1() == Bytecodes::_invokeinterface, ""); return (Method*)_f2; }
   23.23    int  field_index() const                       { assert(is_field_entry(),  ""); return (_flags & field_index_mask); }
   23.24    int  parameter_size() const                    { assert(is_method_entry(), ""); return (_flags & parameter_size_mask); }
   23.25    bool is_volatile() const                       { return (_flags & (1 << is_volatile_shift))       != 0; }
   23.26 @@ -374,7 +376,7 @@
   23.27    // trace_name_printed is set to true if the current call has
   23.28    // printed the klass name so that other routines in the adjust_*
   23.29    // group don't print the klass name.
   23.30 -  bool adjust_method_entry(Method* old_method, Method* new_method,
   23.31 +  void adjust_method_entry(Method* old_method, Method* new_method,
   23.32           bool* trace_name_printed);
   23.33    bool check_no_old_or_obsolete_entries();
   23.34    Method* get_interesting_method_entry(Klass* k);
    24.1 --- a/src/share/vm/oops/klassVtable.cpp	Tue Aug 08 12:02:01 2017 +0100
    24.2 +++ b/src/share/vm/oops/klassVtable.cpp	Fri Sep 29 14:30:05 2017 -0400
    24.3 @@ -1204,7 +1204,6 @@
    24.4    Array<Method*>* methods = InstanceKlass::cast(interf_h())->methods();
    24.5    int nof_methods = methods->length();
    24.6    HandleMark hm;
    24.7 -  assert(nof_methods > 0, "at least one method must exist for interface to be in vtable");
    24.8    Handle interface_loader (THREAD, InstanceKlass::cast(interf_h())->class_loader());
    24.9  
   24.10    int ime_count = method_count_for_interface(interf_h());
   24.11 @@ -1386,8 +1385,10 @@
   24.12        }
   24.13      }
   24.14  
   24.15 -    // Only count interfaces with at least one method
   24.16 -    if (method_count > 0) {
   24.17 +    // Visit all interfaces which either have any methods or can participate in receiver type check.
   24.18 +    // We do not bother to count methods in transitive interfaces, although that would allow us to skip
   24.19 +    // this step in the rare case of a zero-method interface extending another zero-method interface.
   24.20 +    if (method_count > 0 || InstanceKlass::cast(intf)->transitive_interfaces()->length() > 0) {
   24.21        blk->doit(intf, method_count);
   24.22      }
   24.23    }
    25.1 --- a/src/share/vm/oops/method.hpp	Tue Aug 08 12:02:01 2017 +0100
    25.2 +++ b/src/share/vm/oops/method.hpp	Fri Sep 29 14:30:05 2017 -0400
    25.3 @@ -1,5 +1,5 @@
    25.4  /*
    25.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
    25.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
    25.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    25.8   *
    25.9   * This code is free software; you can redistribute it and/or modify it
   25.10 @@ -661,6 +661,7 @@
   25.11    static ByteSize from_interpreted_offset()      { return byte_offset_of(Method, _from_interpreted_entry ); }
   25.12    static ByteSize interpreter_entry_offset()     { return byte_offset_of(Method, _i2i_entry ); }
   25.13    static ByteSize signature_handler_offset()     { return in_ByteSize(sizeof(Method) + wordSize);      }
   25.14 +  static ByteSize itable_index_offset()          { return byte_offset_of(Method, _vtable_index ); }
   25.15  
   25.16    // for code generation
   25.17    static int method_data_offset_in_bytes()       { return offset_of(Method, _method_data); }
    26.1 --- a/src/share/vm/runtime/vmStructs.cpp	Tue Aug 08 12:02:01 2017 +0100
    26.2 +++ b/src/share/vm/runtime/vmStructs.cpp	Fri Sep 29 14:30:05 2017 -0400
    26.3 @@ -278,7 +278,7 @@
    26.4    volatile_nonstatic_field(ArrayKlass,         _lower_dimension,                              Klass*)                                \
    26.5    nonstatic_field(ArrayKlass,                  _vtable_len,                                   int)                                   \
    26.6    nonstatic_field(ArrayKlass,                  _component_mirror,                             oop)                                   \
    26.7 -  nonstatic_field(CompiledICHolder,     _holder_method,                                Method*)                               \
    26.8 +  nonstatic_field(CompiledICHolder,     _holder_metadata,                              Metadata*)                             \
    26.9    nonstatic_field(CompiledICHolder,     _holder_klass,                                 Klass*)                                \
   26.10    nonstatic_field(ConstantPool,         _tags,                                         Array<u1>*)                            \
   26.11    nonstatic_field(ConstantPool,         _cache,                                        ConstantPoolCache*)                    \
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/test/runtime/RedefineTests/RedefineInterfaceCall.java	Fri Sep 29 14:30:05 2017 -0400
    27.3 @@ -0,0 +1,83 @@
    27.4 +/*
    27.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
    27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    27.7 + *
    27.8 + * This code is free software; you can redistribute it and/or modify it
    27.9 + * under the terms of the GNU General Public License version 2 only, as
   27.10 + * published by the Free Software Foundation.
   27.11 + *
   27.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   27.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   27.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   27.15 + * version 2 for more details (a copy is included in the LICENSE file that
   27.16 + * accompanied this code).
   27.17 + *
   27.18 + * You should have received a copy of the GNU General Public License version
   27.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   27.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   27.21 + *
   27.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   27.23 + * or visit www.oracle.com if you need additional information or have any
   27.24 + * questions.
   27.25 + */
   27.26 +
   27.27 +/*
   27.28 + * @test
   27.29 + * @bug 8174962
   27.30 + * @summary Redefine class with interface method call
   27.31 + * @library /testlibrary /test/lib
   27.32 + * @modules java.base/jdk.internal.misc
   27.33 + * @modules java.compiler
   27.34 + *          java.instrument
   27.35 + *          jdk.jartool/sun.tools.jar
   27.36 + * @run main RedefineClassHelper
   27.37 + * @run main/othervm -javaagent:redefineagent.jar RedefineInterfaceCall
   27.38 + */
   27.39 +
   27.40 +import static jdk.testlibrary.Asserts.assertEquals;
   27.41 +
   27.42 +interface I1 { default int m() { return 0; } }
   27.43 +interface I2 extends I1 {}
   27.44 +
   27.45 +public class RedefineInterfaceCall {
   27.46 +
   27.47 +    public static class C implements I2 {
   27.48 +        public int test(I2 i) {
   27.49 +            return i.m(); // invokeinterface cpCacheEntry
   27.50 +        }
   27.51 +    }
   27.52 +
   27.53 +    static String newI1 =
   27.54 +      "interface I1 { default int m() { return 1; } }";
   27.55 +
   27.56 +    static String newC =
   27.57 +        "public class RedefineInterfaceCall$C implements I2 { " +
   27.58 +        "  public int test(I2 i) { " +
   27.59 +        "    return i.m(); " +
   27.60 +        "  } " +
   27.61 +        "} ";
   27.62 +
   27.63 +    static int test(I2 i) {
   27.64 +        return i.m(); // invokeinterface cpCacheEntry
   27.65 +    }
   27.66 +
   27.67 +    public static void main(String[] args) throws Exception {
   27.68 +        C c = new C();
   27.69 +
   27.70 +        assertEquals(test(c),   0);
   27.71 +        assertEquals(c.test(c), 0);
   27.72 +
   27.73 +        RedefineClassHelper.redefineClass(C.class, newC);
   27.74 +
   27.75 +        assertEquals(c.test(c), 0);
   27.76 +
   27.77 +        RedefineClassHelper.redefineClass(I1.class, newI1);
   27.78 +
   27.79 +        assertEquals(test(c),   1);
   27.80 +        assertEquals(c.test(c), 1);
   27.81 +
   27.82 +        RedefineClassHelper.redefineClass(C.class, newC);
   27.83 +
   27.84 +        assertEquals(c.test(c), 1);
   27.85 +    }
   27.86 +}

mercurial