annotate src/hotspot/share/oops/cpCache.cpp @ 54896:bdccafc038a2

8217998: Remove method_type field associated with the appendix field of an indy or method handle call Summary: Removed the unused method_type field associated with the appendix field of an indy or method handle call. Reviewed-by: acorn, coleenp, dlong
author lfoltan
date Wed, 13 Feb 2019 15:50:08 -0500
parents f72661ff0294
children 9c3fe09f69bc
rev   line source
duke@1 1 /*
coleenp@54685 2 * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
duke@1 7 * published by the Free Software Foundation.
duke@1 8 *
duke@1 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 13 * accompanied this code).
duke@1 14 *
duke@1 15 * You should have received a copy of the GNU General Public License version
duke@1 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 18 *
trims@5547 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@5547 20 * or visit www.oracle.com if you need additional information or have any
trims@5547 21 * questions.
duke@1 22 *
duke@1 23 */
duke@1 24
stefank@7397 25 #include "precompiled.hpp"
hseigel@47839 26 #include "classfile/resolutionErrors.hpp"
ccheung@47103 27 #include "interpreter/bytecodeStream.hpp"
ccheung@47103 28 #include "interpreter/bytecodes.hpp"
stefank@7397 29 #include "interpreter/interpreter.hpp"
stefank@50088 30 #include "interpreter/linkResolver.hpp"
stefank@7397 31 #include "interpreter/rewriter.hpp"
rehn@38259 32 #include "logging/log.hpp"
jiangli@52991 33 #include "memory/heapShared.hpp"
coleenp@47095 34 #include "memory/metadataFactory.hpp"
iklam@46746 35 #include "memory/metaspaceClosure.hpp"
kbarrett@51145 36 #include "memory/metaspaceShared.hpp"
jprovino@37248 37 #include "memory/resourceArea.hpp"
stefank@49824 38 #include "memory/universe.hpp"
eosterlund@49168 39 #include "oops/access.inline.hpp"
hseigel@49805 40 #include "oops/constantPool.inline.hpp"
hseigel@49805 41 #include "oops/cpCache.inline.hpp"
stefank@29081 42 #include "oops/objArrayOop.inline.hpp"
stefank@7397 43 #include "oops/oop.inline.hpp"
twisti@13391 44 #include "prims/methodHandles.hpp"
dholmes@40655 45 #include "runtime/atomic.hpp"
stefank@7397 46 #include "runtime/handles.inline.hpp"
coleenp@51033 47 #include "runtime/orderAccess.hpp"
jprovino@15482 48 #include "utilities/macros.hpp"
duke@1 49
drchase@24424 50 // Implementation of ConstantPoolCacheEntry
duke@1 51
jrose@4429 52 void ConstantPoolCacheEntry::initialize_entry(int index) {
jrose@2570 53 assert(0 < index && index < 0x10000, "sanity check");
duke@1 54 _indices = index;
coleenp@15928 55 _f1 = NULL;
coleenp@15928 56 _f2 = _flags = 0;
jrose@2570 57 assert(constant_pool_index() == index, "");
duke@1 58 }
duke@1 59
ccheung@47103 60 void ConstantPoolCacheEntry::verify_just_initialized(bool f2_used) {
ccheung@47103 61 assert((_indices & (~cp_index_mask)) == 0, "sanity");
ccheung@47103 62 assert(_f1 == NULL, "sanity");
ccheung@47103 63 assert(_flags == 0, "sanity");
ccheung@47103 64 if (!f2_used) {
ccheung@47103 65 assert(_f2 == 0, "sanity");
ccheung@47103 66 }
ccheung@47103 67 }
ccheung@47103 68
ccheung@47103 69 void ConstantPoolCacheEntry::reinitialize(bool f2_used) {
ccheung@47103 70 _indices &= cp_index_mask;
ccheung@47103 71 _f1 = NULL;
ccheung@47103 72 _flags = 0;
ccheung@47103 73 if (!f2_used) {
ccheung@47103 74 _f2 = 0;
ccheung@47103 75 }
ccheung@47103 76 }
ccheung@47103 77
twisti@13391 78 int ConstantPoolCacheEntry::make_flags(TosState state,
twisti@13391 79 int option_bits,
twisti@13391 80 int field_index_or_method_params) {
twisti@13391 81 assert(state < number_of_states, "Invalid state in make_flags");
twisti@13391 82 int f = ((int)state << tos_state_shift) | option_bits | field_index_or_method_params;
duke@1 83 // Preserve existing flag bit values
twisti@13391 84 // The low bits are a field offset, or else the method parameter size.
duke@1 85 #ifdef ASSERT
twisti@13391 86 TosState old_state = flag_state();
twisti@13391 87 assert(old_state == (TosState)0 || old_state == state,
duke@1 88 "inconsistent cpCache flags state");
duke@1 89 #endif
duke@1 90 return (_flags | f) ;
duke@1 91 }
duke@1 92
duke@1 93 void ConstantPoolCacheEntry::set_bytecode_1(Bytecodes::Code code) {
duke@1 94 #ifdef ASSERT
duke@1 95 // Read once.
duke@1 96 volatile Bytecodes::Code c = bytecode_1();
duke@1 97 assert(c == 0 || c == code || code == 0, "update must be consistent");
duke@1 98 #endif
duke@1 99 // Need to flush pending stores here before bytecode is written.
coleenp@47789 100 OrderAccess::release_store(&_indices, _indices | ((u_char)code << bytecode_1_shift));
duke@1 101 }
duke@1 102
duke@1 103 void ConstantPoolCacheEntry::set_bytecode_2(Bytecodes::Code code) {
duke@1 104 #ifdef ASSERT
duke@1 105 // Read once.
duke@1 106 volatile Bytecodes::Code c = bytecode_2();
duke@1 107 assert(c == 0 || c == code || code == 0, "update must be consistent");
duke@1 108 #endif
duke@1 109 // Need to flush pending stores here before bytecode is written.
coleenp@47789 110 OrderAccess::release_store(&_indices, _indices | ((u_char)code << bytecode_2_shift));
duke@1 111 }
duke@1 112
twisti@13391 113 // Sets f1, ordering with previous writes.
coleenp@13728 114 void ConstantPoolCacheEntry::release_set_f1(Metadata* f1) {
twisti@13391 115 assert(f1 != NULL, "");
coleenp@47789 116 OrderAccess::release_store(&_f1, f1);
twisti@8316 117 }
twisti@7104 118
hseigel@47839 119 void ConstantPoolCacheEntry::set_indy_resolution_failed() {
hseigel@47839 120 OrderAccess::release_store(&_flags, _flags | (1 << indy_resolution_failed_shift));
hseigel@47839 121 }
hseigel@47839 122
duke@1 123 // Note that concurrent update of both bytecodes can leave one of them
duke@1 124 // reset to zero. This is harmless; the interpreter will simply re-resolve
duke@1 125 // the damaged entry. More seriously, the memory synchronization is needed
duke@1 126 // to flush other fields (f1, f2) completely to memory before the bytecodes
duke@1 127 // are updated, lest other processors see a non-zero bytecode but zero f1/f2.
duke@1 128 void ConstantPoolCacheEntry::set_field(Bytecodes::Code get_code,
duke@1 129 Bytecodes::Code put_code,
coleenp@46329 130 Klass* field_holder,
never@10546 131 int field_index,
duke@1 132 int field_offset,
duke@1 133 TosState field_type,
duke@1 134 bool is_final,
coleenp@13728 135 bool is_volatile,
coleenp@13728 136 Klass* root_klass) {
coleenp@46329 137 set_f1(field_holder);
duke@1 138 set_f2(field_offset);
twisti@13391 139 assert((field_index & field_index_mask) == field_index,
duke@1 140 "field index does not fit in low flag bits");
twisti@13391 141 set_field_flags(field_type,
twisti@13391 142 ((is_volatile ? 1 : 0) << is_volatile_shift) |
twisti@13391 143 ((is_final ? 1 : 0) << is_final_shift),
twisti@13391 144 field_index);
duke@1 145 set_bytecode_1(get_code);
duke@1 146 set_bytecode_2(put_code);
duke@1 147 NOT_PRODUCT(verify(tty));
duke@1 148 }
duke@1 149
twisti@13391 150 void ConstantPoolCacheEntry::set_parameter_size(int value) {
twisti@13391 151 // This routine is called only in corner cases where the CPCE is not yet initialized.
twisti@13391 152 // See AbstractInterpreter::deopt_continue_after_entry.
twisti@13391 153 assert(_flags == 0 || parameter_size() == 0 || parameter_size() == value,
david@33105 154 "size must not change: parameter_size=%d, value=%d", parameter_size(), value);
twisti@13391 155 // Setting the parameter size by itself is only safe if the
twisti@13391 156 // current value of _flags is 0, otherwise another thread may have
twisti@13391 157 // updated it and we don't want to overwrite that value. Don't
twisti@13391 158 // bother trying to update it once it's nonzero but always make
twisti@13391 159 // sure that the final parameter size agrees with what was passed.
twisti@13391 160 if (_flags == 0) {
coleenp@47789 161 intx newflags = (value & parameter_size_mask);
coleenp@47789 162 Atomic::cmpxchg(newflags, &_flags, (intx)0);
twisti@13391 163 }
twisti@13391 164 guarantee(parameter_size() == value,
david@33105 165 "size must not change: parameter_size=%d, value=%d", parameter_size(), value);
duke@1 166 }
duke@1 167
drchase@20017 168 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
coleenp@46727 169 const methodHandle& method,
coleenp@44738 170 int vtable_index,
coleenp@44738 171 bool sender_is_interface) {
drchase@20017 172 bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean
duke@1 173 assert(method->interpreter_entry() != NULL, "should have been set at this point");
duke@1 174 assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache");
duke@1 175
duke@1 176 int byte_no = -1;
twisti@13391 177 bool change_to_virtual = false;
dholmes@51369 178 InstanceKlass* holder = NULL; // have to declare this outside the switch
duke@1 179 switch (invoke_code) {
twisti@13391 180 case Bytecodes::_invokeinterface:
dholmes@51369 181 holder = method->method_holder();
dholmes@51369 182 // check for private interface method invocations
dholmes@51369 183 if (vtable_index == Method::nonvirtual_vtable_index && holder->is_interface() ) {
dholmes@51369 184 assert(method->is_private(), "unexpected non-private method");
dholmes@51369 185 assert(method->can_be_statically_bound(), "unexpected non-statically-bound method");
dholmes@51369 186 // set_f2_as_vfinal_method checks if is_vfinal flag is true.
dholmes@51369 187 set_method_flags(as_TosState(method->result_type()),
dholmes@51369 188 ( 1 << is_vfinal_shift) |
dholmes@51369 189 ((method->is_final_method() ? 1 : 0) << is_final_shift),
dholmes@51369 190 method()->size_of_parameters());
dholmes@51369 191 set_f2_as_vfinal_method(method());
dholmes@51369 192 byte_no = 2;
dholmes@51369 193 set_f1(holder); // interface klass*
dholmes@51369 194 break;
dholmes@51369 195 }
dholmes@51369 196 else {
dholmes@51369 197 // We get here from InterpreterRuntime::resolve_invoke when an invokeinterface
dholmes@51369 198 // instruction links to a non-interface method (in Object). This can happen when
dholmes@51369 199 // an interface redeclares an Object method (like CharSequence declaring toString())
dholmes@51369 200 // or when invokeinterface is used explicitly.
dholmes@51369 201 // In that case, the method has no itable index and must be invoked as a virtual.
dholmes@51369 202 // Set a flag to keep track of this corner case.
dholmes@51369 203 assert(holder->is_interface() || holder == SystemDictionary::Object_klass(), "unexpected holder class");
dholmes@51369 204 assert(method->is_public(), "Calling non-public method in Object with invokeinterface");
dholmes@51369 205 change_to_virtual = true;
twisti@13391 206
dholmes@51369 207 // ...and fall through as if we were handling invokevirtual:
dholmes@51369 208 }
duke@1 209 case Bytecodes::_invokevirtual:
twisti@13391 210 {
drchase@20017 211 if (!is_vtable_call) {
drchase@20017 212 assert(method->can_be_statically_bound(), "");
twisti@13391 213 // set_f2_as_vfinal_method checks if is_vfinal flag is true.
twisti@13391 214 set_method_flags(as_TosState(method->result_type()),
twisti@13391 215 ( 1 << is_vfinal_shift) |
twisti@13391 216 ((method->is_final_method() ? 1 : 0) << is_final_shift) |
twisti@13391 217 ((change_to_virtual ? 1 : 0) << is_forced_virtual_shift),
twisti@13391 218 method()->size_of_parameters());
twisti@13391 219 set_f2_as_vfinal_method(method());
duke@1 220 } else {
drchase@20017 221 assert(!method->can_be_statically_bound(), "");
duke@1 222 assert(vtable_index >= 0, "valid index");
twisti@13391 223 assert(!method->is_final_method(), "sanity");
twisti@13391 224 set_method_flags(as_TosState(method->result_type()),
twisti@13391 225 ((change_to_virtual ? 1 : 0) << is_forced_virtual_shift),
twisti@13391 226 method()->size_of_parameters());
duke@1 227 set_f2(vtable_index);
duke@1 228 }
duke@1 229 byte_no = 2;
duke@1 230 break;
jrose@6062 231 }
jrose@6062 232
duke@1 233 case Bytecodes::_invokespecial:
duke@1 234 case Bytecodes::_invokestatic:
drchase@20017 235 assert(!is_vtable_call, "");
twisti@13391 236 // Note: Read and preserve the value of the is_vfinal flag on any
twisti@13391 237 // invokevirtual bytecode shared with this constant pool cache entry.
twisti@13391 238 // It is cheap and safe to consult is_vfinal() at all times.
twisti@13391 239 // Once is_vfinal is set, it must stay that way, lest we get a dangling oop.
twisti@13391 240 set_method_flags(as_TosState(method->result_type()),
twisti@13391 241 ((is_vfinal() ? 1 : 0) << is_vfinal_shift) |
twisti@13391 242 ((method->is_final_method() ? 1 : 0) << is_final_shift),
twisti@13391 243 method()->size_of_parameters());
duke@1 244 set_f1(method());
duke@1 245 byte_no = 1;
duke@1 246 break;
duke@1 247 default:
duke@1 248 ShouldNotReachHere();
duke@1 249 break;
duke@1 250 }
duke@1 251
duke@1 252 // Note: byte_no also appears in TemplateTable::resolve.
duke@1 253 if (byte_no == 1) {
twisti@13391 254 assert(invoke_code != Bytecodes::_invokevirtual &&
twisti@13391 255 invoke_code != Bytecodes::_invokeinterface, "");
dholmes@54379 256 bool do_resolve = true;
coleenp@44738 257 // Don't mark invokespecial to method as resolved if sender is an interface. The receiver
coleenp@44738 258 // has to be checked that it is a subclass of the current class every time this bytecode
coleenp@44738 259 // is executed.
dholmes@54379 260 if (invoke_code == Bytecodes::_invokespecial && sender_is_interface &&
dholmes@54379 261 method->name() != vmSymbols::object_initializer_name()) {
dholmes@54379 262 do_resolve = false;
dholmes@54379 263 }
dholmes@54379 264 // Don't mark invokestatic to method as resolved if the holder class has not yet completed
dholmes@54379 265 // initialization. An invokestatic must only proceed if the class is initialized, but if
dholmes@54379 266 // we resolve it before then that class initialization check is skipped.
dholmes@54379 267 if (invoke_code == Bytecodes::_invokestatic && !method->method_holder()->is_initialized()) {
dholmes@54379 268 do_resolve = false;
dholmes@54379 269 }
dholmes@54379 270 if (do_resolve) {
dholmes@51369 271 set_bytecode_1(invoke_code);
coleenp@44738 272 }
duke@1 273 } else if (byte_no == 2) {
duke@1 274 if (change_to_virtual) {
twisti@13391 275 assert(invoke_code == Bytecodes::_invokeinterface, "");
duke@1 276 // NOTE: THIS IS A HACK - BE VERY CAREFUL!!!
duke@1 277 //
duke@1 278 // Workaround for the case where we encounter an invokeinterface, but we
duke@1 279 // should really have an _invokevirtual since the resolved method is a
duke@1 280 // virtual method in java.lang.Object. This is a corner case in the spec
duke@1 281 // but is presumably legal. javac does not generate this code.
duke@1 282 //
hseigel@50268 283 // We do not set bytecode_1() to _invokeinterface, because that is the
hseigel@50268 284 // bytecode # used by the interpreter to see if it is resolved. In this
hseigel@50268 285 // case, the method gets reresolved with caller for each interface call
hseigel@50268 286 // because the actual selected method may not be public.
hseigel@50268 287 //
duke@1 288 // We set bytecode_2() to _invokevirtual.
duke@1 289 // See also interpreterRuntime.cpp. (8/25/2000)
duke@1 290 } else {
dholmes@51369 291 assert(invoke_code == Bytecodes::_invokevirtual ||
dholmes@51369 292 (invoke_code == Bytecodes::_invokeinterface &&
dholmes@51369 293 ((method->is_private() ||
dholmes@51369 294 (method->is_final() && method->method_holder() == SystemDictionary::Object_klass())))),
dholmes@51369 295 "unexpected invocation mode");
dholmes@51369 296 if (invoke_code == Bytecodes::_invokeinterface &&
dholmes@51369 297 (method->is_private() || method->is_final())) {
dholmes@51369 298 // We set bytecode_1() to _invokeinterface, because that is the
dholmes@51369 299 // bytecode # used by the interpreter to see if it is resolved.
dholmes@51369 300 // We set bytecode_2() to _invokevirtual.
dholmes@51369 301 set_bytecode_1(invoke_code);
dholmes@51369 302 }
duke@1 303 }
twisti@13391 304 // set up for invokevirtual, even if linking for invokeinterface also:
twisti@13391 305 set_bytecode_2(Bytecodes::_invokevirtual);
duke@1 306 } else {
duke@1 307 ShouldNotReachHere();
duke@1 308 }
duke@1 309 NOT_PRODUCT(verify(tty));
duke@1 310 }
duke@1 311
coleenp@46727 312 void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, const methodHandle& method,
coleenp@44738 313 bool sender_is_interface) {
drchase@20017 314 int index = Method::nonvirtual_vtable_index;
drchase@20017 315 // index < 0; FIXME: inline and customize set_direct_or_vtable_call
coleenp@44738 316 set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface);
drchase@20017 317 }
duke@1 318
coleenp@46727 319 void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, const methodHandle& method, int index) {
drchase@20017 320 // either the method is a miranda or its holder should accept the given index
drchase@20017 321 assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), "");
drchase@20017 322 // index >= 0; FIXME: inline and customize set_direct_or_vtable_call
coleenp@44738 323 set_direct_or_vtable_call(invoke_code, method, index, false);
drchase@20017 324 }
drchase@20017 325
vlivanov@48860 326 void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code,
vlivanov@48860 327 Klass* referenced_klass,
vlivanov@48860 328 const methodHandle& method, int index) {
drchase@20017 329 assert(method->method_holder()->verify_itable_index(index), "");
drchase@20017 330 assert(invoke_code == Bytecodes::_invokeinterface, "");
coleenp@14391 331 InstanceKlass* interf = method->method_holder();
coleenp@14391 332 assert(interf->is_interface(), "must be an interface");
twisti@13391 333 assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");
vlivanov@48860 334 set_f1(referenced_klass);
vlivanov@48860 335 set_f2((intx)method());
twisti@13391 336 set_method_flags(as_TosState(method->result_type()),
twisti@13391 337 0, // no option bits
twisti@13391 338 method()->size_of_parameters());
duke@1 339 set_bytecode_1(Bytecodes::_invokeinterface);
duke@1 340 }
duke@1 341
duke@1 342
coleenp@33593 343 void ConstantPoolCacheEntry::set_method_handle(const constantPoolHandle& cpool, const CallInfo &call_info) {
twisti@14393 344 set_method_handle_common(cpool, Bytecodes::_invokehandle, call_info);
jrose@6062 345 }
jrose@6062 346
coleenp@33593 347 void ConstantPoolCacheEntry::set_dynamic_call(const constantPoolHandle& cpool, const CallInfo &call_info) {
twisti@14393 348 set_method_handle_common(cpool, Bytecodes::_invokedynamic, call_info);
jrose@6062 349 }
jrose@6062 350
coleenp@33593 351 void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle& cpool,
twisti@13740 352 Bytecodes::Code invoke_code,
twisti@14393 353 const CallInfo &call_info) {
twisti@13391 354 // NOTE: This CPCE can be the subject of data races.
coleenp@13728 355 // There are three words to update: flags, refs[f2], f1 (in that order).
twisti@13391 356 // Writers must store all other values before f1.
twisti@13391 357 // Readers must test f1 first for non-null before reading other fields.
twisti@13740 358 // Competing writers must acquire exclusive access via a lock.
twisti@13740 359 // A losing writer waits on the lock until the winner writes f1 and leaves
twisti@13740 360 // the lock, so that when the losing writer returns, he can use the linked
twisti@13740 361 // cache entry.
twisti@13740 362
coleenp@46271 363 objArrayHandle resolved_references(Thread::current(), cpool->resolved_references());
coleenp@28019 364 // Use the resolved_references() lock for this cpCache entry.
coleenp@28019 365 // resolved_references are created for all classes with Invokedynamic, MethodHandle
coleenp@28019 366 // or MethodType constant pool cache entries.
coleenp@28019 367 assert(resolved_references() != NULL,
coleenp@28019 368 "a resolved_references array should have been created for this class");
coleenp@28019 369 ObjectLocker ol(resolved_references, Thread::current());
twisti@13740 370 if (!is_f1_null()) {
twisti@13740 371 return;
twisti@13740 372 }
twisti@13391 373
hseigel@47839 374 if (indy_resolution_failed()) {
hseigel@47839 375 // Before we got here, another thread got a LinkageError exception during
hseigel@47839 376 // resolution. Ignore our success and throw their exception.
hseigel@47839 377 ConstantPoolCache* cpCache = cpool->cache();
hseigel@47839 378 int index = -1;
hseigel@47839 379 for (int i = 0; i < cpCache->length(); i++) {
hseigel@47839 380 if (cpCache->entry_at(i) == this) {
hseigel@47839 381 index = i;
hseigel@47839 382 break;
hseigel@47839 383 }
hseigel@47839 384 }
hseigel@47839 385 guarantee(index >= 0, "Didn't find cpCache entry!");
hseigel@47839 386 int encoded_index = ResolutionErrorTable::encode_cpcache_index(
hseigel@47839 387 ConstantPool::encode_invokedynamic_index(index));
hseigel@47839 388 Thread* THREAD = Thread::current();
hseigel@47839 389 ConstantPool::throw_resolution_error(cpool, encoded_index, THREAD);
hseigel@47839 390 return;
hseigel@47839 391 }
hseigel@47839 392
twisti@14393 393 const methodHandle adapter = call_info.resolved_method();
twisti@14393 394 const Handle appendix = call_info.resolved_appendix();
twisti@13929 395 const bool has_appendix = appendix.not_null();
twisti@13391 396
coleenp@13728 397 // Write the flags.
lfoltan@54896 398 // MHs and indy are always sig-poly and have a local signature.
twisti@13740 399 set_method_flags(as_TosState(adapter->result_type()),
lfoltan@54896 400 ((has_appendix ? 1 : 0) << has_appendix_shift ) |
lfoltan@54896 401 ( 1 << has_local_signature_shift ) |
lfoltan@54896 402 ( 1 << is_final_shift ),
twisti@13391 403 adapter->size_of_parameters());
twisti@13391 404
twisti@13391 405 if (TraceInvokeDynamic) {
vlivanov@35543 406 ttyLocker ttyl;
lfoltan@54896 407 tty->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method=" PTR_FORMAT " (local signature) ",
twisti@13391 408 invoke_code,
lfoltan@54896 409 p2i(appendix()),
lfoltan@54896 410 (has_appendix ? "" : " (unused)"),
david@33148 411 p2i(adapter()));
twisti@13391 412 adapter->print();
twisti@13391 413 if (has_appendix) appendix()->print();
twisti@13391 414 }
twisti@13391 415
twisti@13391 416 // Method handle invokes and invokedynamic sites use both cp cache words.
coleenp@13728 417 // refs[f2], if not null, contains a value passed as a trailing argument to the adapter.
twisti@13391 418 // In the general case, this could be the call site's MethodType,
twisti@13391 419 // for use with java.lang.Invokers.checkExactType, or else a CallSite object.
coleenp@13728 420 // f1 contains the adapter method which manages the actual call.
twisti@13391 421 // In the general case, this is a compiled LambdaForm.
twisti@13391 422 // (The Java code is free to optimize these calls by binding other
twisti@13391 423 // sorts of methods and appendices to call sites.)
coleenp@13728 424 // JVM-level linking is via f1, as if for invokespecial, and signatures are erased.
twisti@13391 425 // The appendix argument (if any) is added to the signature, and is counted in the parameter_size bits.
coleenp@13728 426 // Even with the appendix, the method will never take more than 255 parameter slots.
twisti@13391 427 //
twisti@13391 428 // This means that given a call site like (List)mh.invoke("foo"),
coleenp@13728 429 // the f1 method has signature '(Ljl/Object;Ljl/invoke/MethodType;)Ljl/Object;',
twisti@13391 430 // not '(Ljava/lang/String;)Ljava/util/List;'.
coleenp@13728 431 // The fact that String and List are involved is encoded in the MethodType in refs[f2].
coleenp@23515 432 // This allows us to create fewer Methods, while keeping type safety.
twisti@13391 433 //
coleenp@13728 434
twisti@13929 435 // Store appendix, if any.
coleenp@13728 436 if (has_appendix) {
lfoltan@54896 437 const int appendix_index = f2_as_index();
twisti@13929 438 assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
twisti@13929 439 assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
twisti@13929 440 resolved_references->obj_at_put(appendix_index, appendix());
twisti@13929 441 }
twisti@13929 442
coleenp@13728 443 release_set_f1(adapter()); // This must be the last one to set (see NOTE above)!
coleenp@13728 444
twisti@13929 445 // The interpreter assembly code does not check byte_2,
twisti@13929 446 // but it is used by is_resolved, method_if_resolved, etc.
coleenp@13728 447 set_bytecode_1(invoke_code);
twisti@13391 448 NOT_PRODUCT(verify(tty));
twisti@13391 449 if (TraceInvokeDynamic) {
vlivanov@35543 450 ttyLocker ttyl;
twisti@13391 451 this->print(tty, 0);
twisti@13391 452 }
lfoltan@54896 453
lfoltan@54896 454 assert(has_appendix == this->has_appendix(), "proper storage of appendix flag");
lfoltan@54896 455 assert(this->has_local_signature(), "proper storage of signature flag");
jrose@2570 456 }
jrose@2570 457
hseigel@47839 458 bool ConstantPoolCacheEntry::save_and_throw_indy_exc(
hseigel@47839 459 const constantPoolHandle& cpool, int cpool_index, int index, constantTag tag, TRAPS) {
hseigel@47839 460
hseigel@47839 461 assert(HAS_PENDING_EXCEPTION, "No exception got thrown!");
hseigel@47839 462 assert(PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass()),
hseigel@47839 463 "No LinkageError exception");
hseigel@47839 464
hseigel@47839 465 // Use the resolved_references() lock for this cpCache entry.
hseigel@47839 466 // resolved_references are created for all classes with Invokedynamic, MethodHandle
hseigel@47839 467 // or MethodType constant pool cache entries.
hseigel@47839 468 objArrayHandle resolved_references(Thread::current(), cpool->resolved_references());
hseigel@47839 469 assert(resolved_references() != NULL,
hseigel@47839 470 "a resolved_references array should have been created for this class");
hseigel@47839 471 ObjectLocker ol(resolved_references, THREAD);
hseigel@47839 472
hseigel@47839 473 // if f1 is not null or the indy_resolution_failed flag is set then another
hseigel@47839 474 // thread either succeeded in resolving the method or got a LinkageError
hseigel@47839 475 // exception, before this thread was able to record its failure. So, clear
hseigel@47839 476 // this thread's exception and return false so caller can use the earlier
hseigel@47839 477 // thread's result.
hseigel@47839 478 if (!is_f1_null() || indy_resolution_failed()) {
hseigel@47839 479 CLEAR_PENDING_EXCEPTION;
hseigel@47839 480 return false;
hseigel@47839 481 }
hseigel@47839 482
hseigel@47839 483 Symbol* error = PENDING_EXCEPTION->klass()->name();
hseigel@47839 484 Symbol* message = java_lang_Throwable::detail_message(PENDING_EXCEPTION);
hseigel@47839 485
hseigel@47839 486 SystemDictionary::add_resolution_error(cpool, index, error, message);
hseigel@47839 487 set_indy_resolution_failed();
hseigel@47839 488 return true;
hseigel@47839 489 }
hseigel@47839 490
coleenp@33593 491 Method* ConstantPoolCacheEntry::method_if_resolved(const constantPoolHandle& cpool) {
jrose@10008 492 // Decode the action of set_method and set_interface_call
twisti@13391 493 Bytecodes::Code invoke_code = bytecode_1();
twisti@13391 494 if (invoke_code != (Bytecodes::Code)0) {
goetz@22859 495 Metadata* f1 = f1_ord();
jrose@10008 496 if (f1 != NULL) {
jrose@10008 497 switch (invoke_code) {
jrose@10008 498 case Bytecodes::_invokeinterface:
jrose@10008 499 assert(f1->is_klass(), "");
iklam@52030 500 return klassItable::method_for_itable_index((InstanceKlass*)f1, f2_as_index());
jrose@10008 501 case Bytecodes::_invokestatic:
jrose@10008 502 case Bytecodes::_invokespecial:
twisti@13391 503 assert(!has_appendix(), "");
coleenp@13728 504 case Bytecodes::_invokehandle:
coleenp@13728 505 case Bytecodes::_invokedynamic:
jrose@10008 506 assert(f1->is_method(), "");
coleenp@13728 507 return (Method*)f1;
jwilhelm@46630 508 default:
jwilhelm@46630 509 break;
jrose@10008 510 }
jrose@10008 511 }
jrose@10008 512 }
twisti@13391 513 invoke_code = bytecode_2();
twisti@13391 514 if (invoke_code != (Bytecodes::Code)0) {
jrose@10008 515 switch (invoke_code) {
jrose@10008 516 case Bytecodes::_invokevirtual:
jrose@10008 517 if (is_vfinal()) {
jrose@10008 518 // invokevirtual
coleenp@13728 519 Method* m = f2_as_vfinal_method();
jrose@10008 520 assert(m->is_method(), "");
jrose@10008 521 return m;
jrose@10008 522 } else {
jrose@10008 523 int holder_index = cpool->uncached_klass_ref_index_at(constant_pool_index());
jrose@10008 524 if (cpool->tag_at(holder_index).is_klass()) {
coleenp@13728 525 Klass* klass = cpool->resolved_klass_at(holder_index);
mgerdin@35900 526 return klass->method_at_vtable(f2_as_index());
jrose@10008 527 }
jrose@10008 528 }
twisti@13391 529 break;
jwilhelm@46630 530 default:
jwilhelm@46630 531 break;
jrose@10008 532 }
jrose@10008 533 }
jrose@10008 534 return NULL;
jrose@10008 535 }
jrose@10008 536
jrose@10008 537
coleenp@33593 538 oop ConstantPoolCacheEntry::appendix_if_resolved(const constantPoolHandle& cpool) {
drchase@24926 539 if (!has_appendix())
coleenp@13728 540 return NULL;
lfoltan@54896 541 const int ref_index = f2_as_index();
coleenp@13728 542 objArrayOop resolved_references = cpool->resolved_references();
coleenp@13728 543 return resolved_references->obj_at(ref_index);
duke@1 544 }
duke@1 545
duke@1 546
dcubed@15591 547 #if INCLUDE_JVMTI
vlivanov@48860 548
vlivanov@48860 549 void log_adjust(const char* entry_type, Method* old_method, Method* new_method, bool* trace_name_printed) {
vlivanov@48860 550 if (log_is_enabled(Info, redefine, class, update)) {
vlivanov@48860 551 ResourceMark rm;
vlivanov@48860 552 if (!(*trace_name_printed)) {
vlivanov@48860 553 log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
vlivanov@48860 554 *trace_name_printed = true;
vlivanov@48860 555 }
vlivanov@48860 556 log_debug(redefine, class, update, constantpool)
vlivanov@48860 557 ("cpc %s entry update: %s(%s)", entry_type, new_method->name()->as_C_string(), new_method->signature()->as_C_string());
vlivanov@48860 558 }
vlivanov@48860 559 }
vlivanov@48860 560
duke@1 561 // RedefineClasses() API support:
dcubed@15591 562 // If this ConstantPoolCacheEntry refers to old_method then update it
duke@1 563 // to refer to new_method.
vlivanov@48860 564 void ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
coleenp@13728 565 Method* new_method, bool * trace_name_printed) {
duke@1 566
duke@1 567 if (is_vfinal()) {
twisti@13391 568 // virtual and final so _f2 contains method ptr instead of vtable index
twisti@13391 569 if (f2_as_vfinal_method() == old_method) {
duke@1 570 // match old_method so need an update
twisti@13391 571 // NOTE: can't use set_f2_as_vfinal_method as it asserts on different values
duke@1 572 _f2 = (intptr_t)new_method;
vlivanov@48860 573 log_adjust("vfinal", old_method, new_method, trace_name_printed);
duke@1 574 }
vlivanov@48860 575 return;
duke@1 576 }
duke@1 577
vlivanov@48860 578 assert (_f1 != NULL, "should not call with uninteresting entry");
vlivanov@48860 579
vlivanov@48860 580 if (!(_f1->is_method())) {
vlivanov@48860 581 // _f1 is a Klass* for an interface, _f2 is the method
vlivanov@48860 582 if (f2_as_interface_method() == old_method) {
vlivanov@48860 583 _f2 = (intptr_t)new_method;
vlivanov@48860 584 log_adjust("interface", old_method, new_method, trace_name_printed);
vlivanov@48860 585 }
vlivanov@48860 586 } else if (_f1 == old_method) {
vlivanov@48860 587 _f1 = new_method;
vlivanov@48860 588 log_adjust("special, static or dynamic", old_method, new_method, trace_name_printed);
duke@1 589 }
duke@1 590 }
duke@1 591
dcubed@15591 592 // a constant pool cache entry should never contain old or obsolete methods
dcubed@15591 593 bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() {
vlivanov@48860 594 Method* m = get_interesting_method_entry(NULL);
vlivanov@48860 595 // return false if m refers to a non-deleted old or obsolete method
vlivanov@48860 596 if (m != NULL) {
vlivanov@48860 597 assert(m->is_valid() && m->is_method(), "m is a valid method");
vlivanov@48860 598 return !m->is_old() && !m->is_obsolete(); // old is always set for old and obsolete
vlivanov@48860 599 } else {
dcubed@15591 600 return true;
coleenp@13728 601 }
coleenp@13728 602 }
coleenp@13728 603
sspitsyn@29316 604 Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) {
duke@1 605 if (!is_method_entry()) {
duke@1 606 // not a method entry so not interesting by default
sspitsyn@29316 607 return NULL;
duke@1 608 }
coleenp@13728 609 Method* m = NULL;
duke@1 610 if (is_vfinal()) {
duke@1 611 // virtual and final so _f2 contains method ptr instead of vtable index
twisti@13391 612 m = f2_as_vfinal_method();
twisti@13391 613 } else if (is_f1_null()) {
duke@1 614 // NULL _f1 means this is a virtual entry so also not interesting
sspitsyn@29316 615 return NULL;
duke@1 616 } else {
coleenp@13728 617 if (!(_f1->is_method())) {
vlivanov@48860 618 // _f1 is a Klass* for an interface
vlivanov@48860 619 m = f2_as_interface_method();
vlivanov@48860 620 } else {
vlivanov@48860 621 m = f1_as_method();
duke@1 622 }
duke@1 623 }
duke@1 624 assert(m != NULL && m->is_method(), "sanity check");
coleenp@13728 625 if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {
duke@1 626 // robustness for above sanity checks or method is not in
duke@1 627 // the interesting class
sspitsyn@29316 628 return NULL;
duke@1 629 }
duke@1 630 // the method is in the interesting class so the entry is interesting
sspitsyn@29316 631 return m;
duke@1 632 }
dcubed@15591 633 #endif // INCLUDE_JVMTI
duke@1 634
duke@1 635 void ConstantPoolCacheEntry::print(outputStream* st, int index) const {
duke@1 636 // print separator
dholmes@11956 637 if (index == 0) st->print_cr(" -------------");
duke@1 638 // print entry
bpittore@31592 639 st->print("%3d (" PTR_FORMAT ") ", index, (intptr_t)this);
dcubed@15591 640 st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(),
dcubed@15591 641 constant_pool_index());
bpittore@31592 642 st->print_cr(" [ " PTR_FORMAT "]", (intptr_t)_f1);
bpittore@31592 643 st->print_cr(" [ " PTR_FORMAT "]", (intptr_t)_f2);
bpittore@31592 644 st->print_cr(" [ " PTR_FORMAT "]", (intptr_t)_flags);
dholmes@11956 645 st->print_cr(" -------------");
duke@1 646 }
duke@1 647
duke@1 648 void ConstantPoolCacheEntry::verify(outputStream* st) const {
duke@1 649 // not implemented yet
duke@1 650 }
duke@1 651
duke@1 652 // Implementation of ConstantPoolCache
duke@1 653
coleenp@15928 654 ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data,
coleenp@15928 655 const intStack& index_map,
coleenp@21557 656 const intStack& invokedynamic_index_map,
coleenp@15928 657 const intStack& invokedynamic_map, TRAPS) {
coleenp@21557 658
coleenp@21557 659 const int length = index_map.length() + invokedynamic_index_map.length();
coleenp@13728 660 int size = ConstantPoolCache::size(length);
coleenp@13728 661
iklam@46746 662 return new (loader_data, size, MetaspaceObj::ConstantPoolCacheType, THREAD)
coleenp@21557 663 ConstantPoolCache(length, index_map, invokedynamic_index_map, invokedynamic_map);
coleenp@13728 664 }
coleenp@13728 665
coleenp@15928 666 void ConstantPoolCache::initialize(const intArray& inverse_index_map,
coleenp@21557 667 const intArray& invokedynamic_inverse_index_map,
coleenp@15928 668 const intArray& invokedynamic_references_map) {
coleenp@21557 669 for (int i = 0; i < inverse_index_map.length(); i++) {
jrose@4429 670 ConstantPoolCacheEntry* e = entry_at(i);
fzhinkin@38031 671 int original_index = inverse_index_map.at(i);
twisti@13929 672 e->initialize_entry(original_index);
coleenp@13728 673 assert(entry_at(i) == e, "sanity");
twisti@13929 674 }
coleenp@21557 675
coleenp@21557 676 // Append invokedynamic entries at the end
coleenp@21557 677 int invokedynamic_offset = inverse_index_map.length();
coleenp@21557 678 for (int i = 0; i < invokedynamic_inverse_index_map.length(); i++) {
coleenp@21557 679 int offset = i + invokedynamic_offset;
coleenp@21557 680 ConstantPoolCacheEntry* e = entry_at(offset);
fzhinkin@38031 681 int original_index = invokedynamic_inverse_index_map.at(i);
coleenp@21557 682 e->initialize_entry(original_index);
coleenp@21557 683 assert(entry_at(offset) == e, "sanity");
coleenp@21557 684 }
coleenp@21557 685
twisti@13929 686 for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
fzhinkin@38031 687 const int cpci = invokedynamic_references_map.at(ref);
twisti@13929 688 if (cpci >= 0) {
twisti@13929 689 entry_at(cpci)->initialize_resolved_reference_index(ref);
jrose@4429 690 }
jrose@4429 691 }
duke@1 692 }
duke@1 693
ccheung@47103 694 void ConstantPoolCache::verify_just_initialized() {
ccheung@47103 695 DEBUG_ONLY(walk_entries_for_initialization(/*check_only = */ true));
ccheung@47103 696 }
ccheung@47103 697
ccheung@47103 698 void ConstantPoolCache::remove_unshareable_info() {
ccheung@47103 699 walk_entries_for_initialization(/*check_only = */ false);
ccheung@47103 700 }
ccheung@47103 701
ccheung@47103 702 void ConstantPoolCache::walk_entries_for_initialization(bool check_only) {
ccheung@47103 703 assert(DumpSharedSpaces, "sanity");
ccheung@47103 704 // When dumping the archive, we want to clean up the ConstantPoolCache
ccheung@47103 705 // to remove any effect of linking due to the execution of Java code --
ccheung@47103 706 // each ConstantPoolCacheEntry will have the same contents as if
ccheung@47103 707 // ConstantPoolCache::initialize has just returned:
ccheung@47103 708 //
ccheung@47103 709 // - We keep the ConstantPoolCache::constant_pool_index() bits for all entries.
ccheung@47103 710 // - We keep the "f2" field for entries used by invokedynamic and invokehandle
ccheung@47103 711 // - All other bits in the entries are cleared to zero.
ccheung@47103 712 ResourceMark rm;
ccheung@47103 713
ccheung@47103 714 InstanceKlass* ik = constant_pool()->pool_holder();
ccheung@47103 715 bool* f2_used = NEW_RESOURCE_ARRAY(bool, length());
ccheung@47103 716 memset(f2_used, 0, sizeof(bool) * length());
ccheung@47103 717
ccheung@47103 718 // Find all the slots that we need to preserve f2
ccheung@47103 719 for (int i = 0; i < ik->methods()->length(); i++) {
ccheung@47103 720 Method* m = ik->methods()->at(i);
ccheung@47103 721 RawBytecodeStream bcs(m);
ccheung@47103 722 while (!bcs.is_last_bytecode()) {
ccheung@47103 723 Bytecodes::Code opcode = bcs.raw_next();
ccheung@47103 724 switch (opcode) {
ccheung@47103 725 case Bytecodes::_invokedynamic: {
ccheung@47103 726 int index = Bytes::get_native_u4(bcs.bcp() + 1);
ccheung@47103 727 int cp_cache_index = constant_pool()->invokedynamic_cp_cache_index(index);
ccheung@47103 728 f2_used[cp_cache_index] = 1;
ccheung@47103 729 }
ccheung@47103 730 break;
ccheung@47103 731 case Bytecodes::_invokehandle: {
ccheung@47103 732 int cp_cache_index = Bytes::get_native_u2(bcs.bcp() + 1);
ccheung@47103 733 f2_used[cp_cache_index] = 1;
ccheung@47103 734 }
ccheung@47103 735 break;
ccheung@47103 736 default:
ccheung@47103 737 break;
ccheung@47103 738 }
ccheung@47103 739 }
ccheung@47103 740 }
ccheung@47103 741
ccheung@47103 742 if (check_only) {
ccheung@47103 743 DEBUG_ONLY(
ccheung@47103 744 for (int i=0; i<length(); i++) {
ccheung@47103 745 entry_at(i)->verify_just_initialized(f2_used[i]);
ccheung@47103 746 })
ccheung@47103 747 } else {
ccheung@47103 748 for (int i=0; i<length(); i++) {
ccheung@47103 749 entry_at(i)->reinitialize(f2_used[i]);
ccheung@47103 750 }
ccheung@47103 751 }
ccheung@47103 752 }
ccheung@47103 753
coleenp@47095 754 void ConstantPoolCache::deallocate_contents(ClassLoaderData* data) {
coleenp@47095 755 assert(!is_shared(), "shared caches are not deallocated");
coleenp@47095 756 data->remove_handle(_resolved_references);
coleenp@47095 757 set_resolved_references(NULL);
coleenp@47095 758 MetadataFactory::free_array<u2>(data, _reference_map);
coleenp@47095 759 set_reference_map(NULL);
coleenp@47095 760 }
coleenp@47095 761
jiangli@46810 762 #if INCLUDE_CDS_JAVA_HEAP
jiangli@46810 763 oop ConstantPoolCache::archived_references() {
kbarrett@51145 764 if (CompressedOops::is_null(_archived_references)) {
kbarrett@51145 765 return NULL;
kbarrett@51145 766 }
jiangli@52991 767 return HeapShared::materialize_archived_object(_archived_references);
jiangli@46810 768 }
jiangli@46810 769
jiangli@46810 770 void ConstantPoolCache::set_archived_references(oop o) {
jiangli@46810 771 assert(DumpSharedSpaces, "called only during runtime");
kbarrett@51145 772 _archived_references = CompressedOops::encode(o);
jiangli@46810 773 }
jiangli@46810 774 #endif
jiangli@46810 775
dcubed@15591 776 #if INCLUDE_JVMTI
duke@1 777 // RedefineClasses() API support:
dcubed@15591 778 // If any entry of this ConstantPoolCache points to any of
duke@1 779 // old_methods, replace it with the corresponding new_method.
sspitsyn@29316 780 void ConstantPoolCache::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
sspitsyn@29316 781 for (int i = 0; i < length(); i++) {
sspitsyn@29316 782 ConstantPoolCacheEntry* entry = entry_at(i);
sspitsyn@29316 783 Method* old_method = entry->get_interesting_method_entry(holder);
sspitsyn@29316 784 if (old_method == NULL || !old_method->is_old()) {
sspitsyn@29316 785 continue; // skip uninteresting entries
sspitsyn@29316 786 }
sspitsyn@29316 787 if (old_method->is_deleted()) {
sspitsyn@29316 788 // clean up entries with deleted methods
sspitsyn@29316 789 entry->initialize_entry(entry->constant_pool_index());
sspitsyn@29316 790 continue;
sspitsyn@29316 791 }
sspitsyn@29316 792 Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
sspitsyn@29316 793
sspitsyn@29316 794 assert(new_method != NULL, "method_with_idnum() should not be NULL");
sspitsyn@29316 795 assert(old_method != new_method, "sanity check");
sspitsyn@29316 796
sspitsyn@29316 797 entry_at(i)->adjust_method_entry(old_method, new_method, trace_name_printed);
sspitsyn@29316 798 }
sspitsyn@29316 799 }
sspitsyn@29316 800
dcubed@15591 801 // the constant pool cache should never contain old or obsolete methods
dcubed@15591 802 bool ConstantPoolCache::check_no_old_or_obsolete_entries() {
coleenp@13728 803 for (int i = 1; i < length(); i++) {
sspitsyn@29316 804 if (entry_at(i)->get_interesting_method_entry(NULL) != NULL &&
dcubed@15591 805 !entry_at(i)->check_no_old_or_obsolete_entries()) {
coleenp@13728 806 return false;
coleenp@13728 807 }
coleenp@13728 808 }
coleenp@13728 809 return true;
coleenp@13728 810 }
dcubed@15591 811
dcubed@15591 812 void ConstantPoolCache::dump_cache() {
dcubed@15591 813 for (int i = 1; i < length(); i++) {
sspitsyn@29316 814 if (entry_at(i)->get_interesting_method_entry(NULL) != NULL) {
dcubed@15591 815 entry_at(i)->print(tty, i);
dcubed@15591 816 }
dcubed@15591 817 }
dcubed@15591 818 }
dcubed@15591 819 #endif // INCLUDE_JVMTI
coleenp@13728 820
iklam@46746 821 void ConstantPoolCache::metaspace_pointers_do(MetaspaceClosure* it) {
iklam@46746 822 log_trace(cds)("Iter(ConstantPoolCache): %p", this);
iklam@46746 823 it->push(&_constant_pool);
iklam@46746 824 it->push(&_reference_map);
iklam@46746 825 }
coleenp@13728 826
coleenp@13728 827 // Printing
coleenp@13728 828
coleenp@13728 829 void ConstantPoolCache::print_on(outputStream* st) const {
drchase@24424 830 st->print_cr("%s", internal_name());
coleenp@13728 831 // print constant pool cache entries
coleenp@13728 832 for (int i = 0; i < length(); i++) entry_at(i)->print(st, i);
coleenp@13728 833 }
coleenp@13728 834
coleenp@13728 835 void ConstantPoolCache::print_value_on(outputStream* st) const {
coleenp@13728 836 st->print("cache [%d]", length());
coleenp@13728 837 print_address_on(st);
coleenp@13728 838 st->print(" for ");
coleenp@13728 839 constant_pool()->print_value_on(st);
coleenp@13728 840 }
coleenp@13728 841
coleenp@13728 842
coleenp@13728 843 // Verification
coleenp@13728 844
coleenp@13728 845 void ConstantPoolCache::verify_on(outputStream* st) {
coleenp@13728 846 // print constant pool cache entries
coleenp@13728 847 for (int i = 0; i < length(); i++) entry_at(i)->verify(st);
coleenp@13728 848 }