1 /*
  2  * Copyright (c) 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/aotClassInitializer.hpp"
 27 #include "cds/archiveBuilder.hpp"
 28 #include "cds/cdsConfig.hpp"
 29 #include "cds/heapShared.hpp"
 30 #include "classfile/vmSymbols.hpp"
 31 #include "oops/instanceKlass.inline.hpp"
 32 #include "oops/symbol.hpp"
 33 #include "runtime/javaCalls.hpp"
 34 
 35 // Detector for class names we wish to handle specially.
 36 // It is either an exact string match or a string prefix match.
 37 class AOTClassInitializer::AllowedSpec {
 38   const char* _class_name;
 39   bool _is_prefix;
 40   int _len;
 41 public:
 42   AllowedSpec(const char* class_name, bool is_prefix = false)
 43     : _class_name(class_name), _is_prefix(is_prefix)
 44   {
 45     _len = (class_name == nullptr) ? 0 : (int)strlen(class_name);
 46   }
 47   const char* class_name() { return _class_name; }
 48 
 49   bool matches(Symbol* name, int len) {
 50     assert(_class_name != nullptr, "caller resp.");
 51     if (_is_prefix) {
 52       return len >= _len && name->starts_with(_class_name);
 53     } else {
 54       return len == _len && name->equals(_class_name);
 55     }
 56   }
 57 };
 58 
 59 
 60 // Tell if ik has a name that matches one of the given specs.
 61 bool AOTClassInitializer::is_allowed(AllowedSpec* specs, InstanceKlass* ik) {
 62   Symbol* name = ik->name();
 63   int len = name->utf8_length();
 64   for (AllowedSpec* s = specs; s->class_name() != nullptr; s++) {
 65     if (s->matches(name, len)) {
 66       // If a type is included in the tables inside can_archive_initialized_mirror(), we require that
 67       //   - all super classes must be included
 68       //   - all super interfaces that have <clinit> must be included.
 69       // This ensures that in the production run, we don't run the <clinit> of a supertype but skips
 70       // ik's <clinit>.
 71       if (ik->java_super() != nullptr) {
 72         DEBUG_ONLY(ResourceMark rm);
 73         assert(AOTClassInitializer::can_archive_initialized_mirror(ik->java_super()),
 74                "super class %s of %s must be aot-initialized", ik->java_super()->external_name(),
 75                ik->external_name());
 76       }
 77 
 78       Array<InstanceKlass*>* interfaces = ik->local_interfaces();
 79       int len = interfaces->length();
 80       for (int i = 0; i < len; i++) {
 81         InstanceKlass* intf = interfaces->at(i);
 82         if (intf->class_initializer() != nullptr) {
 83           assert(AOTClassInitializer::can_archive_initialized_mirror(intf),
 84                  "super interface %s (which has <clinit>) of %s must be aot-initialized", intf->external_name(),
 85                  ik->external_name());
 86         }
 87       }
 88 
 89       return true;
 90     }
 91   }
 92   return false;
 93 }
 94 
 95 
 96 bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) {
 97   assert(!ArchiveBuilder::current()->is_in_buffer_space(ik), "must be source klass");
 98   if (!CDSConfig::is_initing_classes_at_dump_time()) {
 99     return false;
100   }
101 
102   if (!ik->is_initialized()) {
103     return false;
104   }
105 
106   if (ik->is_hidden()) {
107     return HeapShared::is_archivable_hidden_klass(ik);
108   }
109 
110   if (ik->is_enum_subclass()) {
111     return true;
112   }
113 
114   // About "static field that may hold a different value" errors:
115   //
116   // Automatic selection for aot-inited classes
117   // ==========================================
118   //
119   // When CDSConfig::is_initing_classes_at_dump_time() is enabled,
120   // HeapShared::find_all_aot_initialized_classes() finds the classes of all
121   // heap objects that are reachable from HeapShared::_run_time_special_subgraph,
122   // and mark these classes as aot-inited. This preserves the initialized
123   // mirrors of these classes, and their <clinit> methods are NOT executed
124   // at runtime.
125   //
126   // For example, with -XX:+AOTInvokeDynamicLinking, _run_time_special_subgraph
127   // will contain some DirectMethodHandle objects. As a result, the DirectMethodHandle
128   // class is automatically marked as aot-inited.
129   //
130   // When a class is aot-inited, its static fields are already set up
131   // by executing the <clinit> method at AOT assembly time.  Later on
132   // in the production run, when the class would normally be
133   // initialized, the VM performs guarding and synchronization as if
134   // it were going to run the <clinit> again, but instead it simply
135   // observes that that class was aot-inited.  The VM assumes that, if
136   // it were to run <clinit> again, it would get a semantically
137   // equivalent set of final field values, so it just adopts the
138   // existing field values (from AOT assembly) and skips the call to
139   // <clinit>.  There may at that point be fixups performed by ad hoc
140   // code, if the VM recognizes a request in the library.
141   //
142   // It is true that this is not generally correct for all possible
143   // Java code.  A <clinit> method might have a side effect beyond
144   // initializing the static fields.  It might send an email somewhere
145   // noting the current time of day.  In that case, such an email
146   // would have been sent during the AOT assembly phase, and the email
147   // would NOT be sent again during production.  This is clearly NOT
148   // what a user would want, if this were a general purpose facility.
149   // But in fact it is only for certain well-behaved classes, which
150   // are known NOT to have such side effects.  We know this because
151   // the optimization (of skipping <clinit> for aot-init classes) is
152   // only applied to classes fully defined by the JDK.
153   //
154   // (A day may come when we figure out how to gracefully extend this
155   // optimization to untrusted third parties, but it is not this day.)
156   //
157   // Manual selection
158   // ================
159   //
160   // There are important cases where one aot-init class has a side
161   // effect on another aot-class, a side effect which is not captured
162   // in any static field value in either class.  The simplest example
163   // is class A forces the initialization of class B.  In that case,
164   // we need to aot-init either both classes or neither.  From looking
165   // at the JDK state after AOT assembly is done, it is hard to tell
166   // that A "touched" B and B might escape our notice.  Another common
167   // example is A copying a field value from B.  We don't know where A
168   // got the value, but it would be wrong to re-initialize B at
169   // startup, while keeping the snapshot of the old B value in A.  In
170   // general, if we aot-init A, we need to aot-init every class B that
171   // somehow contributed to A's initial state, and every class C that
172   // was somehow side-effected by A's initialization.  We say that the
173   // aot-init of A is "init-coupled" to those of B and C.
174   //
175   // So there are init-coupled classes that cannot be automatically discovered. For
176   // example, DirectMethodHandle::IMPL_NAMES points to MethodHandles::IMPL_NAMES,
177   // but the MethodHandles class is not automatically marked because there are
178   // no archived instances of the MethodHandles type.
179   //
180   // If we aot-initialize DirectMethodHandle, but allow MethodHandles to be
181   // initialized at runtime, MethodHandles::IMPL_NAMES will get a different
182   // value than DirectMethodHandle::IMPL_NAMES. This *may or may not* be a problem,
183   // but to ensure compatibility, we should try to preserve the identity equality
184   // of these two fields.
185   //
186   // To do that, we add MethodHandles to the indy_specs[] table below.
187   //
188   // Luckily we do not need to be all-knowing in order to choose which
189   // items to add to that table.  We have tools to help detect couplings.
190   //
191   // Automatic validation
192   // ====================
193   //
194   // CDSHeapVerifier is used to detect potential problems with identity equality.
195   //
196   // A class B is assumed to be init-coupled to some aot-init class if
197   // B has a field which points to a live object X in the AOT heap.
198   // The live object X was created by some other class A which somehow
199   // used B's reference to X, perhaps with the help of an intermediate
200   // class Z.  Or, B pulled the reference to X from some other class
201   // Y, and B obtained that reference from Y (or an intermediate Z).
202   // It is not certain how X got into the heap, nor whether B
203   // contributed it, but it is a good heuristic that B is init-coupled
204   // to X's class or some other aot-init class.  In any case, B should
205   // be made an aot-init class as well, unless a manual inspection
206   // shows that would be a problem.  If there is a problem, then the
207   // JDK code for B and/or X probably needs refactoring.  If there is
208   // no problem, we add B to the list.  Typically the same scan will
209   // find any other accomplices Y, Z, etc.  One failure would be a
210   // class Q whose only initialization action is to scribble a special
211   // value into B, from which the value X is derived and then makes
212   // its way into the heap.  In that case, the heuristic does not
213   // identify Q.  It is (currently) a human responsibility, of JDK
214   // engineers, not to write such dirty JDK code, or to repair it if
215   // it crops up.  Eventually we may have tools, or even a user mode
216   // with design rules and checks, that will vet our code base more
217   // automatically.
218   //
219   // To see how the tool detects the problem with MethodHandles::IMPL_NAMES:
220   //
221   // - Comment out all the lines in indy_specs[] except the {nullptr} line.
222   // - Rebuild the JDK
223   //
224   // Then run the following:
225   //    java -XX:AOTMode=record -XX:AOTConfiguration=jc.aotconfig com.sun.tools.javac.Main
226   //    java -XX:AOTMode=create -Xlog:cds -XX:AOTCache=jc.aot -XX:AOTConfiguration=jc.aotconfig
227   //
228   // You will see an error like this:
229   //
230   // Archive heap points to a static field that may hold a different value at runtime:
231   // Field: java/lang/invoke/MethodHandles::IMPL_NAMES
232   // Value: java.lang.invoke.MemberName$Factory
233   // {0x000000060e906ae8} - klass: 'java/lang/invoke/MemberName$Factory' - flags:
234   //
235   //  - ---- fields (total size 2 words):
236   // --- trace begin ---
237   // [ 0] {0x000000060e8deeb0} java.lang.Class (java.lang.invoke.DirectMethodHandle::IMPL_NAMES)
238   // [ 1] {0x000000060e906ae8} java.lang.invoke.MemberName$Factory
239   // --- trace end ---
240   //
241   // Trouble-shooting
242   // ================
243   //
244   // If you see a "static field that may hold a different value" error, it's probably
245   // because you've made some changes in the JDK core libraries (most likely
246   // java.lang.invoke).
247   //
248   //  - Did you add a new static field to a class that could be referenced by
249   //    cached object instances of MethodType, MethodHandle, etc? You may need
250   //    to add that class to indy_specs[].
251   //  - Did you modify the <clinit> of the classes in java.lang.invoke such that
252   //    a static field now points to an object that should not be cached (e.g.,
253   //    a native resource such as a file descriptior, or a Thread)?
254   //
255   // Note that these potential problems only occur when one class gets
256   // the aot-init treatment, AND another class is init-coupled to it,
257   // AND the coupling is not detected.  Currently there are a number
258   // classes that get the aot-init treatment, in java.lang.invoke
259   // because of invokedynamic.  They are few enough for now to be
260   // manually tracked.  There may be more in the future.
261 
262   // IS_PREFIX means that we match all class names that start with a
263   // prefix.  Otherwise, it is an exact match, of just one class name.
264   const bool IS_PREFIX = true;
265 
266   {
267     static AllowedSpec specs[] = {
268       // everybody's favorite super
269       {"java/lang/Object"},
270 
271       // above we selected all enums; we must include their super as well
272       {"java/lang/Enum"},
273      {nullptr}
274     };
275     if (is_allowed(specs, ik)) {
276       return true;
277     }
278   }
279 
280   if (CDSConfig::is_dumping_invokedynamic()) {
281     // This table was created with the help of CDSHeapVerifier.
282     // Also, some $Holder classes are needed. E.g., Invokers.<clinit> explicitly
283     // initializes Invokers$Holder. Since Invokers.<clinit> won't be executed
284     // at runtime, we need to make sure Invokers$Holder is also aot-inited.
285     //
286     // We hope we can reduce the size of this list over time, and move
287     // the responsibility for identifying such classes into the JDK
288     // code itself.  See tracking RFE JDK-8342481.
289     static AllowedSpec indy_specs[] = {
290       {"java/lang/constant/ConstantDescs"},
291       {"java/lang/constant/DynamicConstantDesc"},
292       {"java/lang/invoke/BoundMethodHandle"},
293       {"java/lang/invoke/BoundMethodHandle$Specializer"},
294       {"java/lang/invoke/BoundMethodHandle$Species_", IS_PREFIX},
295       {"java/lang/invoke/ClassSpecializer"},
296       {"java/lang/invoke/ClassSpecializer$", IS_PREFIX},
297       {"java/lang/invoke/DelegatingMethodHandle"},
298       {"java/lang/invoke/DelegatingMethodHandle$Holder"},     // UNSAFE.ensureClassInitialized()
299       {"java/lang/invoke/DirectMethodHandle"},
300       {"java/lang/invoke/DirectMethodHandle$Constructor"},
301       {"java/lang/invoke/DirectMethodHandle$Holder"},         // UNSAFE.ensureClassInitialized()
302       {"java/lang/invoke/Invokers"},
303       {"java/lang/invoke/Invokers$Holder"},                   // UNSAFE.ensureClassInitialized()
304       {"java/lang/invoke/LambdaForm"},
305       {"java/lang/invoke/LambdaForm$Holder"},                 // UNSAFE.ensureClassInitialized()
306       {"java/lang/invoke/LambdaForm$NamedFunction"},
307       {"java/lang/invoke/MethodHandle"},
308       {"java/lang/invoke/MethodHandles"},
309       {"java/lang/invoke/SimpleMethodHandle"},
310       {"java/util/Collections"},
311       {"java/util/stream/Collectors"},
312       {"jdk/internal/constant/ConstantUtils"},
313       {"jdk/internal/constant/PrimitiveClassDescImpl"},
314       {"jdk/internal/constant/ReferenceClassDescImpl"},
315 
316     // Can't include this, as it will pull in MethodHandleStatics which has many environment
317     // dependencies (on system properties, etc).
318     // MethodHandleStatics is an example of a class that must NOT get the aot-init treatment,
319     // because of its strong reliance on (a) final fields which are (b) environmentally determined.
320     //{"java/lang/invoke/InvokerBytecodeGenerator"},
321 
322       {nullptr}
323     };
324     if (is_allowed(indy_specs, ik)) {
325       return true;
326     }
327   }
328 
329   return false;
330 }
331 
332 // TODO: currently we have a hard-coded list. We should turn this into
333 // an annotation: @jdk.internal.vm.annotation.RuntimeSetupRequired
334 // See JDK-8342481.
335 bool AOTClassInitializer::is_runtime_setup_required(InstanceKlass* ik) {
336   return ik == vmClasses::Class_klass() ||
337          ik == vmClasses::internal_Unsafe_klass() ||
338          ik == vmClasses::ConcurrentHashMap_klass();
339 }
340 
341 void AOTClassInitializer::call_runtime_setup(JavaThread* current, InstanceKlass* ik) {
342   assert(ik->has_aot_initialized_mirror(), "sanity");
343   if (ik->is_runtime_setup_required()) {
344     if (log_is_enabled(Info, cds, init)) {
345       ResourceMark rm;
346       log_info(cds, init)("Calling %s::runtimeSetup()", ik->external_name());
347     }
348     JavaValue result(T_VOID);
349     JavaCalls::call_static(&result, ik,
350                            vmSymbols::runtimeSetup(),
351                            vmSymbols::void_method_signature(), current);
352     if (current->has_pending_exception()) {
353       // We cannot continue, as we might have cached instances of ik in the heap, but propagating the
354       // exception would cause ik to be in an error state.
355       AOTLinkedClassBulkLoader::exit_on_exception(current);
356     }
357   }
358 }
359