Mercurial > hg > graal-compiler
annotate src/share/vm/classfile/classLoader.cpp @ 2607:008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
This is necessary to ensure correct continuation in the interpreter when the stateBefore is used as a deoptimization point.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Fri, 06 May 2011 17:47:17 +0200 |
parents | 0654ee04b214 |
children | 4aa80ca3dbec |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2323
diff
changeset
|
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1188
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1188
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1188
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/classFileParser.hpp" | |
27 #include "classfile/classFileStream.hpp" | |
28 #include "classfile/classLoader.hpp" | |
29 #include "classfile/javaClasses.hpp" | |
30 #include "classfile/systemDictionary.hpp" | |
31 #include "classfile/vmSymbols.hpp" | |
32 #include "compiler/compileBroker.hpp" | |
33 #include "gc_interface/collectedHeap.inline.hpp" | |
34 #include "interpreter/bytecodeStream.hpp" | |
35 #include "interpreter/oopMapCache.hpp" | |
36 #include "memory/allocation.inline.hpp" | |
37 #include "memory/generation.hpp" | |
38 #include "memory/oopFactory.hpp" | |
39 #include "memory/universe.inline.hpp" | |
40 #include "oops/constantPoolKlass.hpp" | |
41 #include "oops/instanceKlass.hpp" | |
42 #include "oops/instanceRefKlass.hpp" | |
43 #include "oops/oop.inline.hpp" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2139
diff
changeset
|
44 #include "oops/symbol.hpp" |
1972 | 45 #include "prims/jvm_misc.hpp" |
46 #include "runtime/arguments.hpp" | |
47 #include "runtime/compilationPolicy.hpp" | |
48 #include "runtime/fprofiler.hpp" | |
49 #include "runtime/handles.hpp" | |
50 #include "runtime/handles.inline.hpp" | |
51 #include "runtime/init.hpp" | |
52 #include "runtime/interfaceSupport.hpp" | |
53 #include "runtime/java.hpp" | |
54 #include "runtime/javaCalls.hpp" | |
55 #include "runtime/threadCritical.hpp" | |
56 #include "runtime/timer.hpp" | |
57 #include "services/management.hpp" | |
58 #include "services/threadService.hpp" | |
59 #include "utilities/events.hpp" | |
60 #include "utilities/hashtable.hpp" | |
61 #include "utilities/hashtable.inline.hpp" | |
62 #ifdef TARGET_OS_FAMILY_linux | |
63 # include "os_linux.inline.hpp" | |
64 #endif | |
65 #ifdef TARGET_OS_FAMILY_solaris | |
66 # include "os_solaris.inline.hpp" | |
67 #endif | |
68 #ifdef TARGET_OS_FAMILY_windows | |
69 # include "os_windows.inline.hpp" | |
70 #endif | |
0 | 71 |
72 | |
73 // Entry points in zip.dll for loading zip/jar file entries | |
74 | |
75 typedef void * * (JNICALL *ZipOpen_t)(const char *name, char **pmsg); | |
76 typedef void (JNICALL *ZipClose_t)(jzfile *zip); | |
77 typedef jzentry* (JNICALL *FindEntry_t)(jzfile *zip, const char *name, jint *sizeP, jint *nameLen); | |
78 typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf); | |
79 typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsigned char **buf, char *namebuf); | |
80 typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n); | |
81 | |
82 static ZipOpen_t ZipOpen = NULL; | |
83 static ZipClose_t ZipClose = NULL; | |
84 static FindEntry_t FindEntry = NULL; | |
85 static ReadEntry_t ReadEntry = NULL; | |
86 static ReadMappedEntry_t ReadMappedEntry = NULL; | |
87 static GetNextEntry_t GetNextEntry = NULL; | |
88 static canonicalize_fn_t CanonicalizeEntry = NULL; | |
89 | |
90 // Globals | |
91 | |
92 PerfCounter* ClassLoader::_perf_accumulated_time = NULL; | |
93 PerfCounter* ClassLoader::_perf_classes_inited = NULL; | |
94 PerfCounter* ClassLoader::_perf_class_init_time = NULL; | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
95 PerfCounter* ClassLoader::_perf_class_init_selftime = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
96 PerfCounter* ClassLoader::_perf_classes_verified = NULL; |
0 | 97 PerfCounter* ClassLoader::_perf_class_verify_time = NULL; |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
98 PerfCounter* ClassLoader::_perf_class_verify_selftime = NULL; |
0 | 99 PerfCounter* ClassLoader::_perf_classes_linked = NULL; |
100 PerfCounter* ClassLoader::_perf_class_link_time = NULL; | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
101 PerfCounter* ClassLoader::_perf_class_link_selftime = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
102 PerfCounter* ClassLoader::_perf_class_parse_time = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
103 PerfCounter* ClassLoader::_perf_class_parse_selftime = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
104 PerfCounter* ClassLoader::_perf_sys_class_lookup_time = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
105 PerfCounter* ClassLoader::_perf_shared_classload_time = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
106 PerfCounter* ClassLoader::_perf_sys_classload_time = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
107 PerfCounter* ClassLoader::_perf_app_classload_time = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
108 PerfCounter* ClassLoader::_perf_app_classload_selftime = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
109 PerfCounter* ClassLoader::_perf_app_classload_count = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
110 PerfCounter* ClassLoader::_perf_define_appclasses = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
111 PerfCounter* ClassLoader::_perf_define_appclass_time = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
112 PerfCounter* ClassLoader::_perf_define_appclass_selftime = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
113 PerfCounter* ClassLoader::_perf_app_classfile_bytes_read = NULL; |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
114 PerfCounter* ClassLoader::_perf_sys_classfile_bytes_read = NULL; |
0 | 115 PerfCounter* ClassLoader::_sync_systemLoaderLockContentionRate = NULL; |
116 PerfCounter* ClassLoader::_sync_nonSystemLoaderLockContentionRate = NULL; | |
117 PerfCounter* ClassLoader::_sync_JVMFindLoadedClassLockFreeCounter = NULL; | |
118 PerfCounter* ClassLoader::_sync_JVMDefineClassLockFreeCounter = NULL; | |
119 PerfCounter* ClassLoader::_sync_JNIDefineClassLockFreeCounter = NULL; | |
120 PerfCounter* ClassLoader::_unsafe_defineClassCallCounter = NULL; | |
121 PerfCounter* ClassLoader::_isUnsyncloadClass = NULL; | |
122 PerfCounter* ClassLoader::_load_instance_class_failCounter = NULL; | |
123 | |
124 ClassPathEntry* ClassLoader::_first_entry = NULL; | |
125 ClassPathEntry* ClassLoader::_last_entry = NULL; | |
126 PackageHashtable* ClassLoader::_package_hash_table = NULL; | |
127 | |
128 // helper routines | |
129 bool string_starts_with(const char* str, const char* str_to_find) { | |
130 size_t str_len = strlen(str); | |
131 size_t str_to_find_len = strlen(str_to_find); | |
132 if (str_to_find_len > str_len) { | |
133 return false; | |
134 } | |
135 return (strncmp(str, str_to_find, str_to_find_len) == 0); | |
136 } | |
137 | |
138 bool string_ends_with(const char* str, const char* str_to_find) { | |
139 size_t str_len = strlen(str); | |
140 size_t str_to_find_len = strlen(str_to_find); | |
141 if (str_to_find_len > str_len) { | |
142 return false; | |
143 } | |
144 return (strncmp(str + (str_len - str_to_find_len), str_to_find, str_to_find_len) == 0); | |
145 } | |
146 | |
147 | |
148 MetaIndex::MetaIndex(char** meta_package_names, int num_meta_package_names) { | |
149 if (num_meta_package_names == 0) { | |
150 _meta_package_names = NULL; | |
151 _num_meta_package_names = 0; | |
152 } else { | |
153 _meta_package_names = NEW_C_HEAP_ARRAY(char*, num_meta_package_names); | |
154 _num_meta_package_names = num_meta_package_names; | |
155 memcpy(_meta_package_names, meta_package_names, num_meta_package_names * sizeof(char*)); | |
156 } | |
157 } | |
158 | |
159 | |
160 MetaIndex::~MetaIndex() { | |
161 FREE_C_HEAP_ARRAY(char*, _meta_package_names); | |
162 } | |
163 | |
164 | |
165 bool MetaIndex::may_contain(const char* class_name) { | |
166 if ( _num_meta_package_names == 0) { | |
167 return false; | |
168 } | |
169 size_t class_name_len = strlen(class_name); | |
170 for (int i = 0; i < _num_meta_package_names; i++) { | |
171 char* pkg = _meta_package_names[i]; | |
172 size_t pkg_len = strlen(pkg); | |
173 size_t min_len = MIN2(class_name_len, pkg_len); | |
174 if (!strncmp(class_name, pkg, min_len)) { | |
175 return true; | |
176 } | |
177 } | |
178 return false; | |
179 } | |
180 | |
181 | |
182 ClassPathEntry::ClassPathEntry() { | |
183 set_next(NULL); | |
184 } | |
185 | |
186 | |
187 bool ClassPathEntry::is_lazy() { | |
188 return false; | |
189 } | |
190 | |
191 ClassPathDirEntry::ClassPathDirEntry(char* dir) : ClassPathEntry() { | |
192 _dir = NEW_C_HEAP_ARRAY(char, strlen(dir)+1); | |
193 strcpy(_dir, dir); | |
194 } | |
195 | |
196 | |
197 ClassFileStream* ClassPathDirEntry::open_stream(const char* name) { | |
198 // construct full path name | |
199 char path[JVM_MAXPATHLEN]; | |
200 if (jio_snprintf(path, sizeof(path), "%s%s%s", _dir, os::file_separator(), name) == -1) { | |
201 return NULL; | |
202 } | |
203 // check if file exists | |
204 struct stat st; | |
205 if (os::stat(path, &st) == 0) { | |
206 // found file, open it | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
207 int file_handle = os::open(path, 0, 0); |
0 | 208 if (file_handle != -1) { |
209 // read contents into resource array | |
210 u1* buffer = NEW_RESOURCE_ARRAY(u1, st.st_size); | |
211 size_t num_read = os::read(file_handle, (char*) buffer, st.st_size); | |
212 // close file | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
213 os::close(file_handle); |
0 | 214 // construct ClassFileStream |
215 if (num_read == (size_t)st.st_size) { | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
216 if (UsePerfData) { |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
217 ClassLoader::perf_sys_classfile_bytes_read()->inc(num_read); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
218 } |
0 | 219 return new ClassFileStream(buffer, st.st_size, _dir); // Resource allocated |
220 } | |
221 } | |
222 } | |
223 return NULL; | |
224 } | |
225 | |
226 | |
227 ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name) : ClassPathEntry() { | |
228 _zip = zip; | |
229 _zip_name = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1); | |
230 strcpy(_zip_name, zip_name); | |
231 } | |
232 | |
233 ClassPathZipEntry::~ClassPathZipEntry() { | |
234 if (ZipClose != NULL) { | |
235 (*ZipClose)(_zip); | |
236 } | |
237 FREE_C_HEAP_ARRAY(char, _zip_name); | |
238 } | |
239 | |
240 ClassFileStream* ClassPathZipEntry::open_stream(const char* name) { | |
241 // enable call to C land | |
242 JavaThread* thread = JavaThread::current(); | |
243 ThreadToNativeFromVM ttn(thread); | |
244 // check whether zip archive contains name | |
245 jint filesize, name_len; | |
246 jzentry* entry = (*FindEntry)(_zip, name, &filesize, &name_len); | |
247 if (entry == NULL) return NULL; | |
248 u1* buffer; | |
249 char name_buf[128]; | |
250 char* filename; | |
251 if (name_len < 128) { | |
252 filename = name_buf; | |
253 } else { | |
254 filename = NEW_RESOURCE_ARRAY(char, name_len + 1); | |
255 } | |
256 | |
257 // file found, get pointer to class in mmaped jar file. | |
258 if (ReadMappedEntry == NULL || | |
259 !(*ReadMappedEntry)(_zip, entry, &buffer, filename)) { | |
260 // mmaped access not available, perhaps due to compression, | |
261 // read contents into resource array | |
262 buffer = NEW_RESOURCE_ARRAY(u1, filesize); | |
263 if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL; | |
264 } | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
265 if (UsePerfData) { |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
266 ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
267 } |
0 | 268 // return result |
269 return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated | |
270 } | |
271 | |
272 // invoke function for each entry in the zip file | |
273 void ClassPathZipEntry::contents_do(void f(const char* name, void* context), void* context) { | |
274 JavaThread* thread = JavaThread::current(); | |
275 HandleMark handle_mark(thread); | |
276 ThreadToNativeFromVM ttn(thread); | |
277 for (int n = 0; ; n++) { | |
278 jzentry * ze = ((*GetNextEntry)(_zip, n)); | |
279 if (ze == NULL) break; | |
280 (*f)(ze->name, context); | |
281 } | |
282 } | |
283 | |
284 LazyClassPathEntry::LazyClassPathEntry(char* path, struct stat st) : ClassPathEntry() { | |
285 _path = strdup(path); | |
286 _st = st; | |
287 _meta_index = NULL; | |
288 _resolved_entry = NULL; | |
289 } | |
290 | |
291 bool LazyClassPathEntry::is_jar_file() { | |
292 return ((_st.st_mode & S_IFREG) == S_IFREG); | |
293 } | |
294 | |
295 ClassPathEntry* LazyClassPathEntry::resolve_entry() { | |
296 if (_resolved_entry != NULL) { | |
297 return (ClassPathEntry*) _resolved_entry; | |
298 } | |
299 ClassPathEntry* new_entry = NULL; | |
300 ClassLoader::create_class_path_entry(_path, _st, &new_entry, false); | |
301 assert(new_entry != NULL, "earlier code should have caught this"); | |
302 { | |
303 ThreadCritical tc; | |
304 if (_resolved_entry == NULL) { | |
305 _resolved_entry = new_entry; | |
306 return new_entry; | |
307 } | |
308 } | |
309 assert(_resolved_entry != NULL, "bug in MT-safe resolution logic"); | |
310 delete new_entry; | |
311 return (ClassPathEntry*) _resolved_entry; | |
312 } | |
313 | |
314 ClassFileStream* LazyClassPathEntry::open_stream(const char* name) { | |
315 if (_meta_index != NULL && | |
316 !_meta_index->may_contain(name)) { | |
317 return NULL; | |
318 } | |
319 return resolve_entry()->open_stream(name); | |
320 } | |
321 | |
322 bool LazyClassPathEntry::is_lazy() { | |
323 return true; | |
324 } | |
325 | |
326 static void print_meta_index(LazyClassPathEntry* entry, | |
327 GrowableArray<char*>& meta_packages) { | |
328 tty->print("[Meta index for %s=", entry->name()); | |
329 for (int i = 0; i < meta_packages.length(); i++) { | |
330 if (i > 0) tty->print(" "); | |
331 tty->print(meta_packages.at(i)); | |
332 } | |
333 tty->print_cr("]"); | |
334 } | |
335 | |
336 | |
337 void ClassLoader::setup_meta_index() { | |
338 // Set up meta index which allows us to open boot jars lazily if | |
339 // class data sharing is enabled | |
340 const char* known_version = "% VERSION 2"; | |
341 char* meta_index_path = Arguments::get_meta_index_path(); | |
342 char* meta_index_dir = Arguments::get_meta_index_dir(); | |
343 FILE* file = fopen(meta_index_path, "r"); | |
344 int line_no = 0; | |
345 if (file != NULL) { | |
346 ResourceMark rm; | |
347 LazyClassPathEntry* cur_entry = NULL; | |
348 GrowableArray<char*> boot_class_path_packages(10); | |
349 char package_name[256]; | |
350 bool skipCurrentJar = false; | |
351 while (fgets(package_name, sizeof(package_name), file) != NULL) { | |
352 ++line_no; | |
353 // Remove trailing newline | |
354 package_name[strlen(package_name) - 1] = '\0'; | |
355 switch(package_name[0]) { | |
356 case '%': | |
357 { | |
358 if ((line_no == 1) && (strcmp(package_name, known_version) != 0)) { | |
359 if (TraceClassLoading && Verbose) { | |
360 tty->print("[Unsupported meta index version]"); | |
361 } | |
362 fclose(file); | |
363 return; | |
364 } | |
365 } | |
366 | |
367 // These directives indicate jar files which contain only | |
368 // classes, only non-classfile resources, or a combination of | |
369 // the two. See src/share/classes/sun/misc/MetaIndex.java and | |
370 // make/tools/MetaIndex/BuildMetaIndex.java in the J2SE | |
371 // workspace. | |
372 case '#': | |
373 case '!': | |
374 case '@': | |
375 { | |
376 // Hand off current packages to current lazy entry (if any) | |
377 if ((cur_entry != NULL) && | |
378 (boot_class_path_packages.length() > 0)) { | |
379 if (TraceClassLoading && Verbose) { | |
380 print_meta_index(cur_entry, boot_class_path_packages); | |
381 } | |
382 MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0), | |
383 boot_class_path_packages.length()); | |
384 cur_entry->set_meta_index(index); | |
385 } | |
386 cur_entry = NULL; | |
387 boot_class_path_packages.clear(); | |
388 | |
389 // Find lazy entry corresponding to this jar file | |
390 for (ClassPathEntry* entry = _first_entry; entry != NULL; entry = entry->next()) { | |
391 if (entry->is_lazy() && | |
392 string_starts_with(entry->name(), meta_index_dir) && | |
393 string_ends_with(entry->name(), &package_name[2])) { | |
394 cur_entry = (LazyClassPathEntry*) entry; | |
395 break; | |
396 } | |
397 } | |
398 | |
399 // If the first character is '@', it indicates the following jar | |
400 // file is a resource only jar file in which case, we should skip | |
401 // reading the subsequent entries since the resource loading is | |
402 // totally handled by J2SE side. | |
403 if (package_name[0] == '@') { | |
404 if (cur_entry != NULL) { | |
405 cur_entry->set_meta_index(new MetaIndex(NULL, 0)); | |
406 } | |
407 cur_entry = NULL; | |
408 skipCurrentJar = true; | |
409 } else { | |
410 skipCurrentJar = false; | |
411 } | |
412 | |
413 break; | |
414 } | |
415 | |
416 default: | |
417 { | |
418 if (!skipCurrentJar && cur_entry != NULL) { | |
419 char* new_name = strdup(package_name); | |
420 boot_class_path_packages.append(new_name); | |
421 } | |
422 } | |
423 } | |
424 } | |
425 // Hand off current packages to current lazy entry (if any) | |
426 if ((cur_entry != NULL) && | |
427 (boot_class_path_packages.length() > 0)) { | |
428 if (TraceClassLoading && Verbose) { | |
429 print_meta_index(cur_entry, boot_class_path_packages); | |
430 } | |
431 MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0), | |
432 boot_class_path_packages.length()); | |
433 cur_entry->set_meta_index(index); | |
434 } | |
435 fclose(file); | |
436 } | |
437 } | |
438 | |
439 void ClassLoader::setup_bootstrap_search_path() { | |
440 assert(_first_entry == NULL, "should not setup bootstrap class search path twice"); | |
441 char* sys_class_path = os::strdup(Arguments::get_sysclasspath()); | |
442 if (TraceClassLoading && Verbose) { | |
443 tty->print_cr("[Bootstrap loader class path=%s]", sys_class_path); | |
444 } | |
445 | |
446 int len = (int)strlen(sys_class_path); | |
447 int end = 0; | |
448 | |
449 // Iterate over class path entries | |
450 for (int start = 0; start < len; start = end) { | |
451 while (sys_class_path[end] && sys_class_path[end] != os::path_separator()[0]) { | |
452 end++; | |
453 } | |
454 char* path = NEW_C_HEAP_ARRAY(char, end-start+1); | |
455 strncpy(path, &sys_class_path[start], end-start); | |
456 path[end-start] = '\0'; | |
457 update_class_path_entry_list(path, false); | |
458 FREE_C_HEAP_ARRAY(char, path); | |
459 while (sys_class_path[end] == os::path_separator()[0]) { | |
460 end++; | |
461 } | |
462 } | |
463 } | |
464 | |
465 void ClassLoader::create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy) { | |
466 JavaThread* thread = JavaThread::current(); | |
467 if (lazy) { | |
468 *new_entry = new LazyClassPathEntry(path, st); | |
469 return; | |
470 } | |
471 if ((st.st_mode & S_IFREG) == S_IFREG) { | |
472 // Regular file, should be a zip file | |
473 // Canonicalized filename | |
474 char canonical_path[JVM_MAXPATHLEN]; | |
475 if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) { | |
476 // This matches the classic VM | |
477 EXCEPTION_MARK; | |
478 THROW_MSG(vmSymbols::java_io_IOException(), "Bad pathname"); | |
479 } | |
480 char* error_msg = NULL; | |
481 jzfile* zip; | |
482 { | |
483 // enable call to C land | |
484 ThreadToNativeFromVM ttn(thread); | |
485 HandleMark hm(thread); | |
486 zip = (*ZipOpen)(canonical_path, &error_msg); | |
487 } | |
488 if (zip != NULL && error_msg == NULL) { | |
489 *new_entry = new ClassPathZipEntry(zip, path); | |
490 if (TraceClassLoading) { | |
491 tty->print_cr("[Opened %s]", path); | |
492 } | |
493 } else { | |
494 ResourceMark rm(thread); | |
495 char *msg; | |
496 if (error_msg == NULL) { | |
497 msg = NEW_RESOURCE_ARRAY(char, strlen(path) + 128); ; | |
498 jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path); | |
499 } else { | |
500 int len = (int)(strlen(path) + strlen(error_msg) + 128); | |
501 msg = NEW_RESOURCE_ARRAY(char, len); ; | |
502 jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path); | |
503 } | |
504 EXCEPTION_MARK; | |
505 THROW_MSG(vmSymbols::java_lang_ClassNotFoundException(), msg); | |
506 } | |
507 } else { | |
508 // Directory | |
509 *new_entry = new ClassPathDirEntry(path); | |
510 if (TraceClassLoading) { | |
511 tty->print_cr("[Path %s]", path); | |
512 } | |
513 } | |
514 } | |
515 | |
516 | |
517 // Create a class path zip entry for a given path (return NULL if not found | |
518 // or zip/JAR file cannot be opened) | |
519 ClassPathZipEntry* ClassLoader::create_class_path_zip_entry(const char *path) { | |
520 // check for a regular file | |
521 struct stat st; | |
522 if (os::stat(path, &st) == 0) { | |
523 if ((st.st_mode & S_IFREG) == S_IFREG) { | |
524 char orig_path[JVM_MAXPATHLEN]; | |
525 char canonical_path[JVM_MAXPATHLEN]; | |
526 | |
527 strcpy(orig_path, path); | |
528 if (get_canonical_path(orig_path, canonical_path, JVM_MAXPATHLEN)) { | |
529 char* error_msg = NULL; | |
530 jzfile* zip; | |
531 { | |
532 // enable call to C land | |
533 JavaThread* thread = JavaThread::current(); | |
534 ThreadToNativeFromVM ttn(thread); | |
535 HandleMark hm(thread); | |
536 zip = (*ZipOpen)(canonical_path, &error_msg); | |
537 } | |
538 if (zip != NULL && error_msg == NULL) { | |
539 // create using canonical path | |
540 return new ClassPathZipEntry(zip, canonical_path); | |
541 } | |
542 } | |
543 } | |
544 } | |
545 return NULL; | |
546 } | |
547 | |
548 // returns true if entry already on class path | |
549 bool ClassLoader::contains_entry(ClassPathEntry *entry) { | |
550 ClassPathEntry* e = _first_entry; | |
551 while (e != NULL) { | |
552 // assume zip entries have been canonicalized | |
553 if (strcmp(entry->name(), e->name()) == 0) { | |
554 return true; | |
555 } | |
556 e = e->next(); | |
557 } | |
558 return false; | |
559 } | |
560 | |
561 void ClassLoader::add_to_list(ClassPathEntry *new_entry) { | |
562 if (new_entry != NULL) { | |
563 if (_last_entry == NULL) { | |
564 _first_entry = _last_entry = new_entry; | |
565 } else { | |
566 _last_entry->set_next(new_entry); | |
567 _last_entry = new_entry; | |
568 } | |
569 } | |
570 } | |
571 | |
572 void ClassLoader::update_class_path_entry_list(const char *path, | |
573 bool check_for_duplicates) { | |
574 struct stat st; | |
575 if (os::stat((char *)path, &st) == 0) { | |
576 // File or directory found | |
577 ClassPathEntry* new_entry = NULL; | |
578 create_class_path_entry((char *)path, st, &new_entry, LazyBootClassLoader); | |
579 // The kernel VM adds dynamically to the end of the classloader path and | |
580 // doesn't reorder the bootclasspath which would break java.lang.Package | |
581 // (see PackageInfo). | |
582 // Add new entry to linked list | |
583 if (!check_for_duplicates || !contains_entry(new_entry)) { | |
584 add_to_list(new_entry); | |
585 } | |
586 } | |
587 } | |
588 | |
589 void ClassLoader::print_bootclasspath() { | |
590 ClassPathEntry* e = _first_entry; | |
591 tty->print("[bootclasspath= "); | |
592 while (e != NULL) { | |
593 tty->print("%s ;", e->name()); | |
594 e = e->next(); | |
595 } | |
596 tty->print_cr("]"); | |
597 } | |
598 | |
599 void ClassLoader::load_zip_library() { | |
600 assert(ZipOpen == NULL, "should not load zip library twice"); | |
601 // First make sure native library is loaded | |
602 os::native_java_library(); | |
603 // Load zip library | |
604 char path[JVM_MAXPATHLEN]; | |
605 char ebuf[1024]; | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
606 os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "zip"); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
607 void* handle = os::dll_load(path, ebuf, sizeof ebuf); |
0 | 608 if (handle == NULL) { |
609 vm_exit_during_initialization("Unable to load ZIP library", path); | |
610 } | |
611 // Lookup zip entry points | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
612 ZipOpen = CAST_TO_FN_PTR(ZipOpen_t, os::dll_lookup(handle, "ZIP_Open")); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
613 ZipClose = CAST_TO_FN_PTR(ZipClose_t, os::dll_lookup(handle, "ZIP_Close")); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
614 FindEntry = CAST_TO_FN_PTR(FindEntry_t, os::dll_lookup(handle, "ZIP_FindEntry")); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
615 ReadEntry = CAST_TO_FN_PTR(ReadEntry_t, os::dll_lookup(handle, "ZIP_ReadEntry")); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
616 ReadMappedEntry = CAST_TO_FN_PTR(ReadMappedEntry_t, os::dll_lookup(handle, "ZIP_ReadMappedEntry")); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
617 GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry")); |
0 | 618 |
619 // ZIP_Close is not exported on Windows in JDK5.0 so don't abort if ZIP_Close is NULL | |
620 if (ZipOpen == NULL || FindEntry == NULL || ReadEntry == NULL || GetNextEntry == NULL) { | |
621 vm_exit_during_initialization("Corrupted ZIP library", path); | |
622 } | |
623 | |
624 // Lookup canonicalize entry in libjava.dll | |
625 void *javalib_handle = os::native_java_library(); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
626 CanonicalizeEntry = CAST_TO_FN_PTR(canonicalize_fn_t, os::dll_lookup(javalib_handle, "Canonicalize")); |
0 | 627 // This lookup only works on 1.3. Do not check for non-null here |
628 } | |
629 | |
630 // PackageInfo data exists in order to support the java.lang.Package | |
631 // class. A Package object provides information about a java package | |
632 // (version, vendor, etc.) which originates in the manifest of the jar | |
633 // file supplying the package. For application classes, the ClassLoader | |
634 // object takes care of this. | |
635 | |
636 // For system (boot) classes, the Java code in the Package class needs | |
637 // to be able to identify which source jar file contained the boot | |
638 // class, so that it can extract the manifest from it. This table | |
639 // identifies java packages with jar files in the boot classpath. | |
640 | |
641 // Because the boot classpath cannot change, the classpath index is | |
642 // sufficient to identify the source jar file or directory. (Since | |
643 // directories have no manifests, the directory name is not required, | |
644 // but is available.) | |
645 | |
646 // When using sharing -- the pathnames of entries in the boot classpath | |
647 // may not be the same at runtime as they were when the archive was | |
648 // created (NFS, Samba, etc.). The actual files and directories named | |
649 // in the classpath must be the same files, in the same order, even | |
650 // though the exact name is not the same. | |
651 | |
652 class PackageInfo: public BasicHashtableEntry { | |
653 public: | |
654 const char* _pkgname; // Package name | |
655 int _classpath_index; // Index of directory or JAR file loaded from | |
656 | |
657 PackageInfo* next() { | |
658 return (PackageInfo*)BasicHashtableEntry::next(); | |
659 } | |
660 | |
661 const char* pkgname() { return _pkgname; } | |
662 void set_pkgname(char* pkgname) { _pkgname = pkgname; } | |
663 | |
664 const char* filename() { | |
665 return ClassLoader::classpath_entry(_classpath_index)->name(); | |
666 } | |
667 | |
668 void set_index(int index) { | |
669 _classpath_index = index; | |
670 } | |
671 }; | |
672 | |
673 | |
674 class PackageHashtable : public BasicHashtable { | |
675 private: | |
676 inline unsigned int compute_hash(const char *s, int n) { | |
677 unsigned int val = 0; | |
678 while (--n >= 0) { | |
679 val = *s++ + 31 * val; | |
680 } | |
681 return val; | |
682 } | |
683 | |
684 PackageInfo* bucket(int index) { | |
685 return (PackageInfo*)BasicHashtable::bucket(index); | |
686 } | |
687 | |
688 PackageInfo* get_entry(int index, unsigned int hash, | |
689 const char* pkgname, size_t n) { | |
690 for (PackageInfo* pp = bucket(index); pp != NULL; pp = pp->next()) { | |
691 if (pp->hash() == hash && | |
692 strncmp(pkgname, pp->pkgname(), n) == 0 && | |
693 pp->pkgname()[n] == '\0') { | |
694 return pp; | |
695 } | |
696 } | |
697 return NULL; | |
698 } | |
699 | |
700 public: | |
701 PackageHashtable(int table_size) | |
702 : BasicHashtable(table_size, sizeof(PackageInfo)) {} | |
703 | |
704 PackageHashtable(int table_size, HashtableBucket* t, int number_of_entries) | |
705 : BasicHashtable(table_size, sizeof(PackageInfo), t, number_of_entries) {} | |
706 | |
707 PackageInfo* get_entry(const char* pkgname, int n) { | |
708 unsigned int hash = compute_hash(pkgname, n); | |
709 return get_entry(hash_to_index(hash), hash, pkgname, n); | |
710 } | |
711 | |
712 PackageInfo* new_entry(char* pkgname, int n) { | |
713 unsigned int hash = compute_hash(pkgname, n); | |
714 PackageInfo* pp; | |
715 pp = (PackageInfo*)BasicHashtable::new_entry(hash); | |
716 pp->set_pkgname(pkgname); | |
717 return pp; | |
718 } | |
719 | |
720 void add_entry(PackageInfo* pp) { | |
721 int index = hash_to_index(pp->hash()); | |
722 BasicHashtable::add_entry(index, pp); | |
723 } | |
724 | |
725 void copy_pkgnames(const char** packages) { | |
726 int n = 0; | |
727 for (int i = 0; i < table_size(); ++i) { | |
728 for (PackageInfo* pp = bucket(i); pp != NULL; pp = pp->next()) { | |
729 packages[n++] = pp->pkgname(); | |
730 } | |
731 } | |
732 assert(n == number_of_entries(), "just checking"); | |
733 } | |
734 | |
735 void copy_table(char** top, char* end, PackageHashtable* table); | |
736 }; | |
737 | |
738 | |
739 void PackageHashtable::copy_table(char** top, char* end, | |
740 PackageHashtable* table) { | |
741 // Copy (relocate) the table to the shared space. | |
742 BasicHashtable::copy_table(top, end); | |
743 | |
744 // Calculate the space needed for the package name strings. | |
745 int i; | |
746 int n = 0; | |
747 for (i = 0; i < table_size(); ++i) { | |
748 for (PackageInfo* pp = table->bucket(i); | |
749 pp != NULL; | |
750 pp = pp->next()) { | |
751 n += (int)(strlen(pp->pkgname()) + 1); | |
752 } | |
753 } | |
754 if (*top + n + sizeof(intptr_t) >= end) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2139
diff
changeset
|
755 report_out_of_shared_space(SharedMiscData); |
0 | 756 } |
757 | |
758 // Copy the table data (the strings) to the shared space. | |
759 n = align_size_up(n, sizeof(HeapWord)); | |
760 *(intptr_t*)(*top) = n; | |
761 *top += sizeof(intptr_t); | |
762 | |
763 for (i = 0; i < table_size(); ++i) { | |
764 for (PackageInfo* pp = table->bucket(i); | |
765 pp != NULL; | |
766 pp = pp->next()) { | |
767 int n1 = (int)(strlen(pp->pkgname()) + 1); | |
768 pp->set_pkgname((char*)memcpy(*top, pp->pkgname(), n1)); | |
769 *top += n1; | |
770 } | |
771 } | |
772 *top = (char*)align_size_up((intptr_t)*top, sizeof(HeapWord)); | |
773 } | |
774 | |
775 | |
776 void ClassLoader::copy_package_info_buckets(char** top, char* end) { | |
777 _package_hash_table->copy_buckets(top, end); | |
778 } | |
779 | |
780 void ClassLoader::copy_package_info_table(char** top, char* end) { | |
781 _package_hash_table->copy_table(top, end, _package_hash_table); | |
782 } | |
783 | |
784 | |
785 PackageInfo* ClassLoader::lookup_package(const char *pkgname) { | |
786 const char *cp = strrchr(pkgname, '/'); | |
787 if (cp != NULL) { | |
788 // Package prefix found | |
789 int n = cp - pkgname + 1; | |
790 return _package_hash_table->get_entry(pkgname, n); | |
791 } | |
792 return NULL; | |
793 } | |
794 | |
795 | |
796 bool ClassLoader::add_package(const char *pkgname, int classpath_index, TRAPS) { | |
797 assert(pkgname != NULL, "just checking"); | |
798 // Bootstrap loader no longer holds system loader lock obj serializing | |
799 // load_instance_class and thereby add_package | |
800 { | |
801 MutexLocker ml(PackageTable_lock, THREAD); | |
802 // First check for previously loaded entry | |
803 PackageInfo* pp = lookup_package(pkgname); | |
804 if (pp != NULL) { | |
805 // Existing entry found, check source of package | |
806 pp->set_index(classpath_index); | |
807 return true; | |
808 } | |
809 | |
810 const char *cp = strrchr(pkgname, '/'); | |
811 if (cp != NULL) { | |
812 // Package prefix found | |
813 int n = cp - pkgname + 1; | |
814 | |
815 char* new_pkgname = NEW_C_HEAP_ARRAY(char, n + 1); | |
816 if (new_pkgname == NULL) { | |
817 return false; | |
818 } | |
819 | |
820 memcpy(new_pkgname, pkgname, n); | |
821 new_pkgname[n] = '\0'; | |
822 pp = _package_hash_table->new_entry(new_pkgname, n); | |
823 pp->set_index(classpath_index); | |
824 | |
825 // Insert into hash table | |
826 _package_hash_table->add_entry(pp); | |
827 } | |
828 return true; | |
829 } | |
830 } | |
831 | |
832 | |
833 oop ClassLoader::get_system_package(const char* name, TRAPS) { | |
834 PackageInfo* pp; | |
835 { | |
836 MutexLocker ml(PackageTable_lock, THREAD); | |
837 pp = lookup_package(name); | |
838 } | |
839 if (pp == NULL) { | |
840 return NULL; | |
841 } else { | |
842 Handle p = java_lang_String::create_from_str(pp->filename(), THREAD); | |
843 return p(); | |
844 } | |
845 } | |
846 | |
847 | |
848 objArrayOop ClassLoader::get_system_packages(TRAPS) { | |
849 ResourceMark rm(THREAD); | |
850 int nof_entries; | |
851 const char** packages; | |
852 { | |
853 MutexLocker ml(PackageTable_lock, THREAD); | |
854 // Allocate resource char* array containing package names | |
855 nof_entries = _package_hash_table->number_of_entries(); | |
856 if ((packages = NEW_RESOURCE_ARRAY(const char*, nof_entries)) == NULL) { | |
857 return NULL; | |
858 } | |
859 _package_hash_table->copy_pkgnames(packages); | |
860 } | |
861 // Allocate objArray and fill with java.lang.String | |
1142 | 862 objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(), |
0 | 863 nof_entries, CHECK_0); |
864 objArrayHandle result(THREAD, r); | |
865 for (int i = 0; i < nof_entries; i++) { | |
866 Handle str = java_lang_String::create_from_str(packages[i], CHECK_0); | |
867 result->obj_at_put(i, str()); | |
868 } | |
869 | |
870 return result(); | |
871 } | |
872 | |
873 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2139
diff
changeset
|
874 instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) { |
0 | 875 ResourceMark rm(THREAD); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2139
diff
changeset
|
876 EventMark m("loading class " INTPTR_FORMAT, (address)h_name); |
0 | 877 ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion); |
878 | |
879 stringStream st; | |
880 // st.print() uses too much stack space while handling a StackOverflowError | |
881 // st.print("%s.class", h_name->as_utf8()); | |
882 st.print_raw(h_name->as_utf8()); | |
883 st.print_raw(".class"); | |
884 char* name = st.as_string(); | |
885 | |
886 // Lookup stream for parsing .class file | |
887 ClassFileStream* stream = NULL; | |
888 int classpath_index = 0; | |
889 { | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
890 PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
891 ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(), |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
892 PerfClassTraceTime::CLASS_LOAD); |
0 | 893 ClassPathEntry* e = _first_entry; |
894 while (e != NULL) { | |
895 stream = e->open_stream(name); | |
896 if (stream != NULL) { | |
897 break; | |
898 } | |
899 e = e->next(); | |
900 ++classpath_index; | |
901 } | |
902 } | |
903 | |
904 instanceKlassHandle h(THREAD, klassOop(NULL)); | |
905 if (stream != NULL) { | |
906 | |
907 // class file found, parse it | |
908 ClassFileParser parser(stream); | |
909 Handle class_loader; | |
910 Handle protection_domain; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2139
diff
changeset
|
911 TempNewSymbol parsed_name = NULL; |
0 | 912 instanceKlassHandle result = parser.parseClassFile(h_name, |
913 class_loader, | |
914 protection_domain, | |
915 parsed_name, | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
882
diff
changeset
|
916 false, |
0 | 917 CHECK_(h)); |
918 | |
919 // add to package table | |
920 if (add_package(name, classpath_index, THREAD)) { | |
921 h = result; | |
922 } | |
923 } | |
924 | |
925 return h; | |
926 } | |
927 | |
928 | |
929 void ClassLoader::create_package_info_table(HashtableBucket *t, int length, | |
930 int number_of_entries) { | |
931 assert(_package_hash_table == NULL, "One package info table allowed."); | |
932 assert(length == package_hash_table_size * sizeof(HashtableBucket), | |
933 "bad shared package info size."); | |
934 _package_hash_table = new PackageHashtable(package_hash_table_size, t, | |
935 number_of_entries); | |
936 } | |
937 | |
938 | |
939 void ClassLoader::create_package_info_table() { | |
940 assert(_package_hash_table == NULL, "shouldn't have one yet"); | |
941 _package_hash_table = new PackageHashtable(package_hash_table_size); | |
942 } | |
943 | |
944 | |
945 // Initialize the class loader's access to methods in libzip. Parse and | |
946 // process the boot classpath into a list ClassPathEntry objects. Once | |
947 // this list has been created, it must not change order (see class PackageInfo) | |
948 // it can be appended to and is by jvmti and the kernel vm. | |
949 | |
950 void ClassLoader::initialize() { | |
951 assert(_package_hash_table == NULL, "should have been initialized by now."); | |
952 EXCEPTION_MARK; | |
953 | |
954 if (UsePerfData) { | |
955 // jvmstat performance counters | |
956 NEWPERFTICKCOUNTER(_perf_accumulated_time, SUN_CLS, "time"); | |
957 NEWPERFTICKCOUNTER(_perf_class_init_time, SUN_CLS, "classInitTime"); | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
958 NEWPERFTICKCOUNTER(_perf_class_init_selftime, SUN_CLS, "classInitTime.self"); |
0 | 959 NEWPERFTICKCOUNTER(_perf_class_verify_time, SUN_CLS, "classVerifyTime"); |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
960 NEWPERFTICKCOUNTER(_perf_class_verify_selftime, SUN_CLS, "classVerifyTime.self"); |
0 | 961 NEWPERFTICKCOUNTER(_perf_class_link_time, SUN_CLS, "classLinkedTime"); |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
962 NEWPERFTICKCOUNTER(_perf_class_link_selftime, SUN_CLS, "classLinkedTime.self"); |
0 | 963 NEWPERFEVENTCOUNTER(_perf_classes_inited, SUN_CLS, "initializedClasses"); |
964 NEWPERFEVENTCOUNTER(_perf_classes_linked, SUN_CLS, "linkedClasses"); | |
875
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
965 NEWPERFEVENTCOUNTER(_perf_classes_verified, SUN_CLS, "verifiedClasses"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
966 |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
967 NEWPERFTICKCOUNTER(_perf_class_parse_time, SUN_CLS, "parseClassTime"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
968 NEWPERFTICKCOUNTER(_perf_class_parse_selftime, SUN_CLS, "parseClassTime.self"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
969 NEWPERFTICKCOUNTER(_perf_sys_class_lookup_time, SUN_CLS, "lookupSysClassTime"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
970 NEWPERFTICKCOUNTER(_perf_shared_classload_time, SUN_CLS, "sharedClassLoadTime"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
971 NEWPERFTICKCOUNTER(_perf_sys_classload_time, SUN_CLS, "sysClassLoadTime"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
972 NEWPERFTICKCOUNTER(_perf_app_classload_time, SUN_CLS, "appClassLoadTime"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
973 NEWPERFTICKCOUNTER(_perf_app_classload_selftime, SUN_CLS, "appClassLoadTime.self"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
974 NEWPERFEVENTCOUNTER(_perf_app_classload_count, SUN_CLS, "appClassLoadCount"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
975 NEWPERFTICKCOUNTER(_perf_define_appclasses, SUN_CLS, "defineAppClasses"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
976 NEWPERFTICKCOUNTER(_perf_define_appclass_time, SUN_CLS, "defineAppClassTime"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
977 NEWPERFTICKCOUNTER(_perf_define_appclass_selftime, SUN_CLS, "defineAppClassTime.self"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
978 NEWPERFBYTECOUNTER(_perf_app_classfile_bytes_read, SUN_CLS, "appClassBytes"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
979 NEWPERFBYTECOUNTER(_perf_sys_classfile_bytes_read, SUN_CLS, "sysClassBytes"); |
6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
mchung
parents:
723
diff
changeset
|
980 |
0 | 981 |
982 // The following performance counters are added for measuring the impact | |
983 // of the bug fix of 6365597. They are mainly focused on finding out | |
984 // the behavior of system & user-defined classloader lock, whether | |
985 // ClassLoader.loadClass/findClass is being called synchronized or not. | |
986 // Also two additional counters are created to see whether 'UnsyncloadClass' | |
987 // flag is being set or not and how many times load_instance_class call | |
988 // fails with linkageError etc. | |
989 NEWPERFEVENTCOUNTER(_sync_systemLoaderLockContentionRate, SUN_CLS, | |
990 "systemLoaderLockContentionRate"); | |
991 NEWPERFEVENTCOUNTER(_sync_nonSystemLoaderLockContentionRate, SUN_CLS, | |
992 "nonSystemLoaderLockContentionRate"); | |
993 NEWPERFEVENTCOUNTER(_sync_JVMFindLoadedClassLockFreeCounter, SUN_CLS, | |
994 "jvmFindLoadedClassNoLockCalls"); | |
995 NEWPERFEVENTCOUNTER(_sync_JVMDefineClassLockFreeCounter, SUN_CLS, | |
996 "jvmDefineClassNoLockCalls"); | |
997 | |
998 NEWPERFEVENTCOUNTER(_sync_JNIDefineClassLockFreeCounter, SUN_CLS, | |
999 "jniDefineClassNoLockCalls"); | |
1000 | |
1001 NEWPERFEVENTCOUNTER(_unsafe_defineClassCallCounter, SUN_CLS, | |
1002 "unsafeDefineClassCalls"); | |
1003 | |
1004 NEWPERFEVENTCOUNTER(_isUnsyncloadClass, SUN_CLS, "isUnsyncloadClassSet"); | |
1005 NEWPERFEVENTCOUNTER(_load_instance_class_failCounter, SUN_CLS, | |
1006 "loadInstanceClassFailRate"); | |
1007 | |
1008 // increment the isUnsyncloadClass counter if UnsyncloadClass is set. | |
1009 if (UnsyncloadClass) { | |
1010 _isUnsyncloadClass->inc(); | |
1011 } | |
1012 } | |
1013 | |
1014 // lookup zip library entry points | |
1015 load_zip_library(); | |
1016 // initialize search path | |
1017 setup_bootstrap_search_path(); | |
1018 if (LazyBootClassLoader) { | |
1019 // set up meta index which makes boot classpath initialization lazier | |
1020 setup_meta_index(); | |
1021 } | |
1022 } | |
1023 | |
1024 | |
1025 jlong ClassLoader::classloader_time_ms() { | |
1026 return UsePerfData ? | |
1027 Management::ticks_to_ms(_perf_accumulated_time->get_value()) : -1; | |
1028 } | |
1029 | |
1030 jlong ClassLoader::class_init_count() { | |
1031 return UsePerfData ? _perf_classes_inited->get_value() : -1; | |
1032 } | |
1033 | |
1034 jlong ClassLoader::class_init_time_ms() { | |
1035 return UsePerfData ? | |
1036 Management::ticks_to_ms(_perf_class_init_time->get_value()) : -1; | |
1037 } | |
1038 | |
1039 jlong ClassLoader::class_verify_time_ms() { | |
1040 return UsePerfData ? | |
1041 Management::ticks_to_ms(_perf_class_verify_time->get_value()) : -1; | |
1042 } | |
1043 | |
1044 jlong ClassLoader::class_link_count() { | |
1045 return UsePerfData ? _perf_classes_linked->get_value() : -1; | |
1046 } | |
1047 | |
1048 jlong ClassLoader::class_link_time_ms() { | |
1049 return UsePerfData ? | |
1050 Management::ticks_to_ms(_perf_class_link_time->get_value()) : -1; | |
1051 } | |
1052 | |
1053 int ClassLoader::compute_Object_vtable() { | |
1054 // hardwired for JDK1.2 -- would need to duplicate class file parsing | |
1055 // code to determine actual value from file | |
1056 // Would be value '11' if finals were in vtable | |
1057 int JDK_1_2_Object_vtable_size = 5; | |
1058 return JDK_1_2_Object_vtable_size * vtableEntry::size(); | |
1059 } | |
1060 | |
1061 | |
1062 void classLoader_init() { | |
1063 ClassLoader::initialize(); | |
1064 } | |
1065 | |
1066 | |
1067 bool ClassLoader::get_canonical_path(char* orig, char* out, int len) { | |
1068 assert(orig != NULL && out != NULL && len > 0, "bad arguments"); | |
1069 if (CanonicalizeEntry != NULL) { | |
1070 JNIEnv* env = JavaThread::current()->jni_environment(); | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1071 if ((CanonicalizeEntry)(env, os::native_path(orig), out, len) < 0) { |
0 | 1072 return false; |
1073 } | |
1074 } else { | |
1075 // On JDK 1.2.2 the Canonicalize does not exist, so just do nothing | |
1076 strncpy(out, orig, len); | |
1077 out[len - 1] = '\0'; | |
1078 } | |
1079 return true; | |
1080 } | |
1081 | |
1082 #ifndef PRODUCT | |
1083 | |
1084 void ClassLoader::verify() { | |
1085 _package_hash_table->verify(); | |
1086 } | |
1087 | |
1088 | |
1089 // CompileTheWorld | |
1090 // | |
1091 // Iterates over all class path entries and forces compilation of all methods | |
1092 // in all classes found. Currently, only zip/jar archives are searched. | |
1093 // | |
1094 // The classes are loaded by the Java level bootstrap class loader, and the | |
1095 // initializer is called. If DelayCompilationDuringStartup is true (default), | |
1096 // the interpreter will run the initialization code. Note that forcing | |
1097 // initialization in this way could potentially lead to initialization order | |
1098 // problems, in which case we could just force the initialization bit to be set. | |
1099 | |
1100 | |
1101 // We need to iterate over the contents of a zip/jar file, so we replicate the | |
1102 // jzcell and jzfile definitions from zip_util.h but rename jzfile to real_jzfile, | |
1103 // since jzfile already has a void* definition. | |
1104 // | |
1105 // Note that this is only used in debug mode. | |
1106 // | |
1107 // HotSpot integration note: | |
1108 // Matches zip_util.h 1.14 99/06/01 from jdk1.3 beta H build | |
1109 | |
1110 | |
1111 // JDK 1.3 version | |
1112 typedef struct real_jzentry13 { /* Zip file entry */ | |
1113 char *name; /* entry name */ | |
1114 jint time; /* modification time */ | |
1115 jint size; /* size of uncompressed data */ | |
1116 jint csize; /* size of compressed data (zero if uncompressed) */ | |
1117 jint crc; /* crc of uncompressed data */ | |
1118 char *comment; /* optional zip file comment */ | |
1119 jbyte *extra; /* optional extra data */ | |
1120 jint pos; /* position of LOC header (if negative) or data */ | |
1121 } real_jzentry13; | |
1122 | |
1123 typedef struct real_jzfile13 { /* Zip file */ | |
1124 char *name; /* zip file name */ | |
1125 jint refs; /* number of active references */ | |
1126 jint fd; /* open file descriptor */ | |
1127 void *lock; /* read lock */ | |
1128 char *comment; /* zip file comment */ | |
1129 char *msg; /* zip error message */ | |
1130 void *entries; /* array of hash cells */ | |
1131 jint total; /* total number of entries */ | |
1132 unsigned short *table; /* Hash chain heads: indexes into entries */ | |
1133 jint tablelen; /* number of hash eads */ | |
1134 real_jzfile13 *next; /* next zip file in search list */ | |
1135 jzentry *cache; /* we cache the most recently freed jzentry */ | |
1136 /* Information on metadata names in META-INF directory */ | |
1137 char **metanames; /* array of meta names (may have null names) */ | |
1138 jint metacount; /* number of slots in metanames array */ | |
1139 /* If there are any per-entry comments, they are in the comments array */ | |
1140 char **comments; | |
1141 } real_jzfile13; | |
1142 | |
1143 // JDK 1.2 version | |
1144 typedef struct real_jzentry12 { /* Zip file entry */ | |
1145 char *name; /* entry name */ | |
1146 jint time; /* modification time */ | |
1147 jint size; /* size of uncompressed data */ | |
1148 jint csize; /* size of compressed data (zero if uncompressed) */ | |
1149 jint crc; /* crc of uncompressed data */ | |
1150 char *comment; /* optional zip file comment */ | |
1151 jbyte *extra; /* optional extra data */ | |
1152 jint pos; /* position of LOC header (if negative) or data */ | |
1153 struct real_jzentry12 *next; /* next entry in hash table */ | |
1154 } real_jzentry12; | |
1155 | |
1156 typedef struct real_jzfile12 { /* Zip file */ | |
1157 char *name; /* zip file name */ | |
1158 jint refs; /* number of active references */ | |
1159 jint fd; /* open file descriptor */ | |
1160 void *lock; /* read lock */ | |
1161 char *comment; /* zip file comment */ | |
1162 char *msg; /* zip error message */ | |
1163 real_jzentry12 *entries; /* array of zip entries */ | |
1164 jint total; /* total number of entries */ | |
1165 real_jzentry12 **table; /* hash table of entries */ | |
1166 jint tablelen; /* number of buckets */ | |
1167 jzfile *next; /* next zip file in search list */ | |
1168 } real_jzfile12; | |
1169 | |
1170 | |
1171 void ClassPathDirEntry::compile_the_world(Handle loader, TRAPS) { | |
1172 // For now we only compile all methods in all classes in zip/jar files | |
1173 tty->print_cr("CompileTheWorld : Skipped classes in %s", _dir); | |
1174 tty->cr(); | |
1175 } | |
1176 | |
1177 | |
1178 bool ClassPathDirEntry::is_rt_jar() { | |
1179 return false; | |
1180 } | |
1181 | |
1182 void ClassPathZipEntry::compile_the_world(Handle loader, TRAPS) { | |
1183 if (JDK_Version::is_jdk12x_version()) { | |
1184 compile_the_world12(loader, THREAD); | |
1185 } else { | |
1186 compile_the_world13(loader, THREAD); | |
1187 } | |
1188 if (HAS_PENDING_EXCEPTION) { | |
1189 if (PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())) { | |
1190 CLEAR_PENDING_EXCEPTION; | |
1191 tty->print_cr("\nCompileTheWorld : Ran out of memory\n"); | |
1192 size_t used = Universe::heap()->permanent_used(); | |
1193 size_t capacity = Universe::heap()->permanent_capacity(); | |
1194 tty->print_cr("Permanent generation used %dK of %dK", used/K, capacity/K); | |
1195 tty->print_cr("Increase size by setting e.g. -XX:MaxPermSize=%dK\n", capacity*2/K); | |
1196 } else { | |
1197 tty->print_cr("\nCompileTheWorld : Unexpected exception occurred\n"); | |
1198 } | |
1199 } | |
1200 } | |
1201 | |
1202 // Version that works for JDK 1.3.x | |
1203 void ClassPathZipEntry::compile_the_world13(Handle loader, TRAPS) { | |
1204 real_jzfile13* zip = (real_jzfile13*) _zip; | |
1205 tty->print_cr("CompileTheWorld : Compiling all classes in %s", zip->name); | |
1206 tty->cr(); | |
1207 // Iterate over all entries in zip file | |
1208 for (int n = 0; ; n++) { | |
1209 real_jzentry13 * ze = (real_jzentry13 *)((*GetNextEntry)(_zip, n)); | |
1210 if (ze == NULL) break; | |
1211 ClassLoader::compile_the_world_in(ze->name, loader, CHECK); | |
1212 } | |
1213 } | |
1214 | |
1215 | |
1216 // Version that works for JDK 1.2.x | |
1217 void ClassPathZipEntry::compile_the_world12(Handle loader, TRAPS) { | |
1218 real_jzfile12* zip = (real_jzfile12*) _zip; | |
1219 tty->print_cr("CompileTheWorld : Compiling all classes in %s", zip->name); | |
1220 tty->cr(); | |
1221 // Iterate over all entries in zip file | |
1222 for (int n = 0; ; n++) { | |
1223 real_jzentry12 * ze = (real_jzentry12 *)((*GetNextEntry)(_zip, n)); | |
1224 if (ze == NULL) break; | |
1225 ClassLoader::compile_the_world_in(ze->name, loader, CHECK); | |
1226 } | |
1227 } | |
1228 | |
1229 bool ClassPathZipEntry::is_rt_jar() { | |
1230 if (JDK_Version::is_jdk12x_version()) { | |
1231 return is_rt_jar12(); | |
1232 } else { | |
1233 return is_rt_jar13(); | |
1234 } | |
1235 } | |
1236 | |
1237 // JDK 1.3 version | |
1238 bool ClassPathZipEntry::is_rt_jar13() { | |
1239 real_jzfile13* zip = (real_jzfile13*) _zip; | |
1240 int len = (int)strlen(zip->name); | |
1241 // Check whether zip name ends in "rt.jar" | |
1242 // This will match other archives named rt.jar as well, but this is | |
1243 // only used for debugging. | |
1244 return (len >= 6) && (strcasecmp(zip->name + len - 6, "rt.jar") == 0); | |
1245 } | |
1246 | |
1247 // JDK 1.2 version | |
1248 bool ClassPathZipEntry::is_rt_jar12() { | |
1249 real_jzfile12* zip = (real_jzfile12*) _zip; | |
1250 int len = (int)strlen(zip->name); | |
1251 // Check whether zip name ends in "rt.jar" | |
1252 // This will match other archives named rt.jar as well, but this is | |
1253 // only used for debugging. | |
1254 return (len >= 6) && (strcasecmp(zip->name + len - 6, "rt.jar") == 0); | |
1255 } | |
1256 | |
1257 void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) { | |
1258 resolve_entry()->compile_the_world(loader, CHECK); | |
1259 } | |
1260 | |
1261 bool LazyClassPathEntry::is_rt_jar() { | |
1262 return resolve_entry()->is_rt_jar(); | |
1263 } | |
1264 | |
1265 void ClassLoader::compile_the_world() { | |
1266 EXCEPTION_MARK; | |
1267 HandleMark hm(THREAD); | |
1268 ResourceMark rm(THREAD); | |
1269 // Make sure we don't run with background compilation | |
1270 BackgroundCompilation = false; | |
1271 // Find bootstrap loader | |
1272 Handle system_class_loader (THREAD, SystemDictionary::java_system_loader()); | |
1273 // Iterate over all bootstrap class path entries | |
1274 ClassPathEntry* e = _first_entry; | |
1275 while (e != NULL) { | |
1276 // We stop at rt.jar, unless it is the first bootstrap path entry | |
1277 if (e->is_rt_jar() && e != _first_entry) break; | |
1278 e->compile_the_world(system_class_loader, CATCH); | |
1279 e = e->next(); | |
1280 } | |
1281 tty->print_cr("CompileTheWorld : Done"); | |
1282 { | |
1283 // Print statistics as if before normal exit: | |
1284 extern void print_statistics(); | |
1285 print_statistics(); | |
1286 } | |
1287 vm_exit(0); | |
1288 } | |
1289 | |
1290 int ClassLoader::_compile_the_world_counter = 0; | |
1188
99af867dfa05
6919886: Sweep CodeCache more aggressively to reduce its usage for CompileTheWorld
kvn
parents:
1142
diff
changeset
|
1291 static int _codecache_sweep_counter = 0; |
0 | 1292 |
2257 | 1293 // Filter out all exceptions except OOMs |
1294 static void clear_pending_exception_if_not_oom(TRAPS) { | |
1295 if (HAS_PENDING_EXCEPTION && | |
1296 !PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())) { | |
1297 CLEAR_PENDING_EXCEPTION; | |
1298 } | |
1299 // The CHECK at the caller will propagate the exception out | |
1300 } | |
1301 | |
0 | 1302 void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { |
1303 int len = (int)strlen(name); | |
1304 if (len > 6 && strcmp(".class", name + len - 6) == 0) { | |
1305 // We have a .class file | |
1306 char buffer[2048]; | |
1307 strncpy(buffer, name, len - 6); | |
1308 buffer[len-6] = 0; | |
1309 // If the file has a period after removing .class, it's not really a | |
1310 // valid class file. The class loader will check everything else. | |
1311 if (strchr(buffer, '.') == NULL) { | |
1312 _compile_the_world_counter++; | |
723 | 1313 if (_compile_the_world_counter > CompileTheWorldStopAt) return; |
1314 | |
1315 // Construct name without extension | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2139
diff
changeset
|
1316 TempNewSymbol sym = SymbolTable::new_symbol(buffer, CHECK); |
723 | 1317 // Use loader to load and initialize class |
1318 klassOop ik = SystemDictionary::resolve_or_null(sym, loader, Handle(), THREAD); | |
1319 instanceKlassHandle k (THREAD, ik); | |
1320 if (k.not_null() && !HAS_PENDING_EXCEPTION) { | |
1321 k->initialize(THREAD); | |
1322 } | |
1323 bool exception_occurred = HAS_PENDING_EXCEPTION; | |
2257 | 1324 clear_pending_exception_if_not_oom(CHECK); |
723 | 1325 if (CompileTheWorldPreloadClasses && k.not_null()) { |
1326 constantPoolKlass::preload_and_initialize_all_classes(k->constants(), THREAD); | |
1327 if (HAS_PENDING_EXCEPTION) { | |
1328 // If something went wrong in preloading we just ignore it | |
2257 | 1329 clear_pending_exception_if_not_oom(CHECK); |
723 | 1330 tty->print_cr("Preloading failed for (%d) %s", _compile_the_world_counter, buffer); |
0 | 1331 } |
723 | 1332 } |
1333 | |
1334 if (_compile_the_world_counter >= CompileTheWorldStartAt) { | |
2323
bc6b27fb3568
6725983: Assertion "method->method_holder())->is_not_initialized(),"method holder must be initialized"
never
parents:
2257
diff
changeset
|
1335 if (k.is_null() || exception_occurred) { |
0 | 1336 // If something went wrong (e.g. ExceptionInInitializerError) we skip this class |
1337 tty->print_cr("CompileTheWorld (%d) : Skipping %s", _compile_the_world_counter, buffer); | |
1338 } else { | |
1339 tty->print_cr("CompileTheWorld (%d) : %s", _compile_the_world_counter, buffer); | |
1340 // Preload all classes to get around uncommon traps | |
1341 // Iterate over all methods in class | |
1342 for (int n = 0; n < k->methods()->length(); n++) { | |
1343 methodHandle m (THREAD, methodOop(k->methods()->obj_at(n))); | |
1783 | 1344 if (CompilationPolicy::can_be_compiled(m)) { |
1188
99af867dfa05
6919886: Sweep CodeCache more aggressively to reduce its usage for CompileTheWorld
kvn
parents:
1142
diff
changeset
|
1345 |
99af867dfa05
6919886: Sweep CodeCache more aggressively to reduce its usage for CompileTheWorld
kvn
parents:
1142
diff
changeset
|
1346 if (++_codecache_sweep_counter == CompileTheWorldSafepointInterval) { |
99af867dfa05
6919886: Sweep CodeCache more aggressively to reduce its usage for CompileTheWorld
kvn
parents:
1142
diff
changeset
|
1347 // Give sweeper a chance to keep up with CTW |
99af867dfa05
6919886: Sweep CodeCache more aggressively to reduce its usage for CompileTheWorld
kvn
parents:
1142
diff
changeset
|
1348 VM_ForceSafepoint op; |
99af867dfa05
6919886: Sweep CodeCache more aggressively to reduce its usage for CompileTheWorld
kvn
parents:
1142
diff
changeset
|
1349 VMThread::execute(&op); |
99af867dfa05
6919886: Sweep CodeCache more aggressively to reduce its usage for CompileTheWorld
kvn
parents:
1142
diff
changeset
|
1350 _codecache_sweep_counter = 0; |
99af867dfa05
6919886: Sweep CodeCache more aggressively to reduce its usage for CompileTheWorld
kvn
parents:
1142
diff
changeset
|
1351 } |
0 | 1352 // Force compilation |
1783 | 1353 CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_initial_compile, |
0 | 1354 methodHandle(), 0, "CTW", THREAD); |
1355 if (HAS_PENDING_EXCEPTION) { | |
2257 | 1356 clear_pending_exception_if_not_oom(CHECK); |
0 | 1357 tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_counter, m->name()->as_C_string()); |
1358 } | |
723 | 1359 if (TieredCompilation) { |
1360 // Clobber the first compile and force second tier compilation | |
1361 nmethod* nm = m->code(); | |
1362 if (nm != NULL) { | |
1363 // Throw out the code so that the code cache doesn't fill up | |
1364 nm->make_not_entrant(); | |
1365 m->clear_code(); | |
1366 } | |
1783 | 1367 CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_full_optimization, |
723 | 1368 methodHandle(), 0, "CTW", THREAD); |
1369 if (HAS_PENDING_EXCEPTION) { | |
2257 | 1370 clear_pending_exception_if_not_oom(CHECK); |
723 | 1371 tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_counter, m->name()->as_C_string()); |
1372 } | |
0 | 1373 } |
1374 } | |
723 | 1375 |
1376 nmethod* nm = m->code(); | |
1377 if (nm != NULL) { | |
1378 // Throw out the code so that the code cache doesn't fill up | |
1379 nm->make_not_entrant(); | |
1380 m->clear_code(); | |
0 | 1381 } |
1382 } | |
1383 } | |
1384 } | |
1385 } | |
1386 } | |
1387 } | |
1388 | |
1389 #endif //PRODUCT | |
2139
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1390 |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1391 // Please keep following two functions at end of this file. With them placed at top or in middle of the file, |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1392 // they could get inlined by agressive compiler, an unknown trick, see bug 6966589. |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1393 void PerfClassTraceTime::initialize() { |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1394 if (!UsePerfData) return; |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1395 |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1396 if (_eventp != NULL) { |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1397 // increment the event counter |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1398 _eventp->inc(); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1399 } |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1400 |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1401 // stop the current active thread-local timer to measure inclusive time |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1402 _prev_active_event = -1; |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1403 for (int i=0; i < EVENT_TYPE_COUNT; i++) { |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1404 if (_timers[i].is_active()) { |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1405 assert(_prev_active_event == -1, "should have only one active timer"); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1406 _prev_active_event = i; |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1407 _timers[i].stop(); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1408 } |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1409 } |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1410 |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1411 if (_recursion_counters == NULL || (_recursion_counters[_event_type])++ == 0) { |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1412 // start the inclusive timer if not recursively called |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1413 _t.start(); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1414 } |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1415 |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1416 // start thread-local timer of the given event type |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1417 if (!_timers[_event_type].is_active()) { |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1418 _timers[_event_type].start(); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1419 } |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1420 } |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1421 |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1422 PerfClassTraceTime::~PerfClassTraceTime() { |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1423 if (!UsePerfData) return; |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1424 |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1425 // stop the thread-local timer as the event completes |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1426 // and resume the thread-local timer of the event next on the stack |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1427 _timers[_event_type].stop(); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1428 jlong selftime = _timers[_event_type].ticks(); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1429 |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1430 if (_prev_active_event >= 0) { |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1431 _timers[_prev_active_event].start(); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1432 } |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1433 |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1434 if (_recursion_counters != NULL && --(_recursion_counters[_event_type]) > 0) return; |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1435 |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1436 // increment the counters only on the leaf call |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1437 _t.stop(); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1438 _timep->inc(_t.ticks()); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1439 if (_selftimep != NULL) { |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1440 _selftimep->inc(selftime); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1441 } |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1442 // add all class loading related event selftime to the accumulated time counter |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1443 ClassLoader::perf_accumulated_time()->inc(selftime); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1444 |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1445 // reset the timer |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1446 _timers[_event_type].reset(); |
75efcee5ac47
6966589: hs16-b08 causes java.lang.StackOverflowError
minqi
parents:
1980
diff
changeset
|
1447 } |