File: | jdk/src/hotspot/share/cds/classListWriter.cpp |
Warning: | line 168, column 34 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright (c) 2021, 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/classListWriter.hpp" | |||
27 | #include "classfile/classFileStream.hpp" | |||
28 | #include "classfile/classLoader.hpp" | |||
29 | #include "classfile/classLoaderData.hpp" | |||
30 | #include "classfile/moduleEntry.hpp" | |||
31 | #include "classfile/systemDictionaryShared.hpp" | |||
32 | #include "memory/resourceArea.hpp" | |||
33 | #include "oops/instanceKlass.hpp" | |||
34 | #include "runtime/mutexLocker.hpp" | |||
35 | ||||
36 | fileStream* ClassListWriter::_classlist_file = NULL__null; | |||
37 | ||||
38 | void ClassListWriter::init() { | |||
39 | // For -XX:DumpLoadedClassList=<file> option | |||
40 | if (DumpLoadedClassList != NULL__null) { | |||
41 | const char* list_name = make_log_name(DumpLoadedClassList, NULL__null); | |||
42 | _classlist_file = new(ResourceObj::C_HEAP, mtInternal) | |||
43 | fileStream(list_name); | |||
44 | _classlist_file->print_cr("# NOTE: Do not modify this file."); | |||
45 | _classlist_file->print_cr("#"); | |||
46 | _classlist_file->print_cr("# This file is generated via the -XX:DumpLoadedClassList=<class_list_file> option"); | |||
47 | _classlist_file->print_cr("# and is used at CDS archive dump time (see -Xshare:dump)."); | |||
48 | _classlist_file->print_cr("#"); | |||
49 | FREE_C_HEAP_ARRAY(char, list_name)FreeHeap((char*)(list_name)); | |||
50 | } | |||
51 | } | |||
52 | ||||
53 | void ClassListWriter::write(const InstanceKlass* k, const ClassFileStream* cfs) { | |||
54 | assert(is_enabled(), "must be")do { if (!(is_enabled())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/cds/classListWriter.cpp" , 54, "assert(" "is_enabled()" ") failed", "must be"); ::breakpoint (); } } while (0); | |||
| ||||
55 | ||||
56 | if (!ClassLoader::has_jrt_entry()) { | |||
57 | warning("DumpLoadedClassList and CDS are not supported in exploded build"); | |||
58 | DumpLoadedClassList = NULL__null; | |||
59 | return; | |||
60 | } | |||
61 | ||||
62 | // filter out java/lang/invoke/BoundMethodHandle$Species.... | |||
63 | if (cfs != NULL__null && strcmp(cfs->source(), "_ClassSpecializer_generateConcreteSpeciesCode") == 0) { | |||
64 | return; | |||
65 | } | |||
66 | ||||
67 | ClassListWriter w; | |||
68 | write_to_stream(k, w.stream(), cfs); | |||
69 | } | |||
70 | ||||
71 | class ClassListWriter::IDTable : public ResourceHashtable< | |||
72 | const InstanceKlass*, int, | |||
73 | 15889, // prime number | |||
74 | ResourceObj::C_HEAP> {}; | |||
75 | ||||
76 | ClassListWriter::IDTable* ClassListWriter::_id_table = NULL__null; | |||
77 | int ClassListWriter::_total_ids = 0; | |||
78 | ||||
79 | int ClassListWriter::get_id(const InstanceKlass* k) { | |||
80 | assert_locked(); | |||
81 | if (_id_table == NULL__null) { | |||
82 | _id_table = new (ResourceObj::C_HEAP, mtClass)IDTable(); | |||
83 | } | |||
84 | bool created; | |||
85 | int* v = _id_table->put_if_absent(k, &created); | |||
86 | if (created) { | |||
87 | *v = _total_ids++; | |||
88 | } | |||
89 | return *v; | |||
90 | } | |||
91 | ||||
92 | bool ClassListWriter::has_id(const InstanceKlass* k) { | |||
93 | assert_locked(); | |||
94 | if (_id_table != NULL__null) { | |||
95 | return _id_table->get(k) != NULL__null; | |||
96 | } else { | |||
97 | return false; | |||
98 | } | |||
99 | } | |||
100 | ||||
101 | void ClassListWriter::handle_class_unloading(const InstanceKlass* klass) { | |||
102 | assert_locked(); | |||
103 | if (_id_table != NULL__null) { | |||
104 | _id_table->remove(klass); | |||
105 | } | |||
106 | } | |||
107 | ||||
108 | void ClassListWriter::write_to_stream(const InstanceKlass* k, outputStream* stream, const ClassFileStream* cfs) { | |||
109 | assert_locked(); | |||
110 | ClassLoaderData* loader_data = k->class_loader_data(); | |||
111 | ||||
112 | if (!SystemDictionaryShared::is_builtin_loader(loader_data)) { | |||
113 | if (cfs == NULL__null || strncmp(cfs->source(), "file:", 5) != 0) { | |||
114 | return; | |||
115 | } | |||
116 | if (!SystemDictionaryShared::add_unregistered_class(Thread::current(), (InstanceKlass*)k)) { | |||
117 | return; | |||
118 | } | |||
119 | } | |||
120 | ||||
121 | ||||
122 | { | |||
123 | InstanceKlass* super = k->java_super(); | |||
124 | if (super != NULL__null && !has_id(super)) { | |||
125 | return; | |||
126 | } | |||
127 | ||||
128 | Array<InstanceKlass*>* interfaces = k->local_interfaces(); | |||
129 | int len = interfaces->length(); | |||
130 | for (int i = 0; i < len; i++) { | |||
131 | InstanceKlass* intf = interfaces->at(i); | |||
132 | if (!has_id(intf)) { | |||
133 | return; | |||
134 | } | |||
135 | } | |||
136 | } | |||
137 | ||||
138 | if (k->is_hidden()) { | |||
139 | return; | |||
140 | } | |||
141 | ||||
142 | if (k->module()->is_patched()) { | |||
143 | return; | |||
144 | } | |||
145 | ||||
146 | ResourceMark rm; | |||
147 | stream->print("%s id: %d", k->name()->as_C_string(), get_id(k)); | |||
148 | if (!SystemDictionaryShared::is_builtin_loader(loader_data)) { | |||
149 | InstanceKlass* super = k->java_super(); | |||
150 | assert(super != NULL, "must be")do { if (!(super != __null)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/cds/classListWriter.cpp" , 150, "assert(" "super != __null" ") failed", "must be"); :: breakpoint(); } } while (0); | |||
151 | stream->print(" super: %d", get_id(super)); | |||
152 | ||||
153 | Array<InstanceKlass*>* interfaces = k->local_interfaces(); | |||
154 | int len = interfaces->length(); | |||
155 | if (len > 0) { | |||
156 | stream->print(" interfaces:"); | |||
157 | for (int i = 0; i < len; i++) { | |||
158 | InstanceKlass* intf = interfaces->at(i); | |||
159 | stream->print(" %d", get_id(intf)); | |||
160 | } | |||
161 | } | |||
162 | ||||
163 | #ifdef _WINDOWS | |||
164 | // "file:/C:/dir/foo.jar" -> "C:/dir/foo.jar" | |||
165 | stream->print(" source: %s", cfs->source() + 6); | |||
166 | #else | |||
167 | // "file:/dir/foo.jar" -> "/dir/foo.jar" | |||
168 | stream->print(" source: %s", cfs->source() + 5); | |||
| ||||
169 | #endif | |||
170 | } | |||
171 | ||||
172 | stream->cr(); | |||
173 | stream->flush(); | |||
174 | } | |||
175 | ||||
176 | void ClassListWriter::delete_classlist() { | |||
177 | if (_classlist_file != NULL__null) { | |||
178 | delete _classlist_file; | |||
179 | } | |||
180 | } |
1 | /* |
2 | * Copyright (c) 1997, 2021, 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_CLASSFILE_CLASSLOADER_HPP |
26 | #define SHARE_CLASSFILE_CLASSLOADER_HPP |
27 | |
28 | #include "jimage.hpp" |
29 | #include "runtime/handles.hpp" |
30 | #include "runtime/perfDataTypes.hpp" |
31 | #include "utilities/exceptions.hpp" |
32 | #include "utilities/macros.hpp" |
33 | |
34 | // The VM class loader. |
35 | #include <sys/stat.h> |
36 | |
37 | // Name of boot "modules" image |
38 | #define MODULES_IMAGE_NAME"modules" "modules" |
39 | |
40 | // Class path entry (directory or zip file) |
41 | |
42 | class JImageFile; |
43 | class ClassFileStream; |
44 | class PackageEntry; |
45 | template <typename T> class GrowableArray; |
46 | |
47 | class ClassPathEntry : public CHeapObj<mtClass> { |
48 | private: |
49 | ClassPathEntry* volatile _next; |
50 | protected: |
51 | const char* copy_path(const char*path); |
52 | public: |
53 | ClassPathEntry* next() const; |
54 | virtual ~ClassPathEntry() {} |
55 | void set_next(ClassPathEntry* next); |
56 | |
57 | virtual bool is_modules_image() const { return false; } |
58 | virtual bool is_jar_file() const { return false; } |
59 | // Is this entry created from the "Class-path" attribute from a JAR Manifest? |
60 | virtual bool from_class_path_attr() const { return false; } |
61 | virtual const char* name() const = 0; |
62 | virtual JImageFile* jimage() const { return NULL__null; } |
63 | virtual void close_jimage() {} |
64 | // Constructor |
65 | ClassPathEntry() : _next(NULL__null) {} |
66 | // Attempt to locate file_name through this class path entry. |
67 | // Returns a class file parsing stream if successfull. |
68 | virtual ClassFileStream* open_stream(JavaThread* current, const char* name) = 0; |
69 | // Open the stream for a specific class loader |
70 | virtual ClassFileStream* open_stream_for_loader(JavaThread* current, const char* name, ClassLoaderData* loader_data) { |
71 | return open_stream(current, name); |
72 | } |
73 | }; |
74 | |
75 | class ClassPathDirEntry: public ClassPathEntry { |
76 | private: |
77 | const char* _dir; // Name of directory |
78 | public: |
79 | const char* name() const { return _dir; } |
80 | ClassPathDirEntry(const char* dir) { |
81 | _dir = copy_path(dir); |
82 | } |
83 | virtual ~ClassPathDirEntry() {} |
84 | ClassFileStream* open_stream(JavaThread* current, const char* name); |
85 | }; |
86 | |
87 | // Type definitions for zip file and zip file entry |
88 | typedef void* jzfile; |
89 | typedef struct { |
90 | char *name; /* entry name */ |
91 | jlong time; /* modification time */ |
92 | jlong size; /* size of uncompressed data */ |
93 | jlong csize; /* size of compressed data (zero if uncompressed) */ |
94 | jint crc; /* crc of uncompressed data */ |
95 | char *comment; /* optional zip file comment */ |
96 | jbyte *extra; /* optional extra data */ |
97 | jlong pos; /* position of LOC header (if negative) or data */ |
98 | } jzentry; |
99 | |
100 | class ClassPathZipEntry: public ClassPathEntry { |
101 | private: |
102 | jzfile* _zip; // The zip archive |
103 | const char* _zip_name; // Name of zip archive |
104 | bool _from_class_path_attr; // From the "Class-path" attribute of a jar file |
105 | public: |
106 | bool is_jar_file() const { return true; } |
107 | bool from_class_path_attr() const { return _from_class_path_attr; } |
108 | const char* name() const { return _zip_name; } |
109 | ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append, bool from_class_path_attr); |
110 | virtual ~ClassPathZipEntry(); |
111 | u1* open_entry(JavaThread* current, const char* name, jint* filesize, bool nul_terminate); |
112 | ClassFileStream* open_stream(JavaThread* current, const char* name); |
113 | void contents_do(void f(const char* name, void* context), void* context); |
114 | }; |
115 | |
116 | |
117 | // For java image files |
118 | class ClassPathImageEntry: public ClassPathEntry { |
119 | private: |
120 | const char* _name; |
121 | DEBUG_ONLY(static ClassPathImageEntry* _singleton;)static ClassPathImageEntry* _singleton; |
122 | public: |
123 | bool is_modules_image() const; |
124 | const char* name() const { return _name == NULL__null ? "" : _name; } |
125 | JImageFile* jimage() const; |
126 | JImageFile* jimage_non_null() const; |
127 | void close_jimage(); |
128 | ClassPathImageEntry(JImageFile* jimage, const char* name); |
129 | virtual ~ClassPathImageEntry() { ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here( "/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoader.hpp" , 129); ::breakpoint(); } while (0); } |
130 | ClassFileStream* open_stream(JavaThread* current, const char* name); |
131 | ClassFileStream* open_stream_for_loader(JavaThread* current, const char* name, ClassLoaderData* loader_data); |
132 | }; |
133 | |
134 | // ModuleClassPathList contains a linked list of ClassPathEntry's |
135 | // that have been specified for a specific module. Currently, |
136 | // the only way to specify a module/path pair is via the --patch-module |
137 | // command line option. |
138 | class ModuleClassPathList : public CHeapObj<mtClass> { |
139 | private: |
140 | Symbol* _module_name; |
141 | // First and last entries of class path entries for a specific module |
142 | ClassPathEntry* _module_first_entry; |
143 | ClassPathEntry* _module_last_entry; |
144 | public: |
145 | Symbol* module_name() const { return _module_name; } |
146 | ClassPathEntry* module_first_entry() const { return _module_first_entry; } |
147 | ModuleClassPathList(Symbol* module_name); |
148 | ~ModuleClassPathList(); |
149 | void add_to_list(ClassPathEntry* new_entry); |
150 | }; |
151 | |
152 | class ClassLoader: AllStatic { |
153 | public: |
154 | enum ClassLoaderType { |
155 | BOOT_LOADER = 1, /* boot loader */ |
156 | PLATFORM_LOADER = 2, /* PlatformClassLoader */ |
157 | APP_LOADER = 3 /* AppClassLoader */ |
158 | }; |
159 | protected: |
160 | |
161 | // Performance counters |
162 | static PerfCounter* _perf_accumulated_time; |
163 | static PerfCounter* _perf_classes_inited; |
164 | static PerfCounter* _perf_class_init_time; |
165 | static PerfCounter* _perf_class_init_selftime; |
166 | static PerfCounter* _perf_classes_verified; |
167 | static PerfCounter* _perf_class_verify_time; |
168 | static PerfCounter* _perf_class_verify_selftime; |
169 | static PerfCounter* _perf_classes_linked; |
170 | static PerfCounter* _perf_class_link_time; |
171 | static PerfCounter* _perf_class_link_selftime; |
172 | static PerfCounter* _perf_sys_class_lookup_time; |
173 | static PerfCounter* _perf_shared_classload_time; |
174 | static PerfCounter* _perf_sys_classload_time; |
175 | static PerfCounter* _perf_app_classload_time; |
176 | static PerfCounter* _perf_app_classload_selftime; |
177 | static PerfCounter* _perf_app_classload_count; |
178 | static PerfCounter* _perf_define_appclasses; |
179 | static PerfCounter* _perf_define_appclass_time; |
180 | static PerfCounter* _perf_define_appclass_selftime; |
181 | static PerfCounter* _perf_app_classfile_bytes_read; |
182 | static PerfCounter* _perf_sys_classfile_bytes_read; |
183 | |
184 | static PerfCounter* _unsafe_defineClassCallCounter; |
185 | |
186 | // The boot class path consists of 3 ordered pieces: |
187 | // 1. the module/path pairs specified to --patch-module |
188 | // --patch-module=<module>=<file>(<pathsep><file>)* |
189 | // 2. the base piece |
190 | // [jimage | build with exploded modules] |
191 | // 3. boot loader append path |
192 | // [-Xbootclasspath/a]; [jvmti appended entries] |
193 | // |
194 | // The boot loader must obey this order when attempting |
195 | // to load a class. |
196 | |
197 | // 1. Contains the module/path pairs specified to --patch-module |
198 | static GrowableArray<ModuleClassPathList*>* _patch_mod_entries; |
199 | |
200 | // 2. the base piece |
201 | // Contains the ClassPathEntry of the modular java runtime image. |
202 | // If no java runtime image is present, this indicates a |
203 | // build with exploded modules is being used instead. |
204 | static ClassPathEntry* _jrt_entry; |
205 | static GrowableArray<ModuleClassPathList*>* _exploded_entries; |
206 | enum { EXPLODED_ENTRY_SIZE = 80 }; // Initial number of exploded modules |
207 | |
208 | // 3. the boot loader's append path |
209 | // [-Xbootclasspath/a]; [jvmti appended entries] |
210 | // Note: boot loader append path does not support named modules. |
211 | static ClassPathEntry* volatile _first_append_entry_list; |
212 | static ClassPathEntry* first_append_entry() { |
213 | return Atomic::load_acquire(&_first_append_entry_list); |
214 | } |
215 | |
216 | // Last entry in linked list of appended ClassPathEntry instances |
217 | static ClassPathEntry* volatile _last_append_entry; |
218 | |
219 | // Info used by CDS |
220 | CDS_ONLY(static ClassPathEntry* _app_classpath_entries;)static ClassPathEntry* _app_classpath_entries; |
221 | CDS_ONLY(static ClassPathEntry* _last_app_classpath_entry;)static ClassPathEntry* _last_app_classpath_entry; |
222 | CDS_ONLY(static ClassPathEntry* _module_path_entries;)static ClassPathEntry* _module_path_entries; |
223 | CDS_ONLY(static ClassPathEntry* _last_module_path_entry;)static ClassPathEntry* _last_module_path_entry; |
224 | CDS_ONLY(static void setup_app_search_path(JavaThread* current, const char* class_path);)static void setup_app_search_path(JavaThread* current, const char * class_path); |
225 | CDS_ONLY(static void setup_module_search_path(JavaThread* current, const char* path);)static void setup_module_search_path(JavaThread* current, const char* path); |
226 | static void add_to_app_classpath_entries(JavaThread* current, |
227 | const char* path, |
228 | ClassPathEntry* entry, |
229 | bool check_for_duplicates); |
230 | CDS_ONLY(static void add_to_module_path_entries(const char* path,static void add_to_module_path_entries(const char* path, ClassPathEntry * entry); |
231 | ClassPathEntry* entry);)static void add_to_module_path_entries(const char* path, ClassPathEntry * entry); |
232 | public: |
233 | CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;})static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries ;} |
234 | CDS_ONLY(static ClassPathEntry* module_path_entries() {return _module_path_entries;})static ClassPathEntry* module_path_entries() {return _module_path_entries ;} |
235 | |
236 | static bool has_bootclasspath_append() { return first_append_entry() != NULL__null; } |
237 | |
238 | protected: |
239 | // Initialization: |
240 | // - setup the boot loader's system class path |
241 | // - setup the boot loader's patch mod entries, if present |
242 | // - create the ModuleEntry for java.base |
243 | static void setup_bootstrap_search_path(JavaThread* current); |
244 | static void setup_bootstrap_search_path_impl(JavaThread* current, const char *class_path); |
245 | static void setup_patch_mod_entries(); |
246 | static void create_javabase(); |
247 | |
248 | static void* dll_lookup(void* lib, const char* name, const char* path); |
249 | static void load_java_library(); |
250 | static void load_zip_library(); |
251 | static void load_jimage_library(); |
252 | |
253 | private: |
254 | static int _libzip_loaded; // used to sync loading zip. |
255 | static void release_load_zip_library(); |
256 | static inline void load_zip_library_if_needed(); |
257 | |
258 | public: |
259 | static jzfile* open_zip_file(const char* canonical_path, char** error_msg, JavaThread* thread); |
260 | static ClassPathEntry* create_class_path_entry(JavaThread* current, |
261 | const char *path, const struct stat* st, |
262 | bool is_boot_append, |
263 | bool from_class_path_attr); |
264 | |
265 | // Canonicalizes path names, so strcmp will work properly. This is mainly |
266 | // to avoid confusing the zip library |
267 | static char* get_canonical_path(const char* orig, Thread* thread); |
268 | static const char* file_name_for_class_name(const char* class_name, |
269 | int class_name_len); |
270 | static PackageEntry* get_package_entry(Symbol* pkg_name, ClassLoaderData* loader_data); |
271 | static int crc32(int crc, const char* buf, int len); |
272 | static bool update_class_path_entry_list(JavaThread* current, |
273 | const char *path, |
274 | bool check_for_duplicates, |
275 | bool is_boot_append, |
276 | bool from_class_path_attr); |
277 | static void print_bootclasspath(); |
278 | |
279 | // Timing |
280 | static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; } |
281 | static PerfCounter* perf_classes_inited() { return _perf_classes_inited; } |
282 | static PerfCounter* perf_class_init_time() { return _perf_class_init_time; } |
283 | static PerfCounter* perf_class_init_selftime() { return _perf_class_init_selftime; } |
284 | static PerfCounter* perf_classes_verified() { return _perf_classes_verified; } |
285 | static PerfCounter* perf_class_verify_time() { return _perf_class_verify_time; } |
286 | static PerfCounter* perf_class_verify_selftime() { return _perf_class_verify_selftime; } |
287 | static PerfCounter* perf_classes_linked() { return _perf_classes_linked; } |
288 | static PerfCounter* perf_class_link_time() { return _perf_class_link_time; } |
289 | static PerfCounter* perf_class_link_selftime() { return _perf_class_link_selftime; } |
290 | static PerfCounter* perf_sys_class_lookup_time() { return _perf_sys_class_lookup_time; } |
291 | static PerfCounter* perf_shared_classload_time() { return _perf_shared_classload_time; } |
292 | static PerfCounter* perf_sys_classload_time() { return _perf_sys_classload_time; } |
293 | static PerfCounter* perf_app_classload_time() { return _perf_app_classload_time; } |
294 | static PerfCounter* perf_app_classload_selftime() { return _perf_app_classload_selftime; } |
295 | static PerfCounter* perf_app_classload_count() { return _perf_app_classload_count; } |
296 | static PerfCounter* perf_define_appclasses() { return _perf_define_appclasses; } |
297 | static PerfCounter* perf_define_appclass_time() { return _perf_define_appclass_time; } |
298 | static PerfCounter* perf_define_appclass_selftime() { return _perf_define_appclass_selftime; } |
299 | static PerfCounter* perf_app_classfile_bytes_read() { return _perf_app_classfile_bytes_read; } |
300 | static PerfCounter* perf_sys_classfile_bytes_read() { return _perf_sys_classfile_bytes_read; } |
301 | |
302 | // Record how many calls to Unsafe_DefineClass |
303 | static PerfCounter* unsafe_defineClassCallCounter() { |
304 | return _unsafe_defineClassCallCounter; |
305 | } |
306 | |
307 | // Modular java runtime image is present vs. a build with exploded modules |
308 | static bool has_jrt_entry() { return (_jrt_entry != NULL__null); } |
309 | static ClassPathEntry* get_jrt_entry() { return _jrt_entry; } |
310 | static void close_jrt_image(); |
311 | |
312 | // Add a module's exploded directory to the boot loader's exploded module build list |
313 | static void add_to_exploded_build_list(JavaThread* current, Symbol* module_name); |
314 | |
315 | // Attempt load of individual class from either the patched or exploded modules build lists |
316 | static ClassFileStream* search_module_entries(JavaThread* current, |
317 | const GrowableArray<ModuleClassPathList*>* const module_list, |
318 | const char* const class_name, |
319 | const char* const file_name); |
320 | |
321 | // Load individual .class file |
322 | static InstanceKlass* load_class(Symbol* class_name, bool search_append_only, TRAPSJavaThread* __the_thread__); |
323 | |
324 | // If the specified package has been loaded by the system, then returns |
325 | // the name of the directory or ZIP file that the package was loaded from. |
326 | // Returns null if the package was not loaded. |
327 | // Note: The specified name can either be the name of a class or package. |
328 | // If a package name is specified, then it must be "/"-separator and also |
329 | // end with a trailing "/". |
330 | static oop get_system_package(const char* name, TRAPSJavaThread* __the_thread__); |
331 | |
332 | // Returns an array of Java strings representing all of the currently |
333 | // loaded system packages. |
334 | // Note: The package names returned are "/"-separated and end with a |
335 | // trailing "/". |
336 | static objArrayOop get_system_packages(TRAPSJavaThread* __the_thread__); |
337 | |
338 | // Initialization |
339 | static void initialize(TRAPSJavaThread* __the_thread__); |
340 | static void classLoader_init2(JavaThread* current); |
341 | CDS_ONLY(static void initialize_shared_path(JavaThread* current);)static void initialize_shared_path(JavaThread* current); |
342 | CDS_ONLY(static void initialize_module_path(TRAPS);)static void initialize_module_path(JavaThread* __the_thread__ ); |
343 | |
344 | static int compute_Object_vtable(); |
345 | |
346 | static ClassPathEntry* classpath_entry(int n); |
347 | |
348 | static bool is_in_patch_mod_entries(Symbol* module_name); |
349 | |
350 | #if INCLUDE_CDS1 |
351 | // Sharing dump and restore |
352 | |
353 | // Helper function used by CDS code to get the number of boot classpath |
354 | // entries during shared classpath setup time. |
355 | static int num_boot_classpath_entries(); |
356 | |
357 | static ClassPathEntry* get_next_boot_classpath_entry(ClassPathEntry* e); |
358 | |
359 | // Helper function used by CDS code to get the number of app classpath |
360 | // entries during shared classpath setup time. |
361 | static int num_app_classpath_entries(); |
362 | |
363 | // Helper function used by CDS code to get the number of module path |
364 | // entries during shared classpath setup time. |
365 | static int num_module_path_entries(); |
366 | static void exit_with_path_failure(const char* error, const char* message); |
367 | static char* skip_uri_protocol(char* source); |
368 | static void record_result(JavaThread* current, InstanceKlass* ik, |
369 | const ClassFileStream* stream, bool redefined); |
370 | #endif |
371 | |
372 | static char* lookup_vm_options(); |
373 | |
374 | static JImageLocationRef jimage_find_resource(JImageFile* jf, const char* module_name, |
375 | const char* file_name, jlong &size); |
376 | |
377 | static void trace_class_path(const char* msg, const char* name = NULL__null); |
378 | |
379 | // VM monitoring and management support |
380 | static jlong classloader_time_ms(); |
381 | static jlong class_method_total_size(); |
382 | static jlong class_init_count(); |
383 | static jlong class_init_time_ms(); |
384 | static jlong class_verify_time_ms(); |
385 | static jlong class_link_count(); |
386 | static jlong class_link_time_ms(); |
387 | |
388 | // adds a class path to the boot append entries |
389 | static void add_to_boot_append_entries(ClassPathEntry* new_entry); |
390 | |
391 | // creates a class path zip entry (returns NULL if JAR file cannot be opened) |
392 | static ClassPathZipEntry* create_class_path_zip_entry(const char *apath, bool is_boot_append); |
393 | |
394 | static bool string_ends_with(const char* str, const char* str_to_find); |
395 | |
396 | // Extract package name from a fully qualified class name |
397 | // *bad_class_name is set to true if there's a problem with parsing class_name, to |
398 | // distinguish from a class_name with no package name, as both cases have a NULL return value |
399 | static Symbol* package_from_class_name(const Symbol* class_name, bool* bad_class_name = NULL__null); |
400 | |
401 | // Debugging |
402 | static void verify() PRODUCT_RETURN; |
403 | }; |
404 | |
405 | // PerfClassTraceTime is used to measure time for class loading related events. |
406 | // This class tracks cumulative time and exclusive time for specific event types. |
407 | // During the execution of one event, other event types (e.g. class loading and |
408 | // resolution) as well as recursive calls of the same event type could happen. |
409 | // Only one elapsed timer (cumulative) and one thread-local self timer (exclusive) |
410 | // (i.e. only one event type) are active at a time even multiple PerfClassTraceTime |
411 | // instances have been created as multiple events are happening. |
412 | class PerfClassTraceTime { |
413 | public: |
414 | enum { |
415 | CLASS_LOAD = 0, |
416 | CLASS_LINK = 1, |
417 | CLASS_VERIFY = 2, |
418 | CLASS_CLINIT = 3, |
419 | DEFINE_CLASS = 4, |
420 | EVENT_TYPE_COUNT = 5 |
421 | }; |
422 | protected: |
423 | // _t tracks time from initialization to destruction of this timer instance |
424 | // including time for all other event types, and recursive calls of this type. |
425 | // When a timer is called recursively, the elapsedTimer _t would not be used. |
426 | elapsedTimer _t; |
427 | PerfLongCounter* _timep; |
428 | PerfLongCounter* _selftimep; |
429 | PerfLongCounter* _eventp; |
430 | // pointer to thread-local recursion counter and timer array |
431 | // The thread_local timers track cumulative time for specific event types |
432 | // exclusive of time for other event types, but including recursive calls |
433 | // of the same type. |
434 | int* _recursion_counters; |
435 | elapsedTimer* _timers; |
436 | int _event_type; |
437 | int _prev_active_event; |
438 | |
439 | public: |
440 | |
441 | inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */ |
442 | PerfLongCounter* selftimep, /* counter incremented with exclusive time */ |
443 | PerfLongCounter* eventp, /* event counter */ |
444 | int* recursion_counters, /* thread-local recursion counter array */ |
445 | elapsedTimer* timers, /* thread-local timer array */ |
446 | int type /* event type */ ) : |
447 | _timep(timep), _selftimep(selftimep), _eventp(eventp), _recursion_counters(recursion_counters), _timers(timers), _event_type(type) { |
448 | initialize(); |
449 | } |
450 | |
451 | inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */ |
452 | elapsedTimer* timers, /* thread-local timer array */ |
453 | int type /* event type */ ) : |
454 | _timep(timep), _selftimep(NULL__null), _eventp(NULL__null), _recursion_counters(NULL__null), _timers(timers), _event_type(type) { |
455 | initialize(); |
456 | } |
457 | |
458 | ~PerfClassTraceTime(); |
459 | void initialize(); |
460 | }; |
461 | |
462 | #endif // SHARE_CLASSFILE_CLASSLOADER_HPP |
1 | /* |
2 | * Copyright (c) 1997, 2021, 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_KLASS_HPP |
26 | #define SHARE_OOPS_KLASS_HPP |
27 | |
28 | #include "memory/iterator.hpp" |
29 | #include "memory/memRegion.hpp" |
30 | #include "oops/markWord.hpp" |
31 | #include "oops/metadata.hpp" |
32 | #include "oops/oop.hpp" |
33 | #include "oops/oopHandle.hpp" |
34 | #include "utilities/accessFlags.hpp" |
35 | #include "utilities/macros.hpp" |
36 | #if INCLUDE_JFR1 |
37 | #include "jfr/support/jfrTraceIdExtension.hpp" |
38 | #endif |
39 | |
40 | // Klass IDs for all subclasses of Klass |
41 | enum KlassID { |
42 | InstanceKlassID, |
43 | InstanceRefKlassID, |
44 | InstanceMirrorKlassID, |
45 | InstanceClassLoaderKlassID, |
46 | TypeArrayKlassID, |
47 | ObjArrayKlassID |
48 | }; |
49 | |
50 | const uint KLASS_ID_COUNT = 6; |
51 | |
52 | // |
53 | // A Klass provides: |
54 | // 1: language level class object (method dictionary etc.) |
55 | // 2: provide vm dispatch behavior for the object |
56 | // Both functions are combined into one C++ class. |
57 | |
58 | // One reason for the oop/klass dichotomy in the implementation is |
59 | // that we don't want a C++ vtbl pointer in every object. Thus, |
60 | // normal oops don't have any virtual functions. Instead, they |
61 | // forward all "virtual" functions to their klass, which does have |
62 | // a vtbl and does the C++ dispatch depending on the object's |
63 | // actual type. (See oop.inline.hpp for some of the forwarding code.) |
64 | // ALL FUNCTIONS IMPLEMENTING THIS DISPATCH ARE PREFIXED WITH "oop_"! |
65 | |
66 | // Forward declarations. |
67 | template <class T> class Array; |
68 | template <class T> class GrowableArray; |
69 | class ClassLoaderData; |
70 | class fieldDescriptor; |
71 | class klassVtable; |
72 | class ModuleEntry; |
73 | class PackageEntry; |
74 | class ParCompactionManager; |
75 | class PSPromotionManager; |
76 | class vtableEntry; |
77 | |
78 | class Klass : public Metadata { |
79 | friend class VMStructs; |
80 | friend class JVMCIVMStructs; |
81 | protected: |
82 | // If you add a new field that points to any metaspace object, you |
83 | // must add this field to Klass::metaspace_pointers_do(). |
84 | |
85 | // note: put frequently-used fields together at start of klass structure |
86 | // for better cache behavior (may not make much of a difference but sure won't hurt) |
87 | enum { _primary_super_limit = 8 }; |
88 | |
89 | // The "layout helper" is a combined descriptor of object layout. |
90 | // For klasses which are neither instance nor array, the value is zero. |
91 | // |
92 | // For instances, layout helper is a positive number, the instance size. |
93 | // This size is already passed through align_object_size and scaled to bytes. |
94 | // The low order bit is set if instances of this class cannot be |
95 | // allocated using the fastpath. |
96 | // |
97 | // For arrays, layout helper is a negative number, containing four |
98 | // distinct bytes, as follows: |
99 | // MSB:[tag, hsz, ebt, log2(esz)]:LSB |
100 | // where: |
101 | // tag is 0x80 if the elements are oops, 0xC0 if non-oops |
102 | // hsz is array header size in bytes (i.e., offset of first element) |
103 | // ebt is the BasicType of the elements |
104 | // esz is the element size in bytes |
105 | // This packed word is arranged so as to be quickly unpacked by the |
106 | // various fast paths that use the various subfields. |
107 | // |
108 | // The esz bits can be used directly by a SLL instruction, without masking. |
109 | // |
110 | // Note that the array-kind tag looks like 0x00 for instance klasses, |
111 | // since their length in bytes is always less than 24Mb. |
112 | // |
113 | // Final note: This comes first, immediately after C++ vtable, |
114 | // because it is frequently queried. |
115 | jint _layout_helper; |
116 | |
117 | // Klass identifier used to implement devirtualized oop closure dispatching. |
118 | const KlassID _id; |
119 | |
120 | // Processed access flags, for use by Class.getModifiers. |
121 | jint _modifier_flags; |
122 | |
123 | // The fields _super_check_offset, _secondary_super_cache, _secondary_supers |
124 | // and _primary_supers all help make fast subtype checks. See big discussion |
125 | // in doc/server_compiler/checktype.txt |
126 | // |
127 | // Where to look to observe a supertype (it is &_secondary_super_cache for |
128 | // secondary supers, else is &_primary_supers[depth()]. |
129 | juint _super_check_offset; |
130 | |
131 | // Class name. Instance classes: java/lang/String, etc. Array classes: [I, |
132 | // [Ljava/lang/String;, etc. Set to zero for all other kinds of classes. |
133 | Symbol* _name; |
134 | |
135 | // Cache of last observed secondary supertype |
136 | Klass* _secondary_super_cache; |
137 | // Array of all secondary supertypes |
138 | Array<Klass*>* _secondary_supers; |
139 | // Ordered list of all primary supertypes |
140 | Klass* _primary_supers[_primary_super_limit]; |
141 | // java/lang/Class instance mirroring this class |
142 | OopHandle _java_mirror; |
143 | // Superclass |
144 | Klass* _super; |
145 | // First subclass (NULL if none); _subklass->next_sibling() is next one |
146 | Klass* volatile _subklass; |
147 | // Sibling link (or NULL); links all subklasses of a klass |
148 | Klass* volatile _next_sibling; |
149 | |
150 | // All klasses loaded by a class loader are chained through these links |
151 | Klass* _next_link; |
152 | |
153 | // The VM's representation of the ClassLoader used to load this class. |
154 | // Provide access the corresponding instance java.lang.ClassLoader. |
155 | ClassLoaderData* _class_loader_data; |
156 | |
157 | int _vtable_len; // vtable length. This field may be read very often when we |
158 | // have lots of itable dispatches (e.g., lambdas and streams). |
159 | // Keep it away from the beginning of a Klass to avoid cacheline |
160 | // contention that may happen when a nearby object is modified. |
161 | AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. |
162 | |
163 | JFR_ONLY(DEFINE_TRACE_ID_FIELD;)mutable traceid _trace_id; |
164 | |
165 | private: |
166 | // This is an index into FileMapHeader::_shared_path_table[], to |
167 | // associate this class with the JAR file where it's loaded from during |
168 | // dump time. If a class is not loaded from the shared archive, this field is |
169 | // -1. |
170 | jshort _shared_class_path_index; |
171 | |
172 | #if INCLUDE_CDS1 |
173 | // Flags of the current shared class. |
174 | u2 _shared_class_flags; |
175 | enum { |
176 | _archived_lambda_proxy_is_available = 2, |
177 | _has_value_based_class_annotation = 4, |
178 | _verified_at_dump_time = 8 |
179 | }; |
180 | #endif |
181 | |
182 | CDS_JAVA_HEAP_ONLY(int _archived_mirror_index;)int _archived_mirror_index; |
183 | |
184 | protected: |
185 | |
186 | // Constructor |
187 | Klass(KlassID id); |
188 | Klass() : _id(KlassID(-1)) { assert(DumpSharedSpaces || UseSharedSpaces, "only for cds")do { if (!(DumpSharedSpaces || UseSharedSpaces)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 188, "assert(" "DumpSharedSpaces || UseSharedSpaces" ") failed" , "only for cds"); ::breakpoint(); } } while (0); } |
189 | |
190 | void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPSJavaThread* __the_thread__) throw(); |
191 | |
192 | public: |
193 | int id() { return _id; } |
194 | |
195 | enum class DefaultsLookupMode { find, skip }; |
196 | enum class OverpassLookupMode { find, skip }; |
197 | enum class StaticLookupMode { find, skip }; |
198 | enum class PrivateLookupMode { find, skip }; |
199 | |
200 | virtual bool is_klass() const { return true; } |
201 | |
202 | // super() cannot be InstanceKlass* -- Java arrays are covariant, and _super is used |
203 | // to implement that. NB: the _super of "[Ljava/lang/Integer;" is "[Ljava/lang/Number;" |
204 | // If this is not what your code expects, you're probably looking for Klass::java_super(). |
205 | Klass* super() const { return _super; } |
206 | void set_super(Klass* k) { _super = k; } |
207 | |
208 | // initializes _super link, _primary_supers & _secondary_supers arrays |
209 | void initialize_supers(Klass* k, Array<InstanceKlass*>* transitive_interfaces, TRAPSJavaThread* __the_thread__); |
210 | |
211 | // klass-specific helper for initializing _secondary_supers |
212 | virtual GrowableArray<Klass*>* compute_secondary_supers(int num_extra_slots, |
213 | Array<InstanceKlass*>* transitive_interfaces); |
214 | |
215 | // java_super is the Java-level super type as specified by Class.getSuperClass. |
216 | virtual InstanceKlass* java_super() const { return NULL__null; } |
217 | |
218 | juint super_check_offset() const { return _super_check_offset; } |
219 | void set_super_check_offset(juint o) { _super_check_offset = o; } |
220 | |
221 | Klass* secondary_super_cache() const { return _secondary_super_cache; } |
222 | void set_secondary_super_cache(Klass* k) { _secondary_super_cache = k; } |
223 | |
224 | Array<Klass*>* secondary_supers() const { return _secondary_supers; } |
225 | void set_secondary_supers(Array<Klass*>* k) { _secondary_supers = k; } |
226 | |
227 | // Return the element of the _super chain of the given depth. |
228 | // If there is no such element, return either NULL or this. |
229 | Klass* primary_super_of_depth(juint i) const { |
230 | assert(i < primary_super_limit(), "oob")do { if (!(i < primary_super_limit())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 230, "assert(" "i < primary_super_limit()" ") failed", "oob" ); ::breakpoint(); } } while (0); |
231 | Klass* super = _primary_supers[i]; |
232 | assert(super == NULL || super->super_depth() == i, "correct display")do { if (!(super == __null || super->super_depth() == i)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 232, "assert(" "super == __null || super->super_depth() == i" ") failed", "correct display"); ::breakpoint(); } } while (0 ); |
233 | return super; |
234 | } |
235 | |
236 | // Can this klass be a primary super? False for interfaces and arrays of |
237 | // interfaces. False also for arrays or classes with long super chains. |
238 | bool can_be_primary_super() const { |
239 | const juint secondary_offset = in_bytes(secondary_super_cache_offset()); |
240 | return super_check_offset() != secondary_offset; |
241 | } |
242 | virtual bool can_be_primary_super_slow() const; |
243 | |
244 | // Returns number of primary supers; may be a number in the inclusive range [0, primary_super_limit]. |
245 | juint super_depth() const { |
246 | if (!can_be_primary_super()) { |
247 | return primary_super_limit(); |
248 | } else { |
249 | juint d = (super_check_offset() - in_bytes(primary_supers_offset())) / sizeof(Klass*); |
250 | assert(d < primary_super_limit(), "oob")do { if (!(d < primary_super_limit())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 250, "assert(" "d < primary_super_limit()" ") failed", "oob" ); ::breakpoint(); } } while (0); |
251 | assert(_primary_supers[d] == this, "proper init")do { if (!(_primary_supers[d] == this)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 251, "assert(" "_primary_supers[d] == this" ") failed", "proper init" ); ::breakpoint(); } } while (0); |
252 | return d; |
253 | } |
254 | } |
255 | |
256 | // java mirror |
257 | oop java_mirror() const; |
258 | oop java_mirror_no_keepalive() const; |
259 | void set_java_mirror(Handle m); |
260 | |
261 | oop archived_java_mirror() NOT_CDS_JAVA_HEAP_RETURN_(NULL); |
262 | void set_archived_java_mirror(oop m) NOT_CDS_JAVA_HEAP_RETURN; |
263 | |
264 | // Temporary mirror switch used by RedefineClasses |
265 | void replace_java_mirror(oop mirror); |
266 | |
267 | // Set java mirror OopHandle to NULL for CDS |
268 | // This leaves the OopHandle in the CLD, but that's ok, you can't release them. |
269 | void clear_java_mirror_handle() { _java_mirror = OopHandle(); } |
270 | |
271 | // modifier flags |
272 | jint modifier_flags() const { return _modifier_flags; } |
273 | void set_modifier_flags(jint flags) { _modifier_flags = flags; } |
274 | |
275 | // size helper |
276 | int layout_helper() const { return _layout_helper; } |
277 | void set_layout_helper(int lh) { _layout_helper = lh; } |
278 | |
279 | // Note: for instances layout_helper() may include padding. |
280 | // Use InstanceKlass::contains_field_offset to classify field offsets. |
281 | |
282 | // sub/superklass links |
283 | Klass* subklass(bool log = false) const; |
284 | Klass* next_sibling(bool log = false) const; |
285 | |
286 | InstanceKlass* superklass() const; |
287 | void append_to_sibling_list(); // add newly created receiver to superklass' subklass list |
288 | |
289 | void set_next_link(Klass* k) { _next_link = k; } |
290 | Klass* next_link() const { return _next_link; } // The next klass defined by the class loader. |
291 | Klass** next_link_addr() { return &_next_link; } |
292 | |
293 | // class loader data |
294 | ClassLoaderData* class_loader_data() const { return _class_loader_data; } |
295 | void set_class_loader_data(ClassLoaderData* loader_data) { _class_loader_data = loader_data; } |
296 | |
297 | int shared_classpath_index() const { |
298 | return _shared_class_path_index; |
299 | }; |
300 | |
301 | void set_shared_classpath_index(int index) { |
302 | _shared_class_path_index = index; |
303 | }; |
304 | |
305 | bool has_archived_mirror_index() const { |
306 | CDS_JAVA_HEAP_ONLY(return _archived_mirror_index >= 0;)return _archived_mirror_index >= 0; |
307 | NOT_CDS_JAVA_HEAP(return false); |
308 | } |
309 | |
310 | void clear_archived_mirror_index() NOT_CDS_JAVA_HEAP_RETURN; |
311 | |
312 | void set_lambda_proxy_is_available() { |
313 | CDS_ONLY(_shared_class_flags |= _archived_lambda_proxy_is_available;)_shared_class_flags |= _archived_lambda_proxy_is_available; |
314 | } |
315 | void clear_lambda_proxy_is_available() { |
316 | CDS_ONLY(_shared_class_flags &= ~_archived_lambda_proxy_is_available;)_shared_class_flags &= ~_archived_lambda_proxy_is_available ; |
317 | } |
318 | bool lambda_proxy_is_available() const { |
319 | CDS_ONLY(return (_shared_class_flags & _archived_lambda_proxy_is_available) != 0;)return (_shared_class_flags & _archived_lambda_proxy_is_available ) != 0; |
320 | NOT_CDS(return false;) |
321 | } |
322 | |
323 | void set_has_value_based_class_annotation() { |
324 | CDS_ONLY(_shared_class_flags |= _has_value_based_class_annotation;)_shared_class_flags |= _has_value_based_class_annotation; |
325 | } |
326 | void clear_has_value_based_class_annotation() { |
327 | CDS_ONLY(_shared_class_flags &= ~_has_value_based_class_annotation;)_shared_class_flags &= ~_has_value_based_class_annotation ; |
328 | } |
329 | bool has_value_based_class_annotation() const { |
330 | CDS_ONLY(return (_shared_class_flags & _has_value_based_class_annotation) != 0;)return (_shared_class_flags & _has_value_based_class_annotation ) != 0; |
331 | NOT_CDS(return false;) |
332 | } |
333 | |
334 | void set_verified_at_dump_time() { |
335 | CDS_ONLY(_shared_class_flags |= _verified_at_dump_time;)_shared_class_flags |= _verified_at_dump_time; |
336 | } |
337 | bool verified_at_dump_time() const { |
338 | CDS_ONLY(return (_shared_class_flags & _verified_at_dump_time) != 0;)return (_shared_class_flags & _verified_at_dump_time) != 0 ; |
339 | NOT_CDS(return false;) |
340 | } |
341 | |
342 | |
343 | // Obtain the module or package for this class |
344 | virtual ModuleEntry* module() const = 0; |
345 | virtual PackageEntry* package() const = 0; |
346 | |
347 | protected: // internal accessors |
348 | void set_subklass(Klass* s); |
349 | void set_next_sibling(Klass* s); |
350 | |
351 | public: |
352 | |
353 | // Compiler support |
354 | static ByteSize super_offset() { return in_ByteSize(offset_of(Klass, _super)(size_t)((intx)&(((Klass*)16)->_super) - 16)); } |
355 | static ByteSize super_check_offset_offset() { return in_ByteSize(offset_of(Klass, _super_check_offset)(size_t)((intx)&(((Klass*)16)->_super_check_offset) - 16 )); } |
356 | static ByteSize primary_supers_offset() { return in_ByteSize(offset_of(Klass, _primary_supers)(size_t)((intx)&(((Klass*)16)->_primary_supers) - 16)); } |
357 | static ByteSize secondary_super_cache_offset() { return in_ByteSize(offset_of(Klass, _secondary_super_cache)(size_t)((intx)&(((Klass*)16)->_secondary_super_cache) - 16)); } |
358 | static ByteSize secondary_supers_offset() { return in_ByteSize(offset_of(Klass, _secondary_supers)(size_t)((intx)&(((Klass*)16)->_secondary_supers) - 16 )); } |
359 | static ByteSize java_mirror_offset() { return in_ByteSize(offset_of(Klass, _java_mirror)(size_t)((intx)&(((Klass*)16)->_java_mirror) - 16)); } |
360 | static ByteSize class_loader_data_offset() { return in_ByteSize(offset_of(Klass, _class_loader_data)(size_t)((intx)&(((Klass*)16)->_class_loader_data) - 16 )); } |
361 | static ByteSize modifier_flags_offset() { return in_ByteSize(offset_of(Klass, _modifier_flags)(size_t)((intx)&(((Klass*)16)->_modifier_flags) - 16)); } |
362 | static ByteSize layout_helper_offset() { return in_ByteSize(offset_of(Klass, _layout_helper)(size_t)((intx)&(((Klass*)16)->_layout_helper) - 16)); } |
363 | static ByteSize access_flags_offset() { return in_ByteSize(offset_of(Klass, _access_flags)(size_t)((intx)&(((Klass*)16)->_access_flags) - 16)); } |
364 | |
365 | // Unpacking layout_helper: |
366 | static const int _lh_neutral_value = 0; // neutral non-array non-instance value |
367 | static const int _lh_instance_slow_path_bit = 0x01; |
368 | static const int _lh_log2_element_size_shift = BitsPerByte*0; |
369 | static const int _lh_log2_element_size_mask = BitsPerLong-1; |
370 | static const int _lh_element_type_shift = BitsPerByte*1; |
371 | static const int _lh_element_type_mask = right_n_bits(BitsPerByte)((((BitsPerByte) >= BitsPerWord) ? 0 : (OneBit << (BitsPerByte ))) - 1); // shifted mask |
372 | static const int _lh_header_size_shift = BitsPerByte*2; |
373 | static const int _lh_header_size_mask = right_n_bits(BitsPerByte)((((BitsPerByte) >= BitsPerWord) ? 0 : (OneBit << (BitsPerByte ))) - 1); // shifted mask |
374 | static const int _lh_array_tag_bits = 2; |
375 | static const int _lh_array_tag_shift = BitsPerInt - _lh_array_tag_bits; |
376 | static const int _lh_array_tag_obj_value = ~0x01; // 0x80000000 >> 30 |
377 | |
378 | static const unsigned int _lh_array_tag_type_value = 0Xffffffff; // ~0x00, // 0xC0000000 >> 30 |
379 | |
380 | static int layout_helper_size_in_bytes(jint lh) { |
381 | assert(lh > (jint)_lh_neutral_value, "must be instance")do { if (!(lh > (jint)_lh_neutral_value)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 381, "assert(" "lh > (jint)_lh_neutral_value" ") failed" , "must be instance"); ::breakpoint(); } } while (0); |
382 | return (int) lh & ~_lh_instance_slow_path_bit; |
383 | } |
384 | static bool layout_helper_needs_slow_path(jint lh) { |
385 | assert(lh > (jint)_lh_neutral_value, "must be instance")do { if (!(lh > (jint)_lh_neutral_value)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 385, "assert(" "lh > (jint)_lh_neutral_value" ") failed" , "must be instance"); ::breakpoint(); } } while (0); |
386 | return (lh & _lh_instance_slow_path_bit) != 0; |
387 | } |
388 | static bool layout_helper_is_instance(jint lh) { |
389 | return (jint)lh > (jint)_lh_neutral_value; |
390 | } |
391 | static bool layout_helper_is_array(jint lh) { |
392 | return (jint)lh < (jint)_lh_neutral_value; |
393 | } |
394 | static bool layout_helper_is_typeArray(jint lh) { |
395 | // _lh_array_tag_type_value == (lh >> _lh_array_tag_shift); |
396 | return (juint)lh >= (juint)(_lh_array_tag_type_value << _lh_array_tag_shift); |
397 | } |
398 | static bool layout_helper_is_objArray(jint lh) { |
399 | // _lh_array_tag_obj_value == (lh >> _lh_array_tag_shift); |
400 | return (jint)lh < (jint)(_lh_array_tag_type_value << _lh_array_tag_shift); |
401 | } |
402 | static int layout_helper_header_size(jint lh) { |
403 | assert(lh < (jint)_lh_neutral_value, "must be array")do { if (!(lh < (jint)_lh_neutral_value)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 403, "assert(" "lh < (jint)_lh_neutral_value" ") failed" , "must be array"); ::breakpoint(); } } while (0); |
404 | int hsize = (lh >> _lh_header_size_shift) & _lh_header_size_mask; |
405 | assert(hsize > 0 && hsize < (int)sizeof(oopDesc)*3, "sanity")do { if (!(hsize > 0 && hsize < (int)sizeof(oopDesc )*3)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 405, "assert(" "hsize > 0 && hsize < (int)sizeof(oopDesc)*3" ") failed", "sanity"); ::breakpoint(); } } while (0); |
406 | return hsize; |
407 | } |
408 | static BasicType layout_helper_element_type(jint lh) { |
409 | assert(lh < (jint)_lh_neutral_value, "must be array")do { if (!(lh < (jint)_lh_neutral_value)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 409, "assert(" "lh < (jint)_lh_neutral_value" ") failed" , "must be array"); ::breakpoint(); } } while (0); |
410 | int btvalue = (lh >> _lh_element_type_shift) & _lh_element_type_mask; |
411 | assert(btvalue >= T_BOOLEAN && btvalue <= T_OBJECT, "sanity")do { if (!(btvalue >= T_BOOLEAN && btvalue <= T_OBJECT )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 411, "assert(" "btvalue >= T_BOOLEAN && btvalue <= T_OBJECT" ") failed", "sanity"); ::breakpoint(); } } while (0); |
412 | return (BasicType) btvalue; |
413 | } |
414 | |
415 | // Want a pattern to quickly diff against layout header in register |
416 | // find something less clever! |
417 | static int layout_helper_boolean_diffbit() { |
418 | jint zlh = array_layout_helper(T_BOOLEAN); |
419 | jint blh = array_layout_helper(T_BYTE); |
420 | assert(zlh != blh, "array layout helpers must differ")do { if (!(zlh != blh)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 420, "assert(" "zlh != blh" ") failed", "array layout helpers must differ" ); ::breakpoint(); } } while (0); |
421 | int diffbit = 1; |
422 | while ((diffbit & (zlh ^ blh)) == 0 && (diffbit & zlh) == 0) { |
423 | diffbit <<= 1; |
424 | assert(diffbit != 0, "make sure T_BOOLEAN has a different bit than T_BYTE")do { if (!(diffbit != 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 424, "assert(" "diffbit != 0" ") failed", "make sure T_BOOLEAN has a different bit than T_BYTE" ); ::breakpoint(); } } while (0); |
425 | } |
426 | return diffbit; |
427 | } |
428 | |
429 | static int layout_helper_log2_element_size(jint lh) { |
430 | assert(lh < (jint)_lh_neutral_value, "must be array")do { if (!(lh < (jint)_lh_neutral_value)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 430, "assert(" "lh < (jint)_lh_neutral_value" ") failed" , "must be array"); ::breakpoint(); } } while (0); |
431 | int l2esz = (lh >> _lh_log2_element_size_shift) & _lh_log2_element_size_mask; |
432 | assert(l2esz <= LogBytesPerLong,do { if (!(l2esz <= LogBytesPerLong)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 433, "assert(" "l2esz <= LogBytesPerLong" ") failed", "sanity. l2esz: 0x%x for lh: 0x%x" , (uint)l2esz, (uint)lh); ::breakpoint(); } } while (0) |
433 | "sanity. l2esz: 0x%x for lh: 0x%x", (uint)l2esz, (uint)lh)do { if (!(l2esz <= LogBytesPerLong)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 433, "assert(" "l2esz <= LogBytesPerLong" ") failed", "sanity. l2esz: 0x%x for lh: 0x%x" , (uint)l2esz, (uint)lh); ::breakpoint(); } } while (0); |
434 | return l2esz; |
435 | } |
436 | static jint array_layout_helper(jint tag, int hsize, BasicType etype, int log2_esize) { |
437 | return (tag << _lh_array_tag_shift) |
438 | | (hsize << _lh_header_size_shift) |
439 | | ((int)etype << _lh_element_type_shift) |
440 | | (log2_esize << _lh_log2_element_size_shift); |
441 | } |
442 | static jint instance_layout_helper(jint size, bool slow_path_flag) { |
443 | return (size << LogBytesPerWord) |
444 | | (slow_path_flag ? _lh_instance_slow_path_bit : 0); |
445 | } |
446 | static int layout_helper_to_size_helper(jint lh) { |
447 | assert(lh > (jint)_lh_neutral_value, "must be instance")do { if (!(lh > (jint)_lh_neutral_value)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 447, "assert(" "lh > (jint)_lh_neutral_value" ") failed" , "must be instance"); ::breakpoint(); } } while (0); |
448 | // Note that the following expression discards _lh_instance_slow_path_bit. |
449 | return lh >> LogBytesPerWord; |
450 | } |
451 | // Out-of-line version computes everything based on the etype: |
452 | static jint array_layout_helper(BasicType etype); |
453 | |
454 | // What is the maximum number of primary superclasses any klass can have? |
455 | static juint primary_super_limit() { return _primary_super_limit; } |
456 | |
457 | // vtables |
458 | klassVtable vtable() const; |
459 | int vtable_length() const { return _vtable_len; } |
460 | |
461 | // subclass check |
462 | bool is_subclass_of(const Klass* k) const; |
463 | // subtype check: true if is_subclass_of, or if k is interface and receiver implements it |
464 | bool is_subtype_of(Klass* k) const { |
465 | juint off = k->super_check_offset(); |
466 | Klass* sup = *(Klass**)( (address)this + off ); |
467 | const juint secondary_offset = in_bytes(secondary_super_cache_offset()); |
468 | if (sup == k) { |
469 | return true; |
470 | } else if (off != secondary_offset) { |
471 | return false; |
472 | } else { |
473 | return search_secondary_supers(k); |
474 | } |
475 | } |
476 | |
477 | bool search_secondary_supers(Klass* k) const; |
478 | |
479 | // Find LCA in class hierarchy |
480 | Klass *LCA( Klass *k ); |
481 | |
482 | // Check whether reflection/jni/jvm code is allowed to instantiate this class; |
483 | // if not, throw either an Error or an Exception. |
484 | virtual void check_valid_for_instantiation(bool throwError, TRAPSJavaThread* __the_thread__); |
485 | |
486 | // array copying |
487 | virtual void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPSJavaThread* __the_thread__); |
488 | |
489 | // tells if the class should be initialized |
490 | virtual bool should_be_initialized() const { return false; } |
491 | // initializes the klass |
492 | virtual void initialize(TRAPSJavaThread* __the_thread__); |
493 | virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const; |
494 | virtual Method* uncached_lookup_method(const Symbol* name, const Symbol* signature, |
495 | OverpassLookupMode overpass_mode, |
496 | PrivateLookupMode = PrivateLookupMode::find) const; |
497 | public: |
498 | Method* lookup_method(const Symbol* name, const Symbol* signature) const { |
499 | return uncached_lookup_method(name, signature, OverpassLookupMode::find); |
500 | } |
501 | |
502 | // array class with specific rank |
503 | virtual Klass* array_klass(int rank, TRAPSJavaThread* __the_thread__) = 0; |
504 | |
505 | // array class with this klass as element type |
506 | virtual Klass* array_klass(TRAPSJavaThread* __the_thread__) = 0; |
507 | |
508 | // These will return NULL instead of allocating on the heap: |
509 | virtual Klass* array_klass_or_null(int rank) = 0; |
510 | virtual Klass* array_klass_or_null() = 0; |
511 | |
512 | virtual oop protection_domain() const = 0; |
513 | |
514 | oop class_loader() const; |
515 | |
516 | inline oop klass_holder() const; |
517 | |
518 | protected: |
519 | |
520 | // Error handling when length > max_length or length < 0 |
521 | static void check_array_allocation_length(int length, int max_length, TRAPSJavaThread* __the_thread__); |
522 | |
523 | void set_vtable_length(int len) { _vtable_len= len; } |
524 | |
525 | vtableEntry* start_of_vtable() const; |
526 | void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPSJavaThread* __the_thread__); |
527 | public: |
528 | Method* method_at_vtable(int index); |
529 | |
530 | static ByteSize vtable_start_offset(); |
531 | static ByteSize vtable_length_offset() { |
532 | return byte_offset_of(Klass, _vtable_len)in_ByteSize((int)(size_t)((intx)&(((Klass*)16)->_vtable_len ) - 16)); |
533 | } |
534 | |
535 | // CDS support - remove and restore oops from metadata. Oops are not shared. |
536 | virtual void remove_unshareable_info(); |
537 | virtual void remove_java_mirror(); |
538 | |
539 | bool is_unshareable_info_restored() const { |
540 | assert(is_shared(), "use this for shared classes only")do { if (!(is_shared())) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 540, "assert(" "is_shared()" ") failed", "use this for shared classes only" ); ::breakpoint(); } } while (0); |
541 | if (has_archived_mirror_index()) { |
542 | // _java_mirror is not a valid OopHandle but rather an encoded reference in the shared heap |
543 | return false; |
544 | } else if (_java_mirror.ptr_raw() == NULL__null) { |
545 | return false; |
546 | } else { |
547 | return true; |
548 | } |
549 | } |
550 | |
551 | public: |
552 | // ALL FUNCTIONS BELOW THIS POINT ARE DISPATCHED FROM AN OOP |
553 | // These functions describe behavior for the oop not the KLASS. |
554 | |
555 | // actual oop size of obj in memory in word size. |
556 | virtual size_t oop_size(oop obj) const = 0; |
557 | |
558 | // Size of klass in word size. |
559 | virtual int size() const = 0; |
560 | |
561 | // Returns the Java name for a class (Resource allocated) |
562 | // For arrays, this returns the name of the element with a leading '['. |
563 | // For classes, this returns the name with the package separators |
564 | // turned into '.'s. |
565 | const char* external_name() const; |
566 | // Returns the name for a class (Resource allocated) as the class |
567 | // would appear in a signature. |
568 | // For arrays, this returns the name of the element with a leading '['. |
569 | // For classes, this returns the name with a leading 'L' and a trailing ';' |
570 | // and the package separators as '/'. |
571 | virtual const char* signature_name() const; |
572 | |
573 | const char* joint_in_module_of_loader(const Klass* class2, bool include_parent_loader = false) const; |
574 | const char* class_in_module_of_loader(bool use_are = false, bool include_parent_loader = false) const; |
575 | |
576 | // Returns "interface", "abstract class" or "class". |
577 | const char* external_kind() const; |
578 | |
579 | // type testing operations |
580 | #ifdef ASSERT1 |
581 | protected: |
582 | virtual bool is_instance_klass_slow() const { return false; } |
583 | virtual bool is_array_klass_slow() const { return false; } |
584 | virtual bool is_objArray_klass_slow() const { return false; } |
585 | virtual bool is_typeArray_klass_slow() const { return false; } |
586 | #endif // ASSERT |
587 | public: |
588 | |
589 | // Fast non-virtual versions |
590 | #ifndef ASSERT1 |
591 | #define assert_same_query(xval, xcheck) xval |
592 | #else |
593 | private: |
594 | static bool assert_same_query(bool xval, bool xslow) { |
595 | assert(xval == xslow, "slow and fast queries agree")do { if (!(xval == xslow)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/oops/klass.hpp" , 595, "assert(" "xval == xslow" ") failed", "slow and fast queries agree" ); ::breakpoint(); } } while (0); |
596 | return xval; |
597 | } |
598 | public: |
599 | #endif |
600 | inline bool is_instance_klass() const { return assert_same_query( |
601 | layout_helper_is_instance(layout_helper()), |
602 | is_instance_klass_slow()); } |
603 | inline bool is_array_klass() const { return assert_same_query( |
604 | layout_helper_is_array(layout_helper()), |
605 | is_array_klass_slow()); } |
606 | inline bool is_objArray_klass() const { return assert_same_query( |
607 | layout_helper_is_objArray(layout_helper()), |
608 | is_objArray_klass_slow()); } |
609 | inline bool is_typeArray_klass() const { return assert_same_query( |
610 | layout_helper_is_typeArray(layout_helper()), |
611 | is_typeArray_klass_slow()); } |
612 | #undef assert_same_query |
613 | |
614 | // Access flags |
615 | AccessFlags access_flags() const { return _access_flags; } |
616 | void set_access_flags(AccessFlags flags) { _access_flags = flags; } |
617 | |
618 | bool is_public() const { return _access_flags.is_public(); } |
619 | bool is_final() const { return _access_flags.is_final(); } |
620 | bool is_interface() const { return _access_flags.is_interface(); } |
621 | bool is_abstract() const { return _access_flags.is_abstract(); } |
622 | bool is_super() const { return _access_flags.is_super(); } |
623 | bool is_synthetic() const { return _access_flags.is_synthetic(); } |
624 | void set_is_synthetic() { _access_flags.set_is_synthetic(); } |
625 | bool has_finalizer() const { return _access_flags.has_finalizer(); } |
626 | bool has_final_method() const { return _access_flags.has_final_method(); } |
627 | void set_has_finalizer() { _access_flags.set_has_finalizer(); } |
628 | void set_has_final_method() { _access_flags.set_has_final_method(); } |
629 | bool has_vanilla_constructor() const { return _access_flags.has_vanilla_constructor(); } |
630 | void set_has_vanilla_constructor() { _access_flags.set_has_vanilla_constructor(); } |
631 | bool has_miranda_methods () const { return access_flags().has_miranda_methods(); } |
632 | void set_has_miranda_methods() { _access_flags.set_has_miranda_methods(); } |
633 | bool is_shared() const { return access_flags().is_shared_class(); } // shadows MetaspaceObj::is_shared)() |
634 | void set_is_shared() { _access_flags.set_is_shared_class(); } |
635 | bool is_hidden() const { return access_flags().is_hidden_class(); } |
636 | void set_is_hidden() { _access_flags.set_is_hidden_class(); } |
637 | bool is_value_based() { return _access_flags.is_value_based_class(); } |
638 | void set_is_value_based() { _access_flags.set_is_value_based_class(); } |
639 | |
640 | inline bool is_non_strong_hidden() const; |
641 | |
642 | bool is_cloneable() const; |
643 | void set_is_cloneable(); |
644 | |
645 | JFR_ONLY(DEFINE_TRACE_ID_METHODS;)traceid trace_id() const { return _trace_id; } traceid* const trace_id_addr() const { return &_trace_id; } void set_trace_id (traceid id) const { _trace_id = id; }; |
646 | |
647 | virtual void metaspace_pointers_do(MetaspaceClosure* iter); |
648 | virtual MetaspaceObj::Type type() const { return ClassType; } |
649 | |
650 | inline bool is_loader_alive() const; |
651 | |
652 | void clean_subklass(); |
653 | |
654 | static void clean_weak_klass_links(bool unloading_occurred, bool clean_alive_klasses = true); |
655 | static void clean_subklass_tree() { |
656 | clean_weak_klass_links(/*unloading_occurred*/ true , /* clean_alive_klasses */ false); |
657 | } |
658 | |
659 | // Return self, except for abstract classes with exactly 1 |
660 | // implementor. Then return the 1 concrete implementation. |
661 | Klass *up_cast_abstract(); |
662 | |
663 | // klass name |
664 | Symbol* name() const { return _name; } |
665 | void set_name(Symbol* n); |
666 | |
667 | virtual void release_C_heap_structures(bool release_constant_pool = true); |
668 | |
669 | public: |
670 | virtual jint compute_modifier_flags() const = 0; |
671 | |
672 | // JVMTI support |
673 | virtual jint jvmti_class_status() const; |
674 | |
675 | // Printing |
676 | virtual void print_on(outputStream* st) const; |
677 | |
678 | virtual void oop_print_value_on(oop obj, outputStream* st); |
679 | virtual void oop_print_on (oop obj, outputStream* st); |
680 | |
681 | virtual const char* internal_name() const = 0; |
682 | |
683 | // Verification |
684 | virtual void verify_on(outputStream* st); |
685 | void verify() { verify_on(tty); } |
686 | |
687 | #ifndef PRODUCT |
688 | bool verify_vtable_index(int index); |
689 | #endif |
690 | |
691 | virtual void oop_verify_on(oop obj, outputStream* st); |
692 | |
693 | // for error reporting |
694 | static bool is_valid(Klass* k); |
695 | }; |
696 | |
697 | #endif // SHARE_OOPS_KLASS_HPP |
1 | /* |
2 | * Copyright (c) 1997, 2021, 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_UTILITIES_ACCESSFLAGS_HPP |
26 | #define SHARE_UTILITIES_ACCESSFLAGS_HPP |
27 | |
28 | #include "jvm_constants.h" |
29 | #include "utilities/debug.hpp" |
30 | #include "utilities/globalDefinitions.hpp" |
31 | #include "utilities/macros.hpp" |
32 | |
33 | // AccessFlags is an abstraction over Java access flags. |
34 | |
35 | class outputStream; |
36 | |
37 | enum { |
38 | // See jvm.h for shared JVM_ACC_XXX access flags |
39 | |
40 | // HotSpot-specific access flags |
41 | |
42 | // flags actually put in .class file |
43 | JVM_ACC_WRITTEN_FLAGS = 0x00007FFF, |
44 | |
45 | // Method* flags |
46 | JVM_ACC_MONITOR_MATCH = 0x10000000, // True if we know that monitorenter/monitorexit bytecodes match |
47 | JVM_ACC_HAS_MONITOR_BYTECODES = 0x20000000, // Method contains monitorenter/monitorexit bytecodes |
48 | JVM_ACC_HAS_LOOPS = 0x40000000, // Method has loops |
49 | JVM_ACC_LOOPS_FLAG_INIT = (int)0x80000000,// The loop flag has been initialized |
50 | JVM_ACC_QUEUED = 0x01000000, // Queued for compilation |
51 | JVM_ACC_NOT_C2_COMPILABLE = 0x02000000, |
52 | JVM_ACC_NOT_C1_COMPILABLE = 0x04000000, |
53 | JVM_ACC_NOT_C2_OSR_COMPILABLE = 0x08000000, |
54 | JVM_ACC_HAS_LINE_NUMBER_TABLE = 0x00100000, |
55 | JVM_ACC_HAS_CHECKED_EXCEPTIONS = 0x00400000, |
56 | JVM_ACC_HAS_JSRS = 0x00800000, |
57 | JVM_ACC_IS_OLD = 0x00010000, // RedefineClasses() has replaced this method |
58 | JVM_ACC_IS_OBSOLETE = 0x00020000, // RedefineClasses() has made method obsolete |
59 | JVM_ACC_IS_PREFIXED_NATIVE = 0x00040000, // JVMTI has prefixed this native method |
60 | JVM_ACC_ON_STACK = 0x00080000, // RedefineClasses() was used on the stack |
61 | JVM_ACC_IS_DELETED = 0x00008000, // RedefineClasses() has deleted this method |
62 | |
63 | // Klass* flags |
64 | JVM_ACC_HAS_MIRANDA_METHODS = 0x10000000, // True if this class has miranda methods in it's vtable |
65 | JVM_ACC_HAS_VANILLA_CONSTRUCTOR = 0x20000000, // True if klass has a vanilla default constructor |
66 | JVM_ACC_HAS_FINALIZER = 0x40000000, // True if klass has a non-empty finalize() method |
67 | JVM_ACC_IS_CLONEABLE_FAST = (int)0x80000000,// True if klass implements the Cloneable interface and can be optimized in generated code |
68 | JVM_ACC_HAS_FINAL_METHOD = 0x01000000, // True if klass has final method |
69 | JVM_ACC_IS_SHARED_CLASS = 0x02000000, // True if klass is shared |
70 | JVM_ACC_IS_HIDDEN_CLASS = 0x04000000, // True if klass is hidden |
71 | JVM_ACC_IS_VALUE_BASED_CLASS = 0x08000000, // True if klass is marked as a ValueBased class |
72 | JVM_ACC_IS_BEING_REDEFINED = 0x00100000, // True if the klass is being redefined. |
73 | JVM_ACC_HAS_RESOLVED_METHODS = 0x00200000, // True if the klass has resolved methods |
74 | |
75 | // Klass* and Method* flags |
76 | JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00400000, |
77 | |
78 | JVM_ACC_PROMOTED_FLAGS = 0x00400000, // flags promoted from methods to the holding klass |
79 | |
80 | // field flags |
81 | // Note: these flags must be defined in the low order 16 bits because |
82 | // InstanceKlass only stores a ushort worth of information from the |
83 | // AccessFlags value. |
84 | // These bits must not conflict with any other field-related access flags |
85 | // (e.g., ACC_ENUM). |
86 | // Note that the class-related ACC_ANNOTATION bit conflicts with these flags. |
87 | JVM_ACC_FIELD_ACCESS_WATCHED = 0x00002000, // field access is watched by JVMTI |
88 | JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000, // field modification is watched by JVMTI |
89 | JVM_ACC_FIELD_INTERNAL = 0x00000400, // internal field, same as JVM_ACC_ABSTRACT |
90 | JVM_ACC_FIELD_STABLE = 0x00000020, // @Stable field, same as JVM_ACC_SYNCHRONIZED and JVM_ACC_SUPER |
91 | JVM_ACC_FIELD_INITIALIZED_FINAL_UPDATE = 0x00000100, // (static) final field updated outside (class) initializer, same as JVM_ACC_NATIVE |
92 | JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE = 0x00000800, // field has generic signature |
93 | |
94 | JVM_ACC_FIELD_INTERNAL_FLAGS = JVM_ACC_FIELD_ACCESS_WATCHED | |
95 | JVM_ACC_FIELD_MODIFICATION_WATCHED | |
96 | JVM_ACC_FIELD_INTERNAL | |
97 | JVM_ACC_FIELD_STABLE | |
98 | JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE, |
99 | |
100 | // flags accepted by set_field_flags() |
101 | JVM_ACC_FIELD_FLAGS = JVM_RECOGNIZED_FIELD_MODIFIERS(JVM_ACC_PUBLIC | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC | JVM_ACC_FINAL | JVM_ACC_VOLATILE | JVM_ACC_TRANSIENT | JVM_ACC_ENUM | JVM_ACC_SYNTHETIC) | JVM_ACC_FIELD_INTERNAL_FLAGS |
102 | |
103 | }; |
104 | |
105 | |
106 | class AccessFlags { |
107 | friend class VMStructs; |
108 | private: |
109 | jint _flags; |
110 | |
111 | public: |
112 | AccessFlags() : _flags(0) {} |
113 | explicit AccessFlags(jint flags) : _flags(flags) {} |
114 | |
115 | // Java access flags |
116 | bool is_public () const { return (_flags & JVM_ACC_PUBLIC ) != 0; } |
117 | bool is_private () const { return (_flags & JVM_ACC_PRIVATE ) != 0; } |
118 | bool is_protected () const { return (_flags & JVM_ACC_PROTECTED ) != 0; } |
119 | bool is_static () const { return (_flags & JVM_ACC_STATIC ) != 0; } |
120 | bool is_final () const { return (_flags & JVM_ACC_FINAL ) != 0; } |
121 | bool is_synchronized() const { return (_flags & JVM_ACC_SYNCHRONIZED) != 0; } |
122 | bool is_super () const { return (_flags & JVM_ACC_SUPER ) != 0; } |
123 | bool is_volatile () const { return (_flags & JVM_ACC_VOLATILE ) != 0; } |
124 | bool is_transient () const { return (_flags & JVM_ACC_TRANSIENT ) != 0; } |
125 | bool is_native () const { return (_flags & JVM_ACC_NATIVE ) != 0; } |
126 | bool is_interface () const { return (_flags & JVM_ACC_INTERFACE ) != 0; } |
127 | bool is_abstract () const { return (_flags & JVM_ACC_ABSTRACT ) != 0; } |
128 | |
129 | // Attribute flags |
130 | bool is_synthetic () const { return (_flags & JVM_ACC_SYNTHETIC ) != 0; } |
131 | |
132 | // Method* flags |
133 | bool is_monitor_matching () const { return (_flags & JVM_ACC_MONITOR_MATCH ) != 0; } |
134 | bool has_monitor_bytecodes () const { return (_flags & JVM_ACC_HAS_MONITOR_BYTECODES ) != 0; } |
135 | bool has_loops () const { return (_flags & JVM_ACC_HAS_LOOPS ) != 0; } |
136 | bool loops_flag_init () const { return (_flags & JVM_ACC_LOOPS_FLAG_INIT ) != 0; } |
137 | bool queued_for_compilation () const { return (_flags & JVM_ACC_QUEUED ) != 0; } |
138 | bool is_not_c1_compilable () const { return (_flags & JVM_ACC_NOT_C1_COMPILABLE ) != 0; } |
139 | bool is_not_c2_compilable () const { return (_flags & JVM_ACC_NOT_C2_COMPILABLE ) != 0; } |
140 | bool is_not_c2_osr_compilable() const { return (_flags & JVM_ACC_NOT_C2_OSR_COMPILABLE ) != 0; } |
141 | bool has_linenumber_table () const { return (_flags & JVM_ACC_HAS_LINE_NUMBER_TABLE ) != 0; } |
142 | bool has_checked_exceptions () const { return (_flags & JVM_ACC_HAS_CHECKED_EXCEPTIONS ) != 0; } |
143 | bool has_jsrs () const { return (_flags & JVM_ACC_HAS_JSRS ) != 0; } |
144 | bool is_old () const { return (_flags & JVM_ACC_IS_OLD ) != 0; } |
145 | bool is_obsolete () const { return (_flags & JVM_ACC_IS_OBSOLETE ) != 0; } |
146 | bool is_deleted () const { return (_flags & JVM_ACC_IS_DELETED ) != 0; } |
147 | bool is_prefixed_native () const { return (_flags & JVM_ACC_IS_PREFIXED_NATIVE ) != 0; } |
148 | |
149 | // Klass* flags |
150 | bool has_miranda_methods () const { return (_flags & JVM_ACC_HAS_MIRANDA_METHODS ) != 0; } |
151 | bool has_vanilla_constructor () const { return (_flags & JVM_ACC_HAS_VANILLA_CONSTRUCTOR) != 0; } |
152 | bool has_finalizer () const { return (_flags & JVM_ACC_HAS_FINALIZER ) != 0; } |
153 | bool has_final_method () const { return (_flags & JVM_ACC_HAS_FINAL_METHOD ) != 0; } |
154 | bool is_cloneable_fast () const { return (_flags & JVM_ACC_IS_CLONEABLE_FAST ) != 0; } |
155 | bool is_shared_class () const { return (_flags & JVM_ACC_IS_SHARED_CLASS ) != 0; } |
156 | bool is_hidden_class () const { return (_flags & JVM_ACC_IS_HIDDEN_CLASS ) != 0; } |
157 | bool is_value_based_class () const { return (_flags & JVM_ACC_IS_VALUE_BASED_CLASS ) != 0; } |
158 | |
159 | // Klass* and Method* flags |
160 | bool has_localvariable_table () const { return (_flags & JVM_ACC_HAS_LOCAL_VARIABLE_TABLE) != 0; } |
161 | void set_has_localvariable_table() { atomic_set_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); } |
162 | void clear_has_localvariable_table() { atomic_clear_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); } |
163 | |
164 | bool is_being_redefined() const { return (_flags & JVM_ACC_IS_BEING_REDEFINED) != 0; } |
165 | void set_is_being_redefined() { atomic_set_bits(JVM_ACC_IS_BEING_REDEFINED); } |
166 | void clear_is_being_redefined() { atomic_clear_bits(JVM_ACC_IS_BEING_REDEFINED); } |
167 | |
168 | bool has_resolved_methods() const { return (_flags & JVM_ACC_HAS_RESOLVED_METHODS) != 0; } |
169 | void set_has_resolved_methods() { atomic_set_bits(JVM_ACC_HAS_RESOLVED_METHODS); } |
170 | |
171 | // field flags |
172 | bool is_field_access_watched() const { return (_flags & JVM_ACC_FIELD_ACCESS_WATCHED) != 0; } |
173 | bool is_field_modification_watched() const |
174 | { return (_flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; } |
175 | bool has_field_initialized_final_update() const |
176 | { return (_flags & JVM_ACC_FIELD_INITIALIZED_FINAL_UPDATE) != 0; } |
177 | bool on_stack() const { return (_flags & JVM_ACC_ON_STACK) != 0; } |
178 | bool is_internal() const { return (_flags & JVM_ACC_FIELD_INTERNAL) != 0; } |
179 | bool is_stable() const { return (_flags & JVM_ACC_FIELD_STABLE) != 0; } |
180 | bool field_has_generic_signature() const |
181 | { return (_flags & JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE) != 0; } |
182 | |
183 | // get .class file flags |
184 | jint get_flags () const { return (_flags & JVM_ACC_WRITTEN_FLAGS); } |
185 | |
186 | // Initialization |
187 | void add_promoted_flags(jint flags) { _flags |= (flags & JVM_ACC_PROMOTED_FLAGS); } |
188 | void set_field_flags(jint flags) { |
189 | assert((flags & JVM_ACC_FIELD_FLAGS) == flags, "only recognized flags")do { if (!((flags & JVM_ACC_FIELD_FLAGS) == flags)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/accessFlags.hpp" , 189, "assert(" "(flags & JVM_ACC_FIELD_FLAGS) == flags" ") failed", "only recognized flags"); ::breakpoint(); } } while (0); |
190 | _flags = (flags & JVM_ACC_FIELD_FLAGS); |
191 | } |
192 | void set_flags(jint flags) { _flags = (flags & JVM_ACC_WRITTEN_FLAGS); } |
193 | |
194 | void set_queued_for_compilation() { atomic_set_bits(JVM_ACC_QUEUED); } |
195 | void clear_queued_for_compilation() { atomic_clear_bits(JVM_ACC_QUEUED); } |
196 | |
197 | // Atomic update of flags |
198 | void atomic_set_bits(jint bits); |
199 | void atomic_clear_bits(jint bits); |
200 | |
201 | private: |
202 | friend class Method; |
203 | friend class Klass; |
204 | friend class ClassFileParser; |
205 | // the functions below should only be called on the _access_flags inst var directly, |
206 | // otherwise they are just changing a copy of the flags |
207 | |
208 | // attribute flags |
209 | void set_is_synthetic() { atomic_set_bits(JVM_ACC_SYNTHETIC); } |
210 | |
211 | // Method* flags |
212 | void set_monitor_matching() { atomic_set_bits(JVM_ACC_MONITOR_MATCH); } |
213 | void set_has_monitor_bytecodes() { atomic_set_bits(JVM_ACC_HAS_MONITOR_BYTECODES); } |
214 | void set_has_loops() { atomic_set_bits(JVM_ACC_HAS_LOOPS); } |
215 | void set_loops_flag_init() { atomic_set_bits(JVM_ACC_LOOPS_FLAG_INIT); } |
216 | void set_not_c1_compilable() { atomic_set_bits(JVM_ACC_NOT_C1_COMPILABLE); } |
217 | void set_not_c2_compilable() { atomic_set_bits(JVM_ACC_NOT_C2_COMPILABLE); } |
218 | void set_not_c2_osr_compilable() { atomic_set_bits(JVM_ACC_NOT_C2_OSR_COMPILABLE); } |
219 | void set_has_linenumber_table() { atomic_set_bits(JVM_ACC_HAS_LINE_NUMBER_TABLE); } |
220 | void set_has_checked_exceptions() { atomic_set_bits(JVM_ACC_HAS_CHECKED_EXCEPTIONS); } |
221 | void set_has_jsrs() { atomic_set_bits(JVM_ACC_HAS_JSRS); } |
222 | void set_is_old() { atomic_set_bits(JVM_ACC_IS_OLD); } |
223 | void set_is_obsolete() { atomic_set_bits(JVM_ACC_IS_OBSOLETE); } |
224 | void set_is_deleted() { atomic_set_bits(JVM_ACC_IS_DELETED); } |
225 | void set_is_prefixed_native() { atomic_set_bits(JVM_ACC_IS_PREFIXED_NATIVE); } |
226 | |
227 | void clear_not_c1_compilable() { atomic_clear_bits(JVM_ACC_NOT_C1_COMPILABLE); } |
228 | void clear_not_c2_compilable() { atomic_clear_bits(JVM_ACC_NOT_C2_COMPILABLE); } |
229 | void clear_not_c2_osr_compilable() { atomic_clear_bits(JVM_ACC_NOT_C2_OSR_COMPILABLE); } |
230 | // Klass* flags |
231 | void set_has_vanilla_constructor() { atomic_set_bits(JVM_ACC_HAS_VANILLA_CONSTRUCTOR); } |
232 | void set_has_finalizer() { atomic_set_bits(JVM_ACC_HAS_FINALIZER); } |
233 | void set_has_final_method() { atomic_set_bits(JVM_ACC_HAS_FINAL_METHOD); } |
234 | void set_is_cloneable_fast() { atomic_set_bits(JVM_ACC_IS_CLONEABLE_FAST); } |
235 | void set_has_miranda_methods() { atomic_set_bits(JVM_ACC_HAS_MIRANDA_METHODS); } |
236 | void set_is_shared_class() { atomic_set_bits(JVM_ACC_IS_SHARED_CLASS); } |
237 | void set_is_hidden_class() { atomic_set_bits(JVM_ACC_IS_HIDDEN_CLASS); } |
238 | void set_is_value_based_class() { atomic_set_bits(JVM_ACC_IS_VALUE_BASED_CLASS); } |
239 | |
240 | public: |
241 | // field flags |
242 | void set_is_field_access_watched(const bool value) |
243 | { |
244 | if (value) { |
245 | atomic_set_bits(JVM_ACC_FIELD_ACCESS_WATCHED); |
246 | } else { |
247 | atomic_clear_bits(JVM_ACC_FIELD_ACCESS_WATCHED); |
248 | } |
249 | } |
250 | void set_is_field_modification_watched(const bool value) |
251 | { |
252 | if (value) { |
253 | atomic_set_bits(JVM_ACC_FIELD_MODIFICATION_WATCHED); |
254 | } else { |
255 | atomic_clear_bits(JVM_ACC_FIELD_MODIFICATION_WATCHED); |
256 | } |
257 | } |
258 | |
259 | void set_has_field_initialized_final_update(const bool value) { |
260 | if (value) { |
261 | atomic_set_bits(JVM_ACC_FIELD_INITIALIZED_FINAL_UPDATE); |
262 | } else { |
263 | atomic_clear_bits(JVM_ACC_FIELD_INITIALIZED_FINAL_UPDATE); |
264 | } |
265 | } |
266 | |
267 | void set_field_has_generic_signature() |
268 | { |
269 | atomic_set_bits(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE); |
270 | } |
271 | |
272 | void set_on_stack(const bool value) |
273 | { |
274 | if (value) { |
275 | atomic_set_bits(JVM_ACC_ON_STACK); |
276 | } else { |
277 | atomic_clear_bits(JVM_ACC_ON_STACK); |
278 | } |
279 | } |
280 | // Conversion |
281 | jshort as_short() const { return (jshort)_flags; } |
282 | jint as_int() const { return _flags; } |
283 | |
284 | inline friend AccessFlags accessFlags_from(jint flags); |
285 | |
286 | // Printing/debugging |
287 | #if INCLUDE_JVMTI1 |
288 | void print_on(outputStream* st) const; |
289 | #else |
290 | void print_on(outputStream* st) const PRODUCT_RETURN; |
291 | #endif |
292 | }; |
293 | |
294 | inline AccessFlags accessFlags_from(jint flags) { |
295 | AccessFlags af; |
296 | af._flags = flags; |
297 | return af; |
298 | } |
299 | |
300 | #endif // SHARE_UTILITIES_ACCESSFLAGS_HPP |