24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/classFileParser.hpp" |
26 #include "classfile/classFileParser.hpp" |
27 #include "classfile/classFileStream.hpp" |
27 #include "classfile/classFileStream.hpp" |
28 #include "classfile/classLoader.hpp" |
28 #include "classfile/classLoader.hpp" |
|
29 #include "classfile/classLoaderExt.hpp" |
29 #include "classfile/classLoaderData.inline.hpp" |
30 #include "classfile/classLoaderData.inline.hpp" |
30 #include "classfile/javaClasses.hpp" |
31 #include "classfile/javaClasses.hpp" |
|
32 #if INCLUDE_CDS |
|
33 #include "classfile/sharedPathsMiscInfo.hpp" |
|
34 #include "classfile/sharedClassUtil.hpp" |
|
35 #endif |
31 #include "classfile/systemDictionary.hpp" |
36 #include "classfile/systemDictionary.hpp" |
32 #include "classfile/vmSymbols.hpp" |
37 #include "classfile/vmSymbols.hpp" |
33 #include "compiler/compileBroker.hpp" |
38 #include "compiler/compileBroker.hpp" |
34 #include "gc_interface/collectedHeap.inline.hpp" |
39 #include "gc_interface/collectedHeap.inline.hpp" |
35 #include "interpreter/bytecodeStream.hpp" |
40 #include "interpreter/bytecodeStream.hpp" |
36 #include "interpreter/oopMapCache.hpp" |
41 #include "interpreter/oopMapCache.hpp" |
37 #include "memory/allocation.inline.hpp" |
42 #include "memory/allocation.inline.hpp" |
|
43 #include "memory/filemap.hpp" |
38 #include "memory/generation.hpp" |
44 #include "memory/generation.hpp" |
39 #include "memory/oopFactory.hpp" |
45 #include "memory/oopFactory.hpp" |
40 #include "memory/universe.inline.hpp" |
46 #include "memory/universe.inline.hpp" |
41 #include "oops/instanceKlass.hpp" |
47 #include "oops/instanceKlass.hpp" |
42 #include "oops/instanceRefKlass.hpp" |
48 #include "oops/instanceRefKlass.hpp" |
192 return NULL; |
202 return NULL; |
193 } |
203 } |
194 // check if file exists |
204 // check if file exists |
195 struct stat st; |
205 struct stat st; |
196 if (os::stat(path, &st) == 0) { |
206 if (os::stat(path, &st) == 0) { |
|
207 #if INCLUDE_CDS |
|
208 if (DumpSharedSpaces) { |
|
209 // We have already check in ClassLoader::check_shared_classpath() that the directory is empty, so |
|
210 // we should never find a file underneath it -- unless user has added a new file while we are running |
|
211 // the dump, in which case let's quit! |
|
212 ShouldNotReachHere(); |
|
213 } |
|
214 #endif |
197 // found file, open it |
215 // found file, open it |
198 int file_handle = os::open(path, 0, 0); |
216 int file_handle = os::open(path, 0, 0); |
199 if (file_handle != -1) { |
217 if (file_handle != -1) { |
200 // read contents into resource array |
218 // read contents into resource array |
201 u1* buffer = NEW_RESOURCE_ARRAY(u1, st.st_size); |
219 u1* buffer = NEW_RESOURCE_ARRAY(u1, st.st_size); |
226 (*ZipClose)(_zip); |
244 (*ZipClose)(_zip); |
227 } |
245 } |
228 FREE_C_HEAP_ARRAY(char, _zip_name, mtClass); |
246 FREE_C_HEAP_ARRAY(char, _zip_name, mtClass); |
229 } |
247 } |
230 |
248 |
231 ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) { |
249 u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) { |
232 // enable call to C land |
250 // enable call to C land |
233 JavaThread* thread = JavaThread::current(); |
251 JavaThread* thread = JavaThread::current(); |
234 ThreadToNativeFromVM ttn(thread); |
252 ThreadToNativeFromVM ttn(thread); |
235 // check whether zip archive contains name |
253 // check whether zip archive contains name |
236 jint filesize, name_len; |
254 jint name_len; |
237 jzentry* entry = (*FindEntry)(_zip, name, &filesize, &name_len); |
255 jzentry* entry = (*FindEntry)(_zip, name, filesize, &name_len); |
238 if (entry == NULL) return NULL; |
256 if (entry == NULL) return NULL; |
239 u1* buffer; |
257 u1* buffer; |
240 char name_buf[128]; |
258 char name_buf[128]; |
241 char* filename; |
259 char* filename; |
242 if (name_len < 128) { |
260 if (name_len < 128) { |
243 filename = name_buf; |
261 filename = name_buf; |
244 } else { |
262 } else { |
245 filename = NEW_RESOURCE_ARRAY(char, name_len + 1); |
263 filename = NEW_RESOURCE_ARRAY(char, name_len + 1); |
246 } |
264 } |
247 |
265 |
248 // file found, get pointer to class in mmaped jar file. |
266 // file found, get pointer to the entry in mmapped jar file. |
249 if (ReadMappedEntry == NULL || |
267 if (ReadMappedEntry == NULL || |
250 !(*ReadMappedEntry)(_zip, entry, &buffer, filename)) { |
268 !(*ReadMappedEntry)(_zip, entry, &buffer, filename)) { |
251 // mmaped access not available, perhaps due to compression, |
269 // mmapped access not available, perhaps due to compression, |
252 // read contents into resource array |
270 // read contents into resource array |
253 buffer = NEW_RESOURCE_ARRAY(u1, filesize); |
271 int size = (*filesize) + ((nul_terminate) ? 1 : 0); |
|
272 buffer = NEW_RESOURCE_ARRAY(u1, size); |
254 if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL; |
273 if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL; |
|
274 } |
|
275 |
|
276 // return result |
|
277 if (nul_terminate) { |
|
278 buffer[*filesize] = 0; |
|
279 } |
|
280 return buffer; |
|
281 } |
|
282 |
|
283 ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) { |
|
284 jint filesize; |
|
285 u1* buffer = open_entry(name, &filesize, false, CHECK_NULL); |
|
286 if (buffer == NULL) { |
|
287 return NULL; |
255 } |
288 } |
256 if (UsePerfData) { |
289 if (UsePerfData) { |
257 ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize); |
290 ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize); |
258 } |
291 } |
259 // return result |
292 return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated |
260 return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated |
|
261 } |
293 } |
262 |
294 |
263 // invoke function for each entry in the zip file |
295 // invoke function for each entry in the zip file |
264 void ClassPathZipEntry::contents_do(void f(const char* name, void* context), void* context) { |
296 void ClassPathZipEntry::contents_do(void f(const char* name, void* context), void* context) { |
265 JavaThread* thread = JavaThread::current(); |
297 JavaThread* thread = JavaThread::current(); |
325 |
362 |
326 bool LazyClassPathEntry::is_lazy() { |
363 bool LazyClassPathEntry::is_lazy() { |
327 return true; |
364 return true; |
328 } |
365 } |
329 |
366 |
|
367 u1* LazyClassPathEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) { |
|
368 if (_has_error) { |
|
369 return NULL; |
|
370 } |
|
371 ClassPathEntry* cpe = resolve_entry(THREAD); |
|
372 if (cpe == NULL) { |
|
373 _has_error = true; |
|
374 return NULL; |
|
375 } else if (cpe->is_jar_file()) { |
|
376 return ((ClassPathZipEntry*)cpe)->open_entry(name, filesize, nul_terminate,THREAD); |
|
377 } else { |
|
378 ShouldNotReachHere(); |
|
379 *filesize = 0; |
|
380 return NULL; |
|
381 } |
|
382 } |
|
383 |
330 static void print_meta_index(LazyClassPathEntry* entry, |
384 static void print_meta_index(LazyClassPathEntry* entry, |
331 GrowableArray<char*>& meta_packages) { |
385 GrowableArray<char*>& meta_packages) { |
332 tty->print("[Meta index for %s=", entry->name()); |
386 tty->print("[Meta index for %s=", entry->name()); |
333 for (int i = 0; i < meta_packages.length(); i++) { |
387 for (int i = 0; i < meta_packages.length(); i++) { |
334 if (i > 0) tty->print(" "); |
388 if (i > 0) tty->print(" "); |
335 tty->print("%s", meta_packages.at(i)); |
389 tty->print("%s", meta_packages.at(i)); |
336 } |
390 } |
337 tty->print_cr("]"); |
391 tty->print_cr("]"); |
338 } |
392 } |
339 |
393 |
340 |
394 #if INCLUDE_CDS |
341 void ClassLoader::setup_meta_index() { |
395 void ClassLoader::exit_with_path_failure(const char* error, const char* message) { |
|
396 assert(DumpSharedSpaces, "only called at dump time"); |
|
397 tty->print_cr("Hint: enable -XX:+TraceClassPaths to diagnose the failure"); |
|
398 vm_exit_during_initialization(error, message); |
|
399 } |
|
400 #endif |
|
401 |
|
402 void ClassLoader::trace_class_path(const char* msg, const char* name) { |
|
403 if (!TraceClassPaths) { |
|
404 return; |
|
405 } |
|
406 |
|
407 if (msg) { |
|
408 tty->print("%s", msg); |
|
409 } |
|
410 if (name) { |
|
411 if (strlen(name) < 256) { |
|
412 tty->print("%s", name); |
|
413 } else { |
|
414 // For very long paths, we need to print each character separately, |
|
415 // as print_cr() has a length limit |
|
416 while (name[0] != '\0') { |
|
417 tty->print("%c", name[0]); |
|
418 name++; |
|
419 } |
|
420 } |
|
421 } |
|
422 if (msg && msg[0] == '[') { |
|
423 tty->print_cr("]"); |
|
424 } else { |
|
425 tty->cr(); |
|
426 } |
|
427 } |
|
428 |
|
429 void ClassLoader::setup_bootstrap_meta_index() { |
342 // Set up meta index which allows us to open boot jars lazily if |
430 // Set up meta index which allows us to open boot jars lazily if |
343 // class data sharing is enabled |
431 // class data sharing is enabled |
|
432 const char* meta_index_path = Arguments::get_meta_index_path(); |
|
433 const char* meta_index_dir = Arguments::get_meta_index_dir(); |
|
434 setup_meta_index(meta_index_path, meta_index_dir, 0); |
|
435 } |
|
436 |
|
437 void ClassLoader::setup_meta_index(const char* meta_index_path, const char* meta_index_dir, int start_index) { |
344 const char* known_version = "% VERSION 2"; |
438 const char* known_version = "% VERSION 2"; |
345 char* meta_index_path = Arguments::get_meta_index_path(); |
|
346 char* meta_index_dir = Arguments::get_meta_index_dir(); |
|
347 FILE* file = fopen(meta_index_path, "r"); |
439 FILE* file = fopen(meta_index_path, "r"); |
348 int line_no = 0; |
440 int line_no = 0; |
|
441 #if INCLUDE_CDS |
|
442 if (DumpSharedSpaces) { |
|
443 if (file != NULL) { |
|
444 _shared_paths_misc_info->add_required_file(meta_index_path); |
|
445 } else { |
|
446 _shared_paths_misc_info->add_nonexist_path(meta_index_path); |
|
447 } |
|
448 } |
|
449 #endif |
349 if (file != NULL) { |
450 if (file != NULL) { |
350 ResourceMark rm; |
451 ResourceMark rm; |
351 LazyClassPathEntry* cur_entry = NULL; |
452 LazyClassPathEntry* cur_entry = NULL; |
352 GrowableArray<char*> boot_class_path_packages(10); |
453 GrowableArray<char*> boot_class_path_packages(10); |
353 char package_name[256]; |
454 char package_name[256]; |
378 case '@': |
479 case '@': |
379 { |
480 { |
380 // Hand off current packages to current lazy entry (if any) |
481 // Hand off current packages to current lazy entry (if any) |
381 if ((cur_entry != NULL) && |
482 if ((cur_entry != NULL) && |
382 (boot_class_path_packages.length() > 0)) { |
483 (boot_class_path_packages.length() > 0)) { |
383 if (TraceClassLoading && Verbose) { |
484 if ((TraceClassLoading || TraceClassPaths) && Verbose) { |
384 print_meta_index(cur_entry, boot_class_path_packages); |
485 print_meta_index(cur_entry, boot_class_path_packages); |
385 } |
486 } |
386 MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0), |
487 MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0), |
387 boot_class_path_packages.length()); |
488 boot_class_path_packages.length()); |
388 cur_entry->set_meta_index(index); |
489 cur_entry->set_meta_index(index); |
389 } |
490 } |
390 cur_entry = NULL; |
491 cur_entry = NULL; |
391 boot_class_path_packages.clear(); |
492 boot_class_path_packages.clear(); |
392 |
493 |
393 // Find lazy entry corresponding to this jar file |
494 // Find lazy entry corresponding to this jar file |
394 for (ClassPathEntry* entry = _first_entry; entry != NULL; entry = entry->next()) { |
495 int count = 0; |
395 if (entry->is_lazy() && |
496 for (ClassPathEntry* entry = _first_entry; entry != NULL; entry = entry->next(), count++) { |
|
497 if (count >= start_index && |
|
498 entry->is_lazy() && |
396 string_starts_with(entry->name(), meta_index_dir) && |
499 string_starts_with(entry->name(), meta_index_dir) && |
397 string_ends_with(entry->name(), &package_name[2])) { |
500 string_ends_with(entry->name(), &package_name[2])) { |
398 cur_entry = (LazyClassPathEntry*) entry; |
501 cur_entry = (LazyClassPathEntry*) entry; |
399 break; |
502 break; |
400 } |
503 } |
427 } |
530 } |
428 } |
531 } |
429 // Hand off current packages to current lazy entry (if any) |
532 // Hand off current packages to current lazy entry (if any) |
430 if ((cur_entry != NULL) && |
533 if ((cur_entry != NULL) && |
431 (boot_class_path_packages.length() > 0)) { |
534 (boot_class_path_packages.length() > 0)) { |
432 if (TraceClassLoading && Verbose) { |
535 if ((TraceClassLoading || TraceClassPaths) && Verbose) { |
433 print_meta_index(cur_entry, boot_class_path_packages); |
536 print_meta_index(cur_entry, boot_class_path_packages); |
434 } |
537 } |
435 MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0), |
538 MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0), |
436 boot_class_path_packages.length()); |
539 boot_class_path_packages.length()); |
437 cur_entry->set_meta_index(index); |
540 cur_entry->set_meta_index(index); |
438 } |
541 } |
439 fclose(file); |
542 fclose(file); |
440 } |
543 } |
441 } |
544 } |
442 |
545 |
|
546 #if INCLUDE_CDS |
|
547 void ClassLoader::check_shared_classpath(const char *path) { |
|
548 if (strcmp(path, "") == 0) { |
|
549 exit_with_path_failure("Cannot have empty path in archived classpaths", NULL); |
|
550 } |
|
551 |
|
552 struct stat st; |
|
553 if (os::stat(path, &st) == 0) { |
|
554 if ((st.st_mode & S_IFREG) != S_IFREG) { // is directory |
|
555 if (!os::dir_is_empty(path)) { |
|
556 tty->print_cr("Error: non-empty directory '%s'", path); |
|
557 exit_with_path_failure("CDS allows only empty directories in archived classpaths", NULL); |
|
558 } |
|
559 } |
|
560 } |
|
561 } |
|
562 #endif |
|
563 |
443 void ClassLoader::setup_bootstrap_search_path() { |
564 void ClassLoader::setup_bootstrap_search_path() { |
444 assert(_first_entry == NULL, "should not setup bootstrap class search path twice"); |
565 assert(_first_entry == NULL, "should not setup bootstrap class search path twice"); |
445 char* sys_class_path = os::strdup_check_oom(Arguments::get_sysclasspath()); |
566 char* sys_class_path = os::strdup_check_oom(Arguments::get_sysclasspath()); |
446 if (TraceClassLoading && Verbose) { |
567 if (!PrintSharedArchiveAndExit) { |
447 tty->print_cr("[Bootstrap loader class path=%s]", sys_class_path); |
568 trace_class_path("[Bootstrap loader class path=", sys_class_path); |
448 } |
569 } |
449 |
570 #if INCLUDE_CDS |
450 int len = (int)strlen(sys_class_path); |
571 if (DumpSharedSpaces) { |
|
572 _shared_paths_misc_info->add_boot_classpath(Arguments::get_sysclasspath()); |
|
573 } |
|
574 #endif |
|
575 setup_search_path(sys_class_path); |
|
576 os::free(sys_class_path); |
|
577 } |
|
578 |
|
579 #if INCLUDE_CDS |
|
580 int ClassLoader::get_shared_paths_misc_info_size() { |
|
581 return _shared_paths_misc_info->get_used_bytes(); |
|
582 } |
|
583 |
|
584 void* ClassLoader::get_shared_paths_misc_info() { |
|
585 return _shared_paths_misc_info->buffer(); |
|
586 } |
|
587 |
|
588 bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) { |
|
589 SharedPathsMiscInfo* checker = SharedClassUtil::allocate_shared_paths_misc_info((char*)buf, size); |
|
590 bool result = checker->check(); |
|
591 delete checker; |
|
592 return result; |
|
593 } |
|
594 #endif |
|
595 |
|
596 void ClassLoader::setup_search_path(char *class_path) { |
|
597 int offset = 0; |
|
598 int len = (int)strlen(class_path); |
451 int end = 0; |
599 int end = 0; |
452 |
600 |
453 // Iterate over class path entries |
601 // Iterate over class path entries |
454 for (int start = 0; start < len; start = end) { |
602 for (int start = 0; start < len; start = end) { |
455 while (sys_class_path[end] && sys_class_path[end] != os::path_separator()[0]) { |
603 while (class_path[end] && class_path[end] != os::path_separator()[0]) { |
456 end++; |
604 end++; |
457 } |
605 } |
458 char* path = NEW_C_HEAP_ARRAY(char, end-start+1, mtClass); |
606 EXCEPTION_MARK; |
459 strncpy(path, &sys_class_path[start], end-start); |
607 ResourceMark rm(THREAD); |
460 path[end-start] = '\0'; |
608 char* path = NEW_RESOURCE_ARRAY(char, end - start + 1); |
|
609 strncpy(path, &class_path[start], end - start); |
|
610 path[end - start] = '\0'; |
461 update_class_path_entry_list(path, false); |
611 update_class_path_entry_list(path, false); |
462 FREE_C_HEAP_ARRAY(char, path, mtClass); |
612 #if INCLUDE_CDS |
463 while (sys_class_path[end] == os::path_separator()[0]) { |
613 if (DumpSharedSpaces) { |
|
614 check_shared_classpath(path); |
|
615 } |
|
616 #endif |
|
617 while (class_path[end] == os::path_separator()[0]) { |
464 end++; |
618 end++; |
465 } |
619 } |
466 } |
620 } |
467 os::free(sys_class_path); |
621 } |
468 } |
622 |
469 |
623 ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st, |
470 ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st, bool lazy, TRAPS) { |
624 bool lazy, bool throw_exception, TRAPS) { |
471 JavaThread* thread = JavaThread::current(); |
625 JavaThread* thread = JavaThread::current(); |
472 if (lazy) { |
626 if (lazy) { |
473 return new LazyClassPathEntry(path, st); |
627 return new LazyClassPathEntry(path, st, throw_exception); |
474 } |
628 } |
475 ClassPathEntry* new_entry = NULL; |
629 ClassPathEntry* new_entry = NULL; |
476 if ((st->st_mode & S_IFREG) == S_IFREG) { |
630 if ((st->st_mode & S_IFREG) == S_IFREG) { |
477 // Regular file, should be a zip file |
631 // Regular file, should be a zip file |
478 // Canonicalized filename |
632 // Canonicalized filename |
479 char canonical_path[JVM_MAXPATHLEN]; |
633 char canonical_path[JVM_MAXPATHLEN]; |
480 if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) { |
634 if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) { |
481 // This matches the classic VM |
635 // This matches the classic VM |
482 THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL); |
636 if (throw_exception) { |
|
637 THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL); |
|
638 } else { |
|
639 return NULL; |
|
640 } |
483 } |
641 } |
484 char* error_msg = NULL; |
642 char* error_msg = NULL; |
485 jzfile* zip; |
643 jzfile* zip; |
486 { |
644 { |
487 // enable call to C land |
645 // enable call to C land |
569 } else { |
731 } else { |
570 _last_entry->set_next(new_entry); |
732 _last_entry->set_next(new_entry); |
571 _last_entry = new_entry; |
733 _last_entry = new_entry; |
572 } |
734 } |
573 } |
735 } |
574 } |
736 _num_entries ++; |
575 |
737 } |
576 void ClassLoader::update_class_path_entry_list(char *path, |
738 |
577 bool check_for_duplicates) { |
739 // Returns true IFF the file/dir exists and the entry was successfully created. |
|
740 bool ClassLoader::update_class_path_entry_list(char *path, |
|
741 bool check_for_duplicates, |
|
742 bool throw_exception) { |
578 struct stat st; |
743 struct stat st; |
579 if (os::stat(path, &st) == 0) { |
744 if (os::stat(path, &st) == 0) { |
580 // File or directory found |
745 // File or directory found |
581 ClassPathEntry* new_entry = NULL; |
746 ClassPathEntry* new_entry = NULL; |
582 Thread* THREAD = Thread::current(); |
747 Thread* THREAD = Thread::current(); |
583 new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, CHECK); |
748 new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, throw_exception, CHECK_(false)); |
|
749 if (new_entry == NULL) { |
|
750 return false; |
|
751 } |
584 // The kernel VM adds dynamically to the end of the classloader path and |
752 // The kernel VM adds dynamically to the end of the classloader path and |
585 // doesn't reorder the bootclasspath which would break java.lang.Package |
753 // doesn't reorder the bootclasspath which would break java.lang.Package |
586 // (see PackageInfo). |
754 // (see PackageInfo). |
587 // Add new entry to linked list |
755 // Add new entry to linked list |
588 if (!check_for_duplicates || !contains_entry(new_entry)) { |
756 if (!check_for_duplicates || !contains_entry(new_entry)) { |
589 add_to_list(new_entry); |
757 ClassLoaderExt::add_class_path_entry(path, check_for_duplicates, new_entry); |
590 } |
758 } |
|
759 return true; |
|
760 } else { |
|
761 #if INCLUDE_CDS |
|
762 if (DumpSharedSpaces) { |
|
763 _shared_paths_misc_info->add_nonexist_path(path); |
|
764 } |
|
765 return false; |
|
766 #endif |
591 } |
767 } |
592 } |
768 } |
593 |
769 |
594 void ClassLoader::print_bootclasspath() { |
770 void ClassLoader::print_bootclasspath() { |
595 ClassPathEntry* e = _first_entry; |
771 ClassPathEntry* e = _first_entry; |
737 } |
913 } |
738 } |
914 } |
739 assert(n == number_of_entries(), "just checking"); |
915 assert(n == number_of_entries(), "just checking"); |
740 } |
916 } |
741 |
917 |
742 void copy_table(char** top, char* end, PackageHashtable* table); |
918 CDS_ONLY(void copy_table(char** top, char* end, PackageHashtable* table);) |
743 }; |
919 }; |
744 |
920 |
745 |
921 #if INCLUDE_CDS |
746 void PackageHashtable::copy_table(char** top, char* end, |
922 void PackageHashtable::copy_table(char** top, char* end, |
747 PackageHashtable* table) { |
923 PackageHashtable* table) { |
748 // Copy (relocate) the table to the shared space. |
924 // Copy (relocate) the table to the shared space. |
749 BasicHashtable<mtClass>::copy_table(top, end); |
925 BasicHashtable<mtClass>::copy_table(top, end); |
750 |
926 |
751 // Calculate the space needed for the package name strings. |
927 // Calculate the space needed for the package name strings. |
752 int i; |
928 int i; |
753 int n = 0; |
929 intptr_t* tableSize = (intptr_t*)(*top); |
754 for (i = 0; i < table_size(); ++i) { |
930 *top += sizeof(intptr_t); // For table size |
755 for (PackageInfo* pp = table->bucket(i); |
931 char* tableStart = *top; |
756 pp != NULL; |
|
757 pp = pp->next()) { |
|
758 n += (int)(strlen(pp->pkgname()) + 1); |
|
759 } |
|
760 } |
|
761 if (*top + n + sizeof(intptr_t) >= end) { |
|
762 report_out_of_shared_space(SharedMiscData); |
|
763 } |
|
764 |
|
765 // Copy the table data (the strings) to the shared space. |
|
766 n = align_size_up(n, sizeof(HeapWord)); |
|
767 *(intptr_t*)(*top) = n; |
|
768 *top += sizeof(intptr_t); |
|
769 |
932 |
770 for (i = 0; i < table_size(); ++i) { |
933 for (i = 0; i < table_size(); ++i) { |
771 for (PackageInfo* pp = table->bucket(i); |
934 for (PackageInfo* pp = table->bucket(i); |
772 pp != NULL; |
935 pp != NULL; |
773 pp = pp->next()) { |
936 pp = pp->next()) { |
774 int n1 = (int)(strlen(pp->pkgname()) + 1); |
937 int n1 = (int)(strlen(pp->pkgname()) + 1); |
|
938 if (*top + n1 >= end) { |
|
939 report_out_of_shared_space(SharedMiscData); |
|
940 } |
775 pp->set_pkgname((char*)memcpy(*top, pp->pkgname(), n1)); |
941 pp->set_pkgname((char*)memcpy(*top, pp->pkgname(), n1)); |
776 *top += n1; |
942 *top += n1; |
777 } |
943 } |
778 } |
944 } |
779 *top = (char*)align_size_up((intptr_t)*top, sizeof(HeapWord)); |
945 *top = (char*)align_size_up((intptr_t)*top, sizeof(HeapWord)); |
|
946 if (*top >= end) { |
|
947 report_out_of_shared_space(SharedMiscData); |
|
948 } |
|
949 |
|
950 // Write table size |
|
951 intptr_t len = *top - (char*)tableStart; |
|
952 *tableSize = len; |
780 } |
953 } |
781 |
954 |
782 |
955 |
783 void ClassLoader::copy_package_info_buckets(char** top, char* end) { |
956 void ClassLoader::copy_package_info_buckets(char** top, char* end) { |
784 _package_hash_table->copy_buckets(top, end); |
957 _package_hash_table->copy_buckets(top, end); |
785 } |
958 } |
786 |
959 |
787 void ClassLoader::copy_package_info_table(char** top, char* end) { |
960 void ClassLoader::copy_package_info_table(char** top, char* end) { |
788 _package_hash_table->copy_table(top, end, _package_hash_table); |
961 _package_hash_table->copy_table(top, end, _package_hash_table); |
789 } |
962 } |
790 |
963 #endif |
791 |
964 |
792 PackageInfo* ClassLoader::lookup_package(const char *pkgname) { |
965 PackageInfo* ClassLoader::lookup_package(const char *pkgname) { |
793 const char *cp = strrchr(pkgname, '/'); |
966 const char *cp = strrchr(pkgname, '/'); |
794 if (cp != NULL) { |
967 if (cp != NULL) { |
795 // Package prefix found |
968 // Package prefix found |
878 } |
1051 } |
879 |
1052 |
880 |
1053 |
881 instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) { |
1054 instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) { |
882 ResourceMark rm(THREAD); |
1055 ResourceMark rm(THREAD); |
883 EventMark m("loading class %s", h_name->as_C_string()); |
1056 const char* class_name = h_name->as_C_string(); |
|
1057 EventMark m("loading class %s", class_name); |
884 ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion); |
1058 ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion); |
885 |
1059 |
886 stringStream st; |
1060 stringStream st; |
887 // st.print() uses too much stack space while handling a StackOverflowError |
1061 // st.print() uses too much stack space while handling a StackOverflowError |
888 // st.print("%s.class", h_name->as_utf8()); |
1062 // st.print("%s.class", h_name->as_utf8()); |
889 st.print_raw(h_name->as_utf8()); |
1063 st.print_raw(h_name->as_utf8()); |
890 st.print_raw(".class"); |
1064 st.print_raw(".class"); |
891 char* name = st.as_string(); |
1065 const char* file_name = st.as_string(); |
|
1066 ClassLoaderExt::Context context(class_name, file_name, THREAD); |
892 |
1067 |
893 // Lookup stream for parsing .class file |
1068 // Lookup stream for parsing .class file |
894 ClassFileStream* stream = NULL; |
1069 ClassFileStream* stream = NULL; |
895 int classpath_index = 0; |
1070 int classpath_index = 0; |
|
1071 ClassPathEntry* e = NULL; |
|
1072 instanceKlassHandle h; |
896 { |
1073 { |
897 PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(), |
1074 PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(), |
898 ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(), |
1075 ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(), |
899 PerfClassTraceTime::CLASS_LOAD); |
1076 PerfClassTraceTime::CLASS_LOAD); |
900 ClassPathEntry* e = _first_entry; |
1077 e = _first_entry; |
901 while (e != NULL) { |
1078 while (e != NULL) { |
902 stream = e->open_stream(name, CHECK_NULL); |
1079 stream = e->open_stream(file_name, CHECK_NULL); |
|
1080 if (!context.check(stream, classpath_index)) { |
|
1081 return h; // NULL |
|
1082 } |
903 if (stream != NULL) { |
1083 if (stream != NULL) { |
904 break; |
1084 break; |
905 } |
1085 } |
906 e = e->next(); |
1086 e = e->next(); |
907 ++classpath_index; |
1087 ++classpath_index; |
908 } |
1088 } |
909 } |
1089 } |
910 |
1090 |
911 instanceKlassHandle h; |
|
912 if (stream != NULL) { |
1091 if (stream != NULL) { |
913 |
|
914 // class file found, parse it |
1092 // class file found, parse it |
915 ClassFileParser parser(stream); |
1093 ClassFileParser parser(stream); |
916 ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); |
1094 ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); |
917 Handle protection_domain; |
1095 Handle protection_domain; |
918 TempNewSymbol parsed_name = NULL; |
1096 TempNewSymbol parsed_name = NULL; |
919 instanceKlassHandle result = parser.parseClassFile(h_name, |
1097 instanceKlassHandle result = parser.parseClassFile(h_name, |
920 loader_data, |
1098 loader_data, |
921 protection_domain, |
1099 protection_domain, |
922 parsed_name, |
1100 parsed_name, |
923 false, |
1101 context.should_verify(classpath_index), |
924 CHECK_(h)); |
1102 THREAD); |
925 |
1103 if (HAS_PENDING_EXCEPTION) { |
926 // add to package table |
1104 ResourceMark rm; |
927 if (add_package(name, classpath_index, THREAD)) { |
1105 if (DumpSharedSpaces) { |
928 h = result; |
1106 tty->print_cr("Preload Error: Failed to load %s", class_name); |
|
1107 } |
|
1108 return h; |
|
1109 } |
|
1110 h = context.record_result(classpath_index, e, result, THREAD); |
|
1111 } else { |
|
1112 if (DumpSharedSpaces) { |
|
1113 tty->print_cr("Preload Error: Cannot find %s", class_name); |
929 } |
1114 } |
930 } |
1115 } |
931 |
1116 |
932 return h; |
1117 return h; |
933 } |
1118 } |