1 /* 2 * Copyright (c) 2022, 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 #include "precompiled.hpp" 26 #include "cds/archiveBuilder.hpp" 27 #include "cds/cdsConfig.hpp" 28 #include "cds/classPrelinker.hpp" 29 #include "cds/regeneratedClasses.hpp" 30 #include "classfile/systemDictionary.hpp" 31 #include "classfile/systemDictionaryShared.hpp" 32 #include "classfile/vmClasses.hpp" 33 #include "interpreter/bytecodeStream.hpp" 34 #include "interpreter/interpreterRuntime.hpp" 35 #include "memory/resourceArea.hpp" 36 #include "oops/constantPool.inline.hpp" 37 #include "oops/instanceKlass.hpp" 38 #include "oops/klass.inline.hpp" 39 #include "runtime/handles.inline.hpp" 40 41 ClassPrelinker::ClassesTable* ClassPrelinker::_processed_classes = nullptr; 42 ClassPrelinker::ClassesTable* ClassPrelinker::_vm_classes = nullptr; 43 44 bool ClassPrelinker::is_vm_class(InstanceKlass* ik) { 45 return (_vm_classes->get(ik) != nullptr); 46 } 47 48 void ClassPrelinker::add_one_vm_class(InstanceKlass* ik) { 49 bool created; 50 _vm_classes->put_if_absent(ik, &created); 51 if (created) { 52 InstanceKlass* super = ik->java_super(); 53 if (super != nullptr) { 54 add_one_vm_class(super); 55 } 56 Array<InstanceKlass*>* ifs = ik->local_interfaces(); 57 for (int i = 0; i < ifs->length(); i++) { 58 add_one_vm_class(ifs->at(i)); 59 } 60 } 61 } 62 63 void ClassPrelinker::initialize() { 64 assert(_vm_classes == nullptr, "must be"); 65 _vm_classes = new (mtClass)ClassesTable(); 66 _processed_classes = new (mtClass)ClassesTable(); 67 for (auto id : EnumRange<vmClassID>{}) { 68 add_one_vm_class(vmClasses::klass_at(id)); 69 } 70 } 71 72 void ClassPrelinker::dispose() { 73 assert(_vm_classes != nullptr, "must be"); 74 delete _vm_classes; 75 delete _processed_classes; 76 _vm_classes = nullptr; 77 _processed_classes = nullptr; 78 } 79 80 // Returns true if we CAN PROVE that cp_index will always resolve to 81 // the same information at both dump time and run time. This is a 82 // necessary (but not sufficient) condition for pre-resolving cp_index 83 // during CDS archive assembly. 84 bool ClassPrelinker::is_resolution_deterministic(ConstantPool* cp, int cp_index) { 85 assert(!is_in_archivebuilder_buffer(cp), "sanity"); 86 87 if (cp->tag_at(cp_index).is_klass()) { 88 // We require cp_index to be already resolved. This is fine for now, are we 89 // currently archive only CP entries that are already resolved. 90 Klass* resolved_klass = cp->resolved_klass_at(cp_index); 91 return resolved_klass != nullptr && is_class_resolution_deterministic(cp->pool_holder(), resolved_klass); 92 } else if (cp->tag_at(cp_index).is_field() || 93 cp->tag_at(cp_index).is_method() || 94 cp->tag_at(cp_index).is_interface_method()) { 95 int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index); 96 if (!cp->tag_at(klass_cp_index).is_klass()) { 97 // Not yet resolved 98 return false; 99 } 100 Klass* k = cp->resolved_klass_at(klass_cp_index); 101 if (!is_class_resolution_deterministic(cp->pool_holder(), k)) { 102 return false; 103 } 104 105 if (!k->is_instance_klass()) { 106 // TODO: support non instance klasses as well. 107 return false; 108 } 109 110 // Here, We don't check if this entry can actually be resolved to a valid Field/Method. 111 // This method should be called by the ConstantPool to check Fields/Methods that 112 // have already been successfully resolved. 113 return true; 114 } else { 115 return false; 116 } 117 } 118 119 bool ClassPrelinker::is_class_resolution_deterministic(InstanceKlass* cp_holder, Klass* resolved_class) { 120 assert(!is_in_archivebuilder_buffer(cp_holder), "sanity"); 121 assert(!is_in_archivebuilder_buffer(resolved_class), "sanity"); 122 123 if (resolved_class->is_instance_klass()) { 124 InstanceKlass* ik = InstanceKlass::cast(resolved_class); 125 126 if (!ik->is_shared() && SystemDictionaryShared::is_excluded_class(ik)) { 127 return false; 128 } 129 130 if (cp_holder->is_subtype_of(ik)) { 131 // All super types of ik will be resolved in ik->class_loader() before 132 // ik is defined in this loader, so it's safe to archive the resolved klass reference. 133 return true; 134 } 135 136 if (is_vm_class(ik)) { 137 if (ik->class_loader() != cp_holder->class_loader()) { 138 // At runtime, cp_holder() may not be able to resolve to the same 139 // ik. For example, a different version of ik may be defined in 140 // cp->pool_holder()'s loader using MethodHandles.Lookup.defineClass(). 141 return false; 142 } else { 143 return true; 144 } 145 } 146 } else if (resolved_class->is_objArray_klass()) { 147 Klass* elem = ObjArrayKlass::cast(resolved_class)->bottom_klass(); 148 if (elem->is_instance_klass()) { 149 return is_class_resolution_deterministic(cp_holder, InstanceKlass::cast(elem)); 150 } else if (elem->is_typeArray_klass()) { 151 return true; 152 } 153 } else if (resolved_class->is_typeArray_klass()) { 154 return true; 155 } 156 157 return false; 158 } 159 160 void ClassPrelinker::dumptime_resolve_constants(InstanceKlass* ik, TRAPS) { 161 if (!ik->is_linked()) { 162 return; 163 } 164 bool first_time; 165 _processed_classes->put_if_absent(ik, &first_time); 166 if (!first_time) { 167 // We have already resolved the constants in class, so no need to do it again. 168 return; 169 } 170 171 constantPoolHandle cp(THREAD, ik->constants()); 172 for (int cp_index = 1; cp_index < cp->length(); cp_index++) { // Index 0 is unused 173 switch (cp->tag_at(cp_index).value()) { 174 case JVM_CONSTANT_String: 175 resolve_string(cp, cp_index, CHECK); // may throw OOM when interning strings. 176 break; 177 } 178 } 179 } 180 181 // This works only for the boot/platform/app loaders 182 Klass* ClassPrelinker::find_loaded_class(Thread* current, oop class_loader, Symbol* name) { 183 HandleMark hm(current); 184 Handle h_loader(current, class_loader); 185 Klass* k = SystemDictionary::find_instance_or_array_klass(current, name, 186 h_loader, 187 Handle()); 188 if (k != nullptr) { 189 return k; 190 } 191 if (h_loader() == SystemDictionary::java_system_loader()) { 192 return find_loaded_class(current, SystemDictionary::java_platform_loader(), name); 193 } else if (h_loader() == SystemDictionary::java_platform_loader()) { 194 return find_loaded_class(current, nullptr, name); 195 } else { 196 assert(h_loader() == nullptr, "This function only works for boot/platform/app loaders %p %p %p", 197 cast_from_oop<address>(h_loader()), 198 cast_from_oop<address>(SystemDictionary::java_system_loader()), 199 cast_from_oop<address>(SystemDictionary::java_platform_loader())); 200 } 201 202 return nullptr; 203 } 204 205 Klass* ClassPrelinker::find_loaded_class(Thread* current, ConstantPool* cp, int class_cp_index) { 206 Symbol* name = cp->klass_name_at(class_cp_index); 207 return find_loaded_class(current, cp->pool_holder()->class_loader(), name); 208 } 209 210 #if INCLUDE_CDS_JAVA_HEAP 211 void ClassPrelinker::resolve_string(constantPoolHandle cp, int cp_index, TRAPS) { 212 if (CDSConfig::is_dumping_heap()) { 213 int cache_index = cp->cp_to_object_index(cp_index); 214 ConstantPool::string_at_impl(cp, cp_index, cache_index, CHECK); 215 } 216 } 217 #endif 218 219 void ClassPrelinker::preresolve_class_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray<bool>* preresolve_list) { 220 if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) { 221 return; 222 } 223 224 JavaThread* THREAD = current; 225 constantPoolHandle cp(THREAD, ik->constants()); 226 for (int cp_index = 1; cp_index < cp->length(); cp_index++) { 227 if (cp->tag_at(cp_index).value() == JVM_CONSTANT_UnresolvedClass) { 228 if (preresolve_list != nullptr && preresolve_list->at(cp_index) == false) { 229 // This class was not resolved during trial run. Don't attempt to resolve it. Otherwise 230 // the compiler may generate less efficient code. 231 continue; 232 } 233 if (find_loaded_class(current, cp(), cp_index) == nullptr) { 234 // Do not resolve any class that has not been loaded yet 235 continue; 236 } 237 Klass* resolved_klass = cp->klass_at(cp_index, THREAD); 238 if (HAS_PENDING_EXCEPTION) { 239 CLEAR_PENDING_EXCEPTION; // just ignore 240 } else { 241 log_trace(cds, resolve)("Resolved class [%3d] %s -> %s", cp_index, ik->external_name(), 242 resolved_klass->external_name()); 243 } 244 } 245 } 246 } 247 248 void ClassPrelinker::preresolve_field_and_method_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray<bool>* preresolve_list) { 249 JavaThread* THREAD = current; 250 constantPoolHandle cp(THREAD, ik->constants()); 251 if (cp->cache() == nullptr) { 252 return; 253 } 254 for (int i = 0; i < ik->methods()->length(); i++) { 255 Method* m = ik->methods()->at(i); 256 BytecodeStream bcs(methodHandle(THREAD, m)); 257 while (!bcs.is_last_bytecode()) { 258 bcs.next(); 259 Bytecodes::Code raw_bc = bcs.raw_code(); 260 switch (raw_bc) { 261 case Bytecodes::_getfield: 262 case Bytecodes::_putfield: 263 maybe_resolve_fmi_ref(ik, m, raw_bc, bcs.get_index_u2(), preresolve_list, THREAD); 264 if (HAS_PENDING_EXCEPTION) { 265 CLEAR_PENDING_EXCEPTION; // just ignore 266 } 267 break; 268 case Bytecodes::_invokespecial: 269 case Bytecodes::_invokevirtual: 270 case Bytecodes::_invokeinterface: 271 maybe_resolve_fmi_ref(ik, m, raw_bc, bcs.get_index_u2(), preresolve_list, THREAD); 272 if (HAS_PENDING_EXCEPTION) { 273 CLEAR_PENDING_EXCEPTION; // just ignore 274 } 275 break; 276 default: 277 break; 278 } 279 } 280 } 281 } 282 283 void ClassPrelinker::maybe_resolve_fmi_ref(InstanceKlass* ik, Method* m, Bytecodes::Code bc, int raw_index, 284 GrowableArray<bool>* preresolve_list, TRAPS) { 285 methodHandle mh(THREAD, m); 286 constantPoolHandle cp(THREAD, ik->constants()); 287 HandleMark hm(THREAD); 288 int cp_index = cp->to_cp_index(raw_index, bc); 289 290 if (cp->is_resolved(raw_index, bc)) { 291 return; 292 } 293 294 if (preresolve_list != nullptr && preresolve_list->at(cp_index) == false) { 295 // This field wasn't resolved during the trial run. Don't attempt to resolve it. Otherwise 296 // the compiler may generate less efficient code. 297 return; 298 } 299 300 int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index); 301 if (find_loaded_class(THREAD, cp(), klass_cp_index) == nullptr) { 302 // Do not resolve any field/methods from a class that has not been loaded yet. 303 return; 304 } 305 306 Klass* resolved_klass = cp->klass_ref_at(raw_index, bc, CHECK); 307 308 switch (bc) { 309 case Bytecodes::_getfield: 310 case Bytecodes::_putfield: 311 InterpreterRuntime::resolve_get_put(bc, raw_index, mh, cp, false /*initialize_holder*/, CHECK); 312 break; 313 314 case Bytecodes::_invokevirtual: 315 case Bytecodes::_invokespecial: 316 case Bytecodes::_invokeinterface: 317 InterpreterRuntime::cds_resolve_invoke(bc, raw_index, cp, CHECK); 318 break; 319 320 default: 321 ShouldNotReachHere(); 322 } 323 324 if (log_is_enabled(Trace, cds, resolve)) { 325 ResourceMark rm(THREAD); 326 bool resolved = cp->is_resolved(raw_index, bc); 327 Symbol* name = cp->name_ref_at(raw_index, bc); 328 Symbol* signature = cp->signature_ref_at(raw_index, bc); 329 log_trace(cds, resolve)("%s %s [%3d] %s -> %s.%s:%s", 330 (resolved ? "Resolved" : "Failed to resolve"), 331 Bytecodes::name(bc), cp_index, ik->external_name(), 332 resolved_klass->external_name(), 333 name->as_C_string(), signature->as_C_string()); 334 } 335 } 336 337 #ifdef ASSERT 338 bool ClassPrelinker::is_in_archivebuilder_buffer(address p) { 339 if (!Thread::current()->is_VM_thread() || ArchiveBuilder::current() == nullptr) { 340 return false; 341 } else { 342 return ArchiveBuilder::current()->is_in_buffer_space(p); 343 } 344 } 345 #endif