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 #ifndef SHARE_CDS_CLASSPRELOADER_HPP
 26 #define SHARE_CDS_CLASSPRELOADER_HPP
 27 
 28 #include "interpreter/bytecodes.hpp"
 29 #include "oops/oopsHierarchy.hpp"
 30 #include "memory/allStatic.hpp"
 31 #include "memory/allocation.hpp"
 32 #include "runtime/handles.hpp"
 33 #include "utilities/exceptions.hpp"
 34 #include "utilities/macros.hpp"
 35 #include "utilities/resourceHash.hpp"
 36 
 37 class InstanceKlass;
 38 class Klass;
 39 class SerializeClosure;
 40 template <typename T> class Array;
 41 
 42 class ClassPreloader :  AllStatic {
 43   class PreloadedKlassRecorder;
 44   using ClassesTable = ResourceHashtable<InstanceKlass*, bool, 15889, AnyObj::C_HEAP, mtClassShared>;
 45 
 46   // Classes loaded inside vmClasses::resolve_all()
 47   static ClassesTable* _vm_classes;
 48 
 49   // Classes that will be automatically loaded into system dictionary at
 50   // VM start-up (this is a superset of _vm_classes)
 51   static ClassesTable* _preloaded_classes;
 52   static ClassesTable* _platform_initiated_classes; // classes initiated but not loaded by platform loader
 53   static ClassesTable* _app_initiated_classes;      // classes initiated but not loaded by app loader
 54 
 55   static bool _record_javabase_only;
 56   static bool _preload_javabase_only;
 57   struct PreloadedKlasses {
 58     Array<InstanceKlass*>* _boot;  // only java.base classes
 59     Array<InstanceKlass*>* _boot2; // boot classes in other modules
 60     Array<InstanceKlass*>* _platform;
 61     Array<InstanceKlass*>* _platform_initiated;
 62     Array<InstanceKlass*>* _app;
 63     Array<InstanceKlass*>* _app_initiated;
 64     PreloadedKlasses() : _boot(nullptr), _boot2(nullptr), _platform(nullptr), _app(nullptr) {}
 65   };
 66 
 67   static PreloadedKlasses _static_preloaded_classes;
 68   static PreloadedKlasses _dynamic_preloaded_classes;
 69   static Array<InstanceKlass*>* _unregistered_classes_from_preimage;
 70 
 71   static void add_one_vm_class(InstanceKlass* ik);
 72   static void add_preloaded_classes(Array<InstanceKlass*>* klasses);
 73   static void add_unrecorded_initiated_classes(ClassesTable* table, Array<InstanceKlass*>* klasses);
 74   static void add_extra_initiated_classes(PreloadedKlasses* table);
 75   static void add_initiated_classes_for_loader(ClassLoaderData* loader_data, const char* loader_name, ClassesTable* table);
 76   static void add_initiated_class(ClassesTable* initiated_classes, const char* loader_name, InstanceKlass* target);
 77   static Array<InstanceKlass*>* record_preloaded_classes(int loader_type);
 78   static Array<InstanceKlass*>* record_initiated_classes(ClassesTable* table);
 79   static void runtime_preload(PreloadedKlasses* table, Handle loader, TRAPS);
 80   static void runtime_preload_class_quick(InstanceKlass* ik, ClassLoaderData* loader_data, Handle domain, TRAPS);
 81   static void preload_archived_hidden_class(Handle class_loader, InstanceKlass* ik,
 82                                             const char* loader_name, TRAPS);
 83   static void jvmti_agent_error(InstanceKlass* expected, InstanceKlass* actual, const char* type);
 84 
 85   static bool is_in_javabase(InstanceKlass* ik);
 86   class RecordInitiatedClassesClosure;
 87 
 88   static void replay_training_at_init(Array<InstanceKlass*>* preloaded_classes, TRAPS) NOT_CDS_RETURN;
 89 
 90 public:
 91   static void initialize();
 92   static void dispose();
 93 
 94   static void record_preloaded_classes(bool is_static_archive);
 95   static void record_initiated_classes(bool is_static_archive);
 96   static void record_unregistered_classes();
 97   static void serialize(SerializeClosure* soc, bool is_static_archive);
 98 
 99   // Is this class resolved as part of vmClasses::resolve_all()?
100   static bool is_vm_class(InstanceKlass* ik);
101 
102   // When CDS is enabled, is ik guatanteed to be loaded at deployment time (and
103   // cannot be replaced by JVMTI)?
104   // This is a necessary (not but sufficient) condition for keeping a direct pointer
105   // to ik in precomputed data (such as ConstantPool entries in archived classes,
106   // or in AOT-compiled code).
107   static bool is_preloaded_class(InstanceKlass* ik);
108 
109   static void add_preloaded_class(InstanceKlass* ik);
110   static void add_initiated_class(InstanceKlass* ik, InstanceKlass* target);
111 
112   static void runtime_preload(JavaThread* current, Handle loader) NOT_CDS_RETURN;
113   static void init_javabase_preloaded_classes(TRAPS) NOT_CDS_RETURN;
114   static void replay_training_at_init_for_preloaded_classes(TRAPS) NOT_CDS_RETURN;
115   static bool class_preloading_finished();
116 
117   static int  num_platform_initiated_classes();
118   static int  num_app_initiated_classes();
119   static void print_counters() NOT_CDS_RETURN;
120 };
121 
122 #endif // SHARE_CDS_CLASSPRELOADER_HPP