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