1 /* 2 * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_OOPS_CPCACHE_HPP 26 #define SHARE_OOPS_CPCACHE_HPP 27 28 #include "interpreter/bytecodes.hpp" 29 #include "memory/allocation.hpp" 30 #include "oops/array.hpp" 31 #include "oops/oopHandle.hpp" 32 #include "runtime/handles.hpp" 33 #include "utilities/align.hpp" 34 #include "utilities/constantTag.hpp" 35 #include "utilities/growableArray.hpp" 36 37 // The ConstantPoolCache is not a cache! It is the resolution table that the 38 // interpreter uses to avoid going into the runtime and a way to access resolved 39 // values. 40 41 class CallInfo; 42 class ResolvedFieldEntry; 43 class ResolvedIndyEntry; 44 class ResolvedMethodEntry; 45 46 // A constant pool cache is a runtime data structure set aside to a constant pool. The cache 47 // holds runtime information for all field access and invoke bytecodes. The cache 48 // is created and initialized before a class is actively used (i.e., initialized), the indivi- 49 // dual cache entries are filled at resolution (i.e., "link") time (see also: rewriter.*). 50 51 class ConstantPoolCache: public MetaspaceObj { 52 friend class VMStructs; 53 friend class MetadataFactory; 54 private: 55 // If you add a new field that points to any metaspace object, you 56 // must add this field to ConstantPoolCache::metaspace_pointers_do(). 57 58 // The narrowOop pointer to the archived resolved_references. Set at CDS dump 59 // time when caching java heap object is supported. 60 CDS_JAVA_HEAP_ONLY(int _archived_references_index;) // Gap on LP64 61 62 ConstantPool* _constant_pool; // the corresponding constant pool 63 64 // The following fields need to be modified at runtime, so they cannot be 65 // stored in the ConstantPool, which is read-only. 66 // Array of resolved objects from the constant pool and map from resolved 67 // object index to original constant pool index 68 OopHandle _resolved_references; 69 Array<u2>* _reference_map; 70 71 // RedefineClasses support 72 uint64_t _gc_epoch; 73 74 Array<ResolvedIndyEntry>* _resolved_indy_entries; 75 Array<ResolvedFieldEntry>* _resolved_field_entries; 76 Array<ResolvedMethodEntry>* _resolved_method_entries; 77 78 // Sizing 79 debug_only(friend class ClassVerifier;) 80 81 public: 82 // specific but defiinitions for ldc 83 enum { 84 // high order bits are the TosState corresponding to field type or method return type 85 tos_state_bits = 4, 86 tos_state_mask = right_n_bits(tos_state_bits), 87 tos_state_shift = BitsPerInt - tos_state_bits, // see verify_tos_state_shift below 88 // low order bits give field index (for FieldInfo) or method parameter size: 89 field_index_bits = 16, 90 field_index_mask = right_n_bits(field_index_bits), 91 }; 92 93 // Constructor 94 ConstantPoolCache(const intStack& invokedynamic_references_map, 95 Array<ResolvedIndyEntry>* indy_info, 96 Array<ResolvedFieldEntry>* field_entries, 97 Array<ResolvedMethodEntry>* mehtod_entries); 98 99 // Initialization 100 void initialize(const intArray& invokedynamic_references_map); 101 public: 102 static ConstantPoolCache* allocate(ClassLoaderData* loader_data, 103 const intStack& invokedynamic_references_map, 104 const GrowableArray<ResolvedIndyEntry> indy_entries, 105 const GrowableArray<ResolvedFieldEntry> field_entries, 106 const GrowableArray<ResolvedMethodEntry> method_entries, 107 TRAPS); 108 109 void metaspace_pointers_do(MetaspaceClosure* it); 110 MetaspaceObj::Type type() const { return ConstantPoolCacheType; } 111 112 oop archived_references() NOT_CDS_JAVA_HEAP_RETURN_(nullptr); 113 void set_archived_references(int root_index) NOT_CDS_JAVA_HEAP_RETURN; 114 void clear_archived_references() NOT_CDS_JAVA_HEAP_RETURN; 115 116 inline objArrayOop resolved_references(); 117 void set_resolved_references(OopHandle s) { _resolved_references = s; } 118 Array<u2>* reference_map() const { return _reference_map; } 119 void set_reference_map(Array<u2>* o) { _reference_map = o; } 120 121 private: 122 void set_direct_or_vtable_call( 123 Bytecodes::Code invoke_code, // the bytecode used for invoking the method 124 int method_index, // Index into the resolved method entry array 125 const methodHandle& method, // the method/prototype if any (null, otherwise) 126 int vtable_index, // the vtable index if any, else negative 127 bool sender_is_interface 128 ); 129 130 public: 131 void set_direct_call( // sets entry to exact concrete method entry 132 Bytecodes::Code invoke_code, // the bytecode used for invoking the method 133 int method_index, // Index into the resolved method entry array 134 const methodHandle& method, // the method to call 135 bool sender_is_interface 136 ); 137 138 void set_vtable_call( // sets entry to vtable index 139 Bytecodes::Code invoke_code, // the bytecode used for invoking the method 140 int method_index, // Index into the resolved method entry array 141 const methodHandle& method, // resolved method which declares the vtable index 142 int vtable_index // the vtable index 143 ); 144 145 void set_itable_call( 146 Bytecodes::Code invoke_code, // the bytecode used; must be invokeinterface 147 int method_index, // Index into the resolved method entry array 148 Klass* referenced_klass, // the referenced klass in the InterfaceMethodref 149 const methodHandle& method, // the resolved interface method 150 int itable_index // index into itable for the method 151 ); 152 153 // The "appendix" is an optional call-site-specific parameter which is 154 // pushed by the JVM at the end of the argument list. This argument may 155 // be a MethodType for the MH.invokes and a CallSite for an invokedynamic 156 // instruction. However, its exact type and use depends on the Java upcall, 157 // which simply returns a compiled LambdaForm along with any reference 158 // that LambdaForm needs to complete the call. If the upcall returns a 159 // null appendix, the argument is not passed at all. 160 // 161 // The appendix is *not* represented in the signature of the symbolic 162 // reference for the call site, but (if present) it *is* represented in 163 // the Method* bound to the site. This means that static and dynamic 164 // resolution logic needs to make slightly different assessments about the 165 // number and types of arguments. 166 ResolvedMethodEntry* set_method_handle( 167 int method_index, 168 const CallInfo &call_info // Call link information 169 ); 170 171 Method* method_if_resolved(int method_index) const; 172 173 Array<ResolvedFieldEntry>* resolved_field_entries() { return _resolved_field_entries; } 174 inline ResolvedFieldEntry* resolved_field_entry_at(int field_index) const; 175 inline int resolved_field_entries_length() const; 176 void print_resolved_field_entries(outputStream* st) const; 177 178 Array<ResolvedIndyEntry>* resolved_indy_entries() { return _resolved_indy_entries; } 179 inline ResolvedIndyEntry* resolved_indy_entry_at(int index) const; 180 inline int resolved_indy_entries_length() const; 181 void print_resolved_indy_entries(outputStream* st) const; 182 183 Array<ResolvedMethodEntry>* resolved_method_entries() { return _resolved_method_entries; } 184 inline ResolvedMethodEntry* resolved_method_entry_at(int method_index) const; 185 inline int resolved_method_entries_length() const; 186 void print_resolved_method_entries(outputStream* st) const; 187 188 // Assembly code support 189 static ByteSize resolved_references_offset() { return byte_offset_of(ConstantPoolCache, _resolved_references); } 190 static ByteSize invokedynamic_entries_offset() { return byte_offset_of(ConstantPoolCache, _resolved_indy_entries); } 191 static ByteSize field_entries_offset() { return byte_offset_of(ConstantPoolCache, _resolved_field_entries); } 192 static ByteSize method_entries_offset() { return byte_offset_of(ConstantPoolCache, _resolved_method_entries); } 193 194 #if INCLUDE_CDS 195 void remove_unshareable_info(); 196 #endif 197 198 public: 199 static int size() { return align_metadata_size(sizeof(ConstantPoolCache) / wordSize); } 200 201 private: 202 // Helpers 203 ConstantPool** constant_pool_addr() { return &_constant_pool; } 204 205 public: 206 // Accessors 207 void set_constant_pool(ConstantPool* pool) { _constant_pool = pool; } 208 ConstantPool* constant_pool() const { return _constant_pool; } 209 210 // Code generation 211 static ByteSize base_offset() { return in_ByteSize(sizeof(ConstantPoolCache)); } 212 213 #if INCLUDE_JVMTI 214 // RedefineClasses() API support: 215 // If any entry of this ConstantPoolCache points to any of 216 // old_methods, replace it with the corresponding new_method. 217 // trace_name_printed is set to true if the current call has 218 // printed the klass name so that other routines in the adjust_* 219 // group don't print the klass name. 220 void adjust_method_entries(bool* trace_name_printed); 221 bool check_no_old_or_obsolete_entries(); 222 void dump_cache(); 223 #endif // INCLUDE_JVMTI 224 225 #if INCLUDE_CDS 226 void remove_resolved_field_entries_if_non_deterministic(); 227 void remove_resolved_method_entries_if_non_deterministic(); 228 bool can_archive_resolved_method(ResolvedMethodEntry* method_entry); 229 #endif 230 231 // RedefineClasses support 232 DEBUG_ONLY(bool on_stack() { return false; }) 233 void deallocate_contents(ClassLoaderData* data); 234 void record_gc_epoch(); 235 uint64_t gc_epoch() { return _gc_epoch; } 236 237 // Return TRUE if resolution failed and this thread got to record the failure 238 // status. Return FALSE if another thread succeeded or failed in resolving 239 // the method and recorded the success or failure before this thread had a 240 // chance to record its failure. 241 bool save_and_throw_indy_exc(const constantPoolHandle& cpool, int cpool_index, int index, constantTag tag, TRAPS); 242 oop set_dynamic_call(const CallInfo &call_info, int index); 243 oop appendix_if_resolved(int method_index) const; 244 oop appendix_if_resolved(ResolvedMethodEntry* method_entry) const; 245 246 // Printing 247 void print_on(outputStream* st) const; 248 void print_value_on(outputStream* st) const; 249 250 const char* internal_name() const { return "{constant pool cache}"; } 251 252 // Verify 253 void verify_on(outputStream* st); 254 }; 255 256 #endif // SHARE_OOPS_CPCACHE_HPP