1.1 --- a/src/share/vm/oops/cpCache.cpp Tue Aug 08 12:02:01 2017 +0100 1.2 +++ b/src/share/vm/oops/cpCache.cpp Fri Sep 29 14:30:05 2017 -0400 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1998, 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 @@ -259,14 +259,16 @@ 1.11 set_direct_or_vtable_call(invoke_code, method, index, false); 1.12 } 1.13 1.14 -void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) { 1.15 +void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, 1.16 + KlassHandle referenced_klass, 1.17 + methodHandle method, int index) { 1.18 assert(method->method_holder()->verify_itable_index(index), ""); 1.19 assert(invoke_code == Bytecodes::_invokeinterface, ""); 1.20 InstanceKlass* interf = method->method_holder(); 1.21 assert(interf->is_interface(), "must be an interface"); 1.22 assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here"); 1.23 - set_f1(interf); 1.24 - set_f2(index); 1.25 + set_f1(referenced_klass()); 1.26 + set_f2((intx)method()); 1.27 set_method_flags(as_TosState(method->result_type()), 1.28 0, // no option bits 1.29 method()->size_of_parameters()); 1.30 @@ -433,10 +435,27 @@ 1.31 1.32 1.33 #if INCLUDE_JVMTI 1.34 + 1.35 +void log_adjust(const char* entry_type, Method* old_method, Method* new_method, bool* trace_name_printed) { 1.36 + if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { 1.37 + if (!(*trace_name_printed)) { 1.38 + // RC_TRACE_MESG macro has an embedded ResourceMark 1.39 + RC_TRACE_MESG(("adjust: name=%s", 1.40 + old_method->method_holder()->external_name())); 1.41 + *trace_name_printed = true; 1.42 + } 1.43 + // RC_TRACE macro has an embedded ResourceMark 1.44 + RC_TRACE(0x00400000, ("cpc %s entry update: %s(%s)", 1.45 + entry_type, 1.46 + new_method->name()->as_C_string(), 1.47 + new_method->signature()->as_C_string())); 1.48 + } 1.49 +} 1.50 + 1.51 // RedefineClasses() API support: 1.52 // If this ConstantPoolCacheEntry refers to old_method then update it 1.53 // to refer to new_method. 1.54 -bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method, 1.55 +void ConstantPoolCacheEntry::adjust_method_entry(Method* old_method, 1.56 Method* new_method, bool * trace_name_printed) { 1.57 1.58 if (is_vfinal()) { 1.59 @@ -445,69 +464,34 @@ 1.60 // match old_method so need an update 1.61 // NOTE: can't use set_f2_as_vfinal_method as it asserts on different values 1.62 _f2 = (intptr_t)new_method; 1.63 - if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { 1.64 - if (!(*trace_name_printed)) { 1.65 - // RC_TRACE_MESG macro has an embedded ResourceMark 1.66 - RC_TRACE_MESG(("adjust: name=%s", 1.67 - old_method->method_holder()->external_name())); 1.68 - *trace_name_printed = true; 1.69 - } 1.70 - // RC_TRACE macro has an embedded ResourceMark 1.71 - RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)", 1.72 - new_method->name()->as_C_string(), 1.73 - new_method->signature()->as_C_string())); 1.74 - } 1.75 - return true; 1.76 } 1.77 - 1.78 - // f1() is not used with virtual entries so bail out 1.79 - return false; 1.80 + return; 1.81 } 1.82 1.83 - if (_f1 == NULL) { 1.84 - // NULL f1() means this is a virtual entry so bail out 1.85 - // We are assuming that the vtable index does not need change. 1.86 - return false; 1.87 + assert (_f1 != NULL, "should not call with uninteresting entry"); 1.88 + 1.89 + if (!(_f1->is_method())) { 1.90 + // _f1 is a Klass* for an interface, _f2 is the method 1.91 + if (f2_as_interface_method() == old_method) { 1.92 + _f2 = (intptr_t)new_method; 1.93 + log_adjust("interface", old_method, new_method, trace_name_printed); 1.94 + } 1.95 + } else if (_f1 == old_method) { 1.96 + _f1 = new_method; 1.97 + log_adjust("special, static or dynamic", old_method, new_method, trace_name_printed); 1.98 } 1.99 - 1.100 - if (_f1 == old_method) { 1.101 - _f1 = new_method; 1.102 - if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { 1.103 - if (!(*trace_name_printed)) { 1.104 - // RC_TRACE_MESG macro has an embedded ResourceMark 1.105 - RC_TRACE_MESG(("adjust: name=%s", 1.106 - old_method->method_holder()->external_name())); 1.107 - *trace_name_printed = true; 1.108 - } 1.109 - // RC_TRACE macro has an embedded ResourceMark 1.110 - RC_TRACE(0x00400000, ("cpc entry update: %s(%s)", 1.111 - new_method->name()->as_C_string(), 1.112 - new_method->signature()->as_C_string())); 1.113 - } 1.114 - return true; 1.115 - } 1.116 - 1.117 - return false; 1.118 } 1.119 1.120 // a constant pool cache entry should never contain old or obsolete methods 1.121 bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() { 1.122 - if (is_vfinal()) { 1.123 - // virtual and final so _f2 contains method ptr instead of vtable index 1.124 - Metadata* f2 = (Metadata*)_f2; 1.125 - // Return false if _f2 refers to an old or an obsolete method. 1.126 - // _f2 == NULL || !_f2->is_method() are just as unexpected here. 1.127 - return (f2 != NULL NOT_PRODUCT(&& f2->is_valid()) && f2->is_method() && 1.128 - !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete()); 1.129 - } else if (_f1 == NULL || 1.130 - (NOT_PRODUCT(_f1->is_valid() &&) !_f1->is_method())) { 1.131 - // _f1 == NULL || !_f1->is_method() are OK here 1.132 + Method* m = get_interesting_method_entry(NULL); 1.133 + // return false if m refers to a non-deleted old or obsolete method 1.134 + if (m != NULL) { 1.135 + assert(m->is_valid() && m->is_method(), "m is a valid method"); 1.136 + return !m->is_old() && !m->is_obsolete(); // old is always set for old and obsolete 1.137 + } else { 1.138 return true; 1.139 } 1.140 - // return false if _f1 refers to a non-deleted old or obsolete method 1.141 - return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() && 1.142 - (f1_as_method()->is_deleted() || 1.143 - (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete()))); 1.144 } 1.145 1.146 Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) { 1.147 @@ -524,10 +508,11 @@ 1.148 return NULL; 1.149 } else { 1.150 if (!(_f1->is_method())) { 1.151 - // _f1 can also contain a Klass* for an interface 1.152 - return NULL; 1.153 + // _f1 is a Klass* for an interface 1.154 + m = f2_as_interface_method(); 1.155 + } else { 1.156 + m = f1_as_method(); 1.157 } 1.158 - m = f1_as_method(); 1.159 } 1.160 assert(m != NULL && m->is_method(), "sanity check"); 1.161 if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {