| 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 |