1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/classfile/classLoader.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,309 @@ 1.4 +/* 1.5 + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +// The VM class loader. 1.29 +#include <sys/stat.h> 1.30 + 1.31 + 1.32 +// Meta-index (optional, to be able to skip opening boot classpath jar files) 1.33 +class MetaIndex: public CHeapObj { 1.34 + private: 1.35 + char** _meta_package_names; 1.36 + int _num_meta_package_names; 1.37 + public: 1.38 + MetaIndex(char** meta_package_names, int num_meta_package_names); 1.39 + ~MetaIndex(); 1.40 + bool may_contain(const char* class_name); 1.41 +}; 1.42 + 1.43 + 1.44 +// Class path entry (directory or zip file) 1.45 + 1.46 +class ClassPathEntry: public CHeapObj { 1.47 + private: 1.48 + ClassPathEntry* _next; 1.49 + public: 1.50 + // Next entry in class path 1.51 + ClassPathEntry* next() { return _next; } 1.52 + void set_next(ClassPathEntry* next) { 1.53 + // may have unlocked readers, so write atomically. 1.54 + OrderAccess::release_store_ptr(&_next, next); 1.55 + } 1.56 + virtual bool is_jar_file() = 0; 1.57 + virtual const char* name() = 0; 1.58 + virtual bool is_lazy(); 1.59 + // Constructor 1.60 + ClassPathEntry(); 1.61 + // Attempt to locate file_name through this class path entry. 1.62 + // Returns a class file parsing stream if successfull. 1.63 + virtual ClassFileStream* open_stream(const char* name) = 0; 1.64 + // Debugging 1.65 + NOT_PRODUCT(virtual void compile_the_world(Handle loader, TRAPS) = 0;) 1.66 + NOT_PRODUCT(virtual bool is_rt_jar() = 0;) 1.67 +}; 1.68 + 1.69 + 1.70 +class ClassPathDirEntry: public ClassPathEntry { 1.71 + private: 1.72 + char* _dir; // Name of directory 1.73 + public: 1.74 + bool is_jar_file() { return false; } 1.75 + const char* name() { return _dir; } 1.76 + ClassPathDirEntry(char* dir); 1.77 + ClassFileStream* open_stream(const char* name); 1.78 + // Debugging 1.79 + NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);) 1.80 + NOT_PRODUCT(bool is_rt_jar();) 1.81 +}; 1.82 + 1.83 + 1.84 +// Type definitions for zip file and zip file entry 1.85 +typedef void* jzfile; 1.86 +typedef struct { 1.87 + char *name; /* entry name */ 1.88 + jlong time; /* modification time */ 1.89 + jlong size; /* size of uncompressed data */ 1.90 + jlong csize; /* size of compressed data (zero if uncompressed) */ 1.91 + jint crc; /* crc of uncompressed data */ 1.92 + char *comment; /* optional zip file comment */ 1.93 + jbyte *extra; /* optional extra data */ 1.94 + jlong pos; /* position of LOC header (if negative) or data */ 1.95 +} jzentry; 1.96 + 1.97 + 1.98 +class ClassPathZipEntry: public ClassPathEntry { 1.99 + private: 1.100 + jzfile* _zip; // The zip archive 1.101 + char* _zip_name; // Name of zip archive 1.102 + public: 1.103 + bool is_jar_file() { return true; } 1.104 + const char* name() { return _zip_name; } 1.105 + ClassPathZipEntry(jzfile* zip, const char* zip_name); 1.106 + ~ClassPathZipEntry(); 1.107 + ClassFileStream* open_stream(const char* name); 1.108 + void contents_do(void f(const char* name, void* context), void* context); 1.109 + // Debugging 1.110 + NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);) 1.111 + NOT_PRODUCT(void compile_the_world12(Handle loader, TRAPS);) // JDK 1.2 version 1.112 + NOT_PRODUCT(void compile_the_world13(Handle loader, TRAPS);) // JDK 1.3 version 1.113 + NOT_PRODUCT(bool is_rt_jar();) 1.114 + NOT_PRODUCT(bool is_rt_jar12();) 1.115 + NOT_PRODUCT(bool is_rt_jar13();) 1.116 +}; 1.117 + 1.118 + 1.119 +// For lazier loading of boot class path entries 1.120 +class LazyClassPathEntry: public ClassPathEntry { 1.121 + private: 1.122 + char* _path; // dir or file 1.123 + struct stat _st; 1.124 + MetaIndex* _meta_index; 1.125 + volatile ClassPathEntry* _resolved_entry; 1.126 + ClassPathEntry* resolve_entry(); 1.127 + public: 1.128 + bool is_jar_file(); 1.129 + const char* name() { return _path; } 1.130 + LazyClassPathEntry(char* path, struct stat st); 1.131 + ClassFileStream* open_stream(const char* name); 1.132 + void set_meta_index(MetaIndex* meta_index) { _meta_index = meta_index; } 1.133 + virtual bool is_lazy(); 1.134 + // Debugging 1.135 + NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);) 1.136 + NOT_PRODUCT(bool is_rt_jar();) 1.137 +}; 1.138 + 1.139 +class PackageHashtable; 1.140 +class PackageInfo; 1.141 +class HashtableBucket; 1.142 + 1.143 +class ClassLoader: AllStatic { 1.144 + public: 1.145 + enum SomeConstants { 1.146 + package_hash_table_size = 31 // Number of buckets 1.147 + }; 1.148 + private: 1.149 + friend class LazyClassPathEntry; 1.150 + 1.151 + // Performance counters 1.152 + static PerfCounter* _perf_accumulated_time; 1.153 + static PerfCounter* _perf_classes_inited; 1.154 + static PerfCounter* _perf_class_init_time; 1.155 + static PerfCounter* _perf_class_verify_time; 1.156 + static PerfCounter* _perf_classes_linked; 1.157 + static PerfCounter* _perf_class_link_time; 1.158 + 1.159 + static PerfCounter* _sync_systemLoaderLockContentionRate; 1.160 + static PerfCounter* _sync_nonSystemLoaderLockContentionRate; 1.161 + static PerfCounter* _sync_JVMFindLoadedClassLockFreeCounter; 1.162 + static PerfCounter* _sync_JVMDefineClassLockFreeCounter; 1.163 + static PerfCounter* _sync_JNIDefineClassLockFreeCounter; 1.164 + 1.165 + static PerfCounter* _unsafe_defineClassCallCounter; 1.166 + static PerfCounter* _isUnsyncloadClass; 1.167 + static PerfCounter* _load_instance_class_failCounter; 1.168 + 1.169 + // First entry in linked list of ClassPathEntry instances 1.170 + static ClassPathEntry* _first_entry; 1.171 + // Last entry in linked list of ClassPathEntry instances 1.172 + static ClassPathEntry* _last_entry; 1.173 + // Hash table used to keep track of loaded packages 1.174 + static PackageHashtable* _package_hash_table; 1.175 + static const char* _shared_archive; 1.176 + 1.177 + // Hash function 1.178 + static unsigned int hash(const char *s, int n); 1.179 + // Returns the package file name corresponding to the specified package 1.180 + // or class name, or null if not found. 1.181 + static PackageInfo* lookup_package(const char *pkgname); 1.182 + // Adds a new package entry for the specified class or package name and 1.183 + // corresponding directory or jar file name. 1.184 + static bool add_package(const char *pkgname, int classpath_index, TRAPS); 1.185 + 1.186 + // Initialization 1.187 + static void setup_meta_index(); 1.188 + static void setup_bootstrap_search_path(); 1.189 + static void load_zip_library(); 1.190 + static void create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy); 1.191 + 1.192 + // Canonicalizes path names, so strcmp will work properly. This is mainly 1.193 + // to avoid confusing the zip library 1.194 + static bool get_canonical_path(char* orig, char* out, int len); 1.195 + public: 1.196 + // Used by the kernel jvm. 1.197 + static void update_class_path_entry_list(const char *path, 1.198 + bool check_for_duplicates); 1.199 + static void print_bootclasspath(); 1.200 + 1.201 + // Timing 1.202 + static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; } 1.203 + static PerfCounter* perf_classes_inited() { return _perf_classes_inited; } 1.204 + static PerfCounter* perf_class_init_time() { return _perf_class_init_time; } 1.205 + static PerfCounter* perf_class_verify_time() { return _perf_class_verify_time; } 1.206 + static PerfCounter* perf_classes_linked() { return _perf_classes_linked; } 1.207 + static PerfCounter* perf_class_link_time() { return _perf_class_link_time; } 1.208 + 1.209 + // Record how often system loader lock object is contended 1.210 + static PerfCounter* sync_systemLoaderLockContentionRate() { 1.211 + return _sync_systemLoaderLockContentionRate; 1.212 + } 1.213 + 1.214 + // Record how often non system loader lock object is contended 1.215 + static PerfCounter* sync_nonSystemLoaderLockContentionRate() { 1.216 + return _sync_nonSystemLoaderLockContentionRate; 1.217 + } 1.218 + 1.219 + // Record how many calls to JVM_FindLoadedClass w/o holding a lock 1.220 + static PerfCounter* sync_JVMFindLoadedClassLockFreeCounter() { 1.221 + return _sync_JVMFindLoadedClassLockFreeCounter; 1.222 + } 1.223 + 1.224 + // Record how many calls to JVM_DefineClass w/o holding a lock 1.225 + static PerfCounter* sync_JVMDefineClassLockFreeCounter() { 1.226 + return _sync_JVMDefineClassLockFreeCounter; 1.227 + } 1.228 + 1.229 + // Record how many calls to jni_DefineClass w/o holding a lock 1.230 + static PerfCounter* sync_JNIDefineClassLockFreeCounter() { 1.231 + return _sync_JNIDefineClassLockFreeCounter; 1.232 + } 1.233 + 1.234 + // Record how many calls to Unsafe_DefineClass 1.235 + static PerfCounter* unsafe_defineClassCallCounter() { 1.236 + return _unsafe_defineClassCallCounter; 1.237 + } 1.238 + 1.239 + // Record how many times SystemDictionary::load_instance_class call 1.240 + // fails with linkageError when Unsyncloadclass flag is set. 1.241 + static PerfCounter* load_instance_class_failCounter() { 1.242 + return _load_instance_class_failCounter; 1.243 + } 1.244 + 1.245 + // Load individual .class file 1.246 + static instanceKlassHandle load_classfile(symbolHandle h_name, TRAPS); 1.247 + 1.248 + // If the specified package has been loaded by the system, then returns 1.249 + // the name of the directory or ZIP file that the package was loaded from. 1.250 + // Returns null if the package was not loaded. 1.251 + // Note: The specified name can either be the name of a class or package. 1.252 + // If a package name is specified, then it must be "/"-separator and also 1.253 + // end with a trailing "/". 1.254 + static oop get_system_package(const char* name, TRAPS); 1.255 + 1.256 + // Returns an array of Java strings representing all of the currently 1.257 + // loaded system packages. 1.258 + // Note: The package names returned are "/"-separated and end with a 1.259 + // trailing "/". 1.260 + static objArrayOop get_system_packages(TRAPS); 1.261 + 1.262 + // Initialization 1.263 + static void initialize(); 1.264 + static void create_package_info_table(); 1.265 + static void create_package_info_table(HashtableBucket *t, int length, 1.266 + int number_of_entries); 1.267 + static int compute_Object_vtable(); 1.268 + 1.269 + static ClassPathEntry* classpath_entry(int n) { 1.270 + ClassPathEntry* e = ClassLoader::_first_entry; 1.271 + while (--n >= 0) { 1.272 + assert(e != NULL, "Not that many classpath entries."); 1.273 + e = e->next(); 1.274 + } 1.275 + return e; 1.276 + } 1.277 + 1.278 + // Sharing dump and restore 1.279 + static void copy_package_info_buckets(char** top, char* end); 1.280 + static void copy_package_info_table(char** top, char* end); 1.281 + 1.282 + // VM monitoring and management support 1.283 + static jlong classloader_time_ms(); 1.284 + static jlong class_method_total_size(); 1.285 + static jlong class_init_count(); 1.286 + static jlong class_init_time_ms(); 1.287 + static jlong class_verify_time_ms(); 1.288 + static jlong class_link_count(); 1.289 + static jlong class_link_time_ms(); 1.290 + 1.291 + // indicates if class path already contains a entry (exact match by name) 1.292 + static bool contains_entry(ClassPathEntry* entry); 1.293 + 1.294 + // adds a class path list 1.295 + static void add_to_list(ClassPathEntry* new_entry); 1.296 + 1.297 + // creates a class path zip entry (returns NULL if JAR file cannot be opened) 1.298 + static ClassPathZipEntry* create_class_path_zip_entry(const char *apath); 1.299 + 1.300 + // Debugging 1.301 + static void verify() PRODUCT_RETURN; 1.302 + 1.303 + // Force compilation of all methods in all classes in bootstrap class path (stress test) 1.304 +#ifndef PRODUCT 1.305 + private: 1.306 + static int _compile_the_world_counter; 1.307 + public: 1.308 + static void compile_the_world(); 1.309 + static void compile_the_world_in(char* name, Handle loader, TRAPS); 1.310 + static int compile_the_world_counter() { return _compile_the_world_counter; } 1.311 +#endif //PRODUCT 1.312 +};