246 _num_module_paths = ClassLoader::num_module_path_entries();
247 _max_used_path_index = ClassLoaderExt::max_used_path_index();
248
249 _verify_local = BytecodeVerificationLocal;
250 _verify_remote = BytecodeVerificationRemote;
251 _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
252 _shared_base_address = SharedBaseAddress;
253 _allow_archiving_with_java_agent = AllowArchivingWithJavaAgent;
254 // the following 2 fields will be set in write_header for dynamic archive header
255 _base_archive_name_size = 0;
256 _base_archive_is_default = false;
257 }
258
259 void SharedClassPathEntry::init_as_non_existent(const char* path, TRAPS) {
260 _type = non_existent_entry;
261 set_name(path, THREAD);
262 }
263
264 void SharedClassPathEntry::init(bool is_modules_image,
265 ClassPathEntry* cpe, TRAPS) {
266 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
267 _timestamp = 0;
268 _filesize = 0;
269 _from_class_path_attr = false;
270
271 struct stat st;
272 if (os::stat(cpe->name(), &st) == 0) {
273 if ((st.st_mode & S_IFMT) == S_IFDIR) {
274 _type = dir_entry;
275 } else {
276 // The timestamp of the modules_image is not checked at runtime.
277 if (is_modules_image) {
278 _type = modules_image_entry;
279 } else {
280 _type = jar_entry;
281 _timestamp = st.st_mtime;
282 _from_class_path_attr = cpe->from_class_path_attr();
283 }
284 _filesize = st.st_size;
285 }
286 } else {
380 it->push(&_table);
381 for (int i=0; i<_size; i++) {
382 path_at(i)->metaspace_pointers_do(it);
383 }
384 }
385
386 void SharedPathTable::dumptime_init(ClassLoaderData* loader_data, Thread* THREAD) {
387 size_t entry_size = sizeof(SharedClassPathEntry);
388 int num_entries = 0;
389 num_entries += ClassLoader::num_boot_classpath_entries();
390 num_entries += ClassLoader::num_app_classpath_entries();
391 num_entries += ClassLoader::num_module_path_entries();
392 num_entries += FileMapInfo::num_non_existent_class_paths();
393 size_t bytes = entry_size * num_entries;
394
395 _table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
396 _size = num_entries;
397 }
398
399 void FileMapInfo::allocate_shared_path_table() {
400 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity");
401
402 EXCEPTION_MARK; // The following calls should never throw, but would exit VM on error.
403 ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
404 ClassPathEntry* jrt = ClassLoader::get_jrt_entry();
405
406 assert(jrt != NULL,
407 "No modular java runtime image present when allocating the CDS classpath entry table");
408
409 _shared_path_table.dumptime_init(loader_data, THREAD);
410
411 // 1. boot class path
412 int i = 0;
413 i = add_shared_classpaths(i, "boot", jrt, THREAD);
414 i = add_shared_classpaths(i, "app", ClassLoader::app_classpath_entries(), THREAD);
415 i = add_shared_classpaths(i, "module", ClassLoader::module_path_entries(), THREAD);
416
417 for (int x = 0; x < num_non_existent_class_paths(); x++, i++) {
418 const char* path = _non_existent_class_paths->at(x);
419 shared_path(i)->init_as_non_existent(path, THREAD);
420 }
427 bool is_jrt = (cpe == ClassLoader::get_jrt_entry());
428 const char* type = (is_jrt ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
429 log_info(class, path)("add %s shared path (%s) %s", which, type, cpe->name());
430 SharedClassPathEntry* ent = shared_path(i);
431 ent->init(is_jrt, cpe, THREAD);
432 if (cpe->is_jar_file()) {
433 update_jar_manifest(cpe, ent, THREAD);
434 }
435 if (is_jrt) {
436 cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
437 } else {
438 cpe = cpe->next();
439 }
440 i++;
441 }
442
443 return i;
444 }
445
446 void FileMapInfo::check_nonempty_dir_in_shared_path_table() {
447 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
448
449 bool has_nonempty_dir = false;
450
451 int last = _shared_path_table.size() - 1;
452 if (last > ClassLoaderExt::max_used_path_index()) {
453 // no need to check any path beyond max_used_path_index
454 last = ClassLoaderExt::max_used_path_index();
455 }
456
457 for (int i = 0; i <= last; i++) {
458 SharedClassPathEntry *e = shared_path(i);
459 if (e->is_dir()) {
460 const char* path = e->name();
461 if (!os::dir_is_empty(path)) {
462 log_error(cds)("Error: non-empty directory '%s'", path);
463 has_nonempty_dir = true;
464 }
465 }
466 }
467
468 if (has_nonempty_dir) {
469 ClassLoader::exit_with_path_failure("Cannot have non-empty directory in paths", NULL);
470 }
471 }
472
473 void FileMapInfo::record_non_existent_class_path_entry(const char* path) {
474 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
475 log_info(class, path)("non-existent Class-Path entry %s", path);
476 if (_non_existent_class_paths == NULL) {
477 _non_existent_class_paths = new (ResourceObj::C_HEAP, mtInternal)GrowableArray<const char*>(10, true);
478 }
479 _non_existent_class_paths->append(os::strdup(path));
480 }
481
482 int FileMapInfo::num_non_existent_class_paths() {
483 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
484 if (_non_existent_class_paths != NULL) {
485 return _non_existent_class_paths->length();
486 } else {
487 return 0;
488 }
489 }
490
491 class ManifestStream: public ResourceObj {
492 private:
493 u1* _buffer_start; // Buffer bottom
494 u1* _buffer_end; // Buffer top (one past last element)
495 u1* _current; // Current buffer position
496
497 public:
498 // Constructor
499 ManifestStream(u1* buffer, int length) : _buffer_start(buffer),
500 _current(buffer) {
501 _buffer_end = buffer + length;
502 }
503
1133
1134 if (is_heap_region) {
1135 assert(!DynamicDumpSharedSpaces, "must be");
1136 assert((base - (char*)CompressedKlassPointers::base()) % HeapWordSize == 0, "Sanity");
1137 if (base != NULL) {
1138 _addr._offset = (intx)CompressedOops::encode_not_null((oop)base);
1139 } else {
1140 _addr._offset = 0;
1141 }
1142 } else {
1143 _addr._base = base;
1144 }
1145 _used = size;
1146 _read_only = read_only;
1147 _allow_exec = allow_exec;
1148 _crc = crc;
1149 }
1150
1151 void FileMapInfo::write_region(int region, char* base, size_t size,
1152 bool read_only, bool allow_exec) {
1153 assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Dump time only");
1154
1155 FileMapRegion* si = space_at(region);
1156 char* target_base = base;
1157 if (DynamicDumpSharedSpaces) {
1158 assert(!HeapShared::is_heap_region(region), "dynamic archive doesn't support heap regions");
1159 target_base = DynamicArchive::buffer_to_target(base);
1160 }
1161
1162 si->set_file_offset(_file_offset);
1163 log_info(cds)("Shared file region %d: " SIZE_FORMAT_HEX_W(08)
1164 " bytes, addr " INTPTR_FORMAT " file offset " SIZE_FORMAT_HEX_W(08),
1165 region, size, p2i(target_base), _file_offset);
1166
1167 int crc = ClassLoader::crc32(0, base, (jint)size);
1168 si->init(HeapShared::is_heap_region(region), target_base, size, read_only, allow_exec, crc);
1169
1170 if (base != NULL) {
1171 write_bytes_aligned(base, size);
1172 }
1173 }
|
246 _num_module_paths = ClassLoader::num_module_path_entries();
247 _max_used_path_index = ClassLoaderExt::max_used_path_index();
248
249 _verify_local = BytecodeVerificationLocal;
250 _verify_remote = BytecodeVerificationRemote;
251 _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
252 _shared_base_address = SharedBaseAddress;
253 _allow_archiving_with_java_agent = AllowArchivingWithJavaAgent;
254 // the following 2 fields will be set in write_header for dynamic archive header
255 _base_archive_name_size = 0;
256 _base_archive_is_default = false;
257 }
258
259 void SharedClassPathEntry::init_as_non_existent(const char* path, TRAPS) {
260 _type = non_existent_entry;
261 set_name(path, THREAD);
262 }
263
264 void SharedClassPathEntry::init(bool is_modules_image,
265 ClassPathEntry* cpe, TRAPS) {
266 Arguments::assert_is_dumping_archive();
267 _timestamp = 0;
268 _filesize = 0;
269 _from_class_path_attr = false;
270
271 struct stat st;
272 if (os::stat(cpe->name(), &st) == 0) {
273 if ((st.st_mode & S_IFMT) == S_IFDIR) {
274 _type = dir_entry;
275 } else {
276 // The timestamp of the modules_image is not checked at runtime.
277 if (is_modules_image) {
278 _type = modules_image_entry;
279 } else {
280 _type = jar_entry;
281 _timestamp = st.st_mtime;
282 _from_class_path_attr = cpe->from_class_path_attr();
283 }
284 _filesize = st.st_size;
285 }
286 } else {
380 it->push(&_table);
381 for (int i=0; i<_size; i++) {
382 path_at(i)->metaspace_pointers_do(it);
383 }
384 }
385
386 void SharedPathTable::dumptime_init(ClassLoaderData* loader_data, Thread* THREAD) {
387 size_t entry_size = sizeof(SharedClassPathEntry);
388 int num_entries = 0;
389 num_entries += ClassLoader::num_boot_classpath_entries();
390 num_entries += ClassLoader::num_app_classpath_entries();
391 num_entries += ClassLoader::num_module_path_entries();
392 num_entries += FileMapInfo::num_non_existent_class_paths();
393 size_t bytes = entry_size * num_entries;
394
395 _table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
396 _size = num_entries;
397 }
398
399 void FileMapInfo::allocate_shared_path_table() {
400 Arguments::assert_is_dumping_archive();
401
402 EXCEPTION_MARK; // The following calls should never throw, but would exit VM on error.
403 ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
404 ClassPathEntry* jrt = ClassLoader::get_jrt_entry();
405
406 assert(jrt != NULL,
407 "No modular java runtime image present when allocating the CDS classpath entry table");
408
409 _shared_path_table.dumptime_init(loader_data, THREAD);
410
411 // 1. boot class path
412 int i = 0;
413 i = add_shared_classpaths(i, "boot", jrt, THREAD);
414 i = add_shared_classpaths(i, "app", ClassLoader::app_classpath_entries(), THREAD);
415 i = add_shared_classpaths(i, "module", ClassLoader::module_path_entries(), THREAD);
416
417 for (int x = 0; x < num_non_existent_class_paths(); x++, i++) {
418 const char* path = _non_existent_class_paths->at(x);
419 shared_path(i)->init_as_non_existent(path, THREAD);
420 }
427 bool is_jrt = (cpe == ClassLoader::get_jrt_entry());
428 const char* type = (is_jrt ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
429 log_info(class, path)("add %s shared path (%s) %s", which, type, cpe->name());
430 SharedClassPathEntry* ent = shared_path(i);
431 ent->init(is_jrt, cpe, THREAD);
432 if (cpe->is_jar_file()) {
433 update_jar_manifest(cpe, ent, THREAD);
434 }
435 if (is_jrt) {
436 cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
437 } else {
438 cpe = cpe->next();
439 }
440 i++;
441 }
442
443 return i;
444 }
445
446 void FileMapInfo::check_nonempty_dir_in_shared_path_table() {
447 Arguments::assert_is_dumping_archive();
448
449 bool has_nonempty_dir = false;
450
451 int last = _shared_path_table.size() - 1;
452 if (last > ClassLoaderExt::max_used_path_index()) {
453 // no need to check any path beyond max_used_path_index
454 last = ClassLoaderExt::max_used_path_index();
455 }
456
457 for (int i = 0; i <= last; i++) {
458 SharedClassPathEntry *e = shared_path(i);
459 if (e->is_dir()) {
460 const char* path = e->name();
461 if (!os::dir_is_empty(path)) {
462 log_error(cds)("Error: non-empty directory '%s'", path);
463 has_nonempty_dir = true;
464 }
465 }
466 }
467
468 if (has_nonempty_dir) {
469 ClassLoader::exit_with_path_failure("Cannot have non-empty directory in paths", NULL);
470 }
471 }
472
473 void FileMapInfo::record_non_existent_class_path_entry(const char* path) {
474 Arguments::assert_is_dumping_archive();
475 log_info(class, path)("non-existent Class-Path entry %s", path);
476 if (_non_existent_class_paths == NULL) {
477 _non_existent_class_paths = new (ResourceObj::C_HEAP, mtInternal)GrowableArray<const char*>(10, true);
478 }
479 _non_existent_class_paths->append(os::strdup(path));
480 }
481
482 int FileMapInfo::num_non_existent_class_paths() {
483 Arguments::assert_is_dumping_archive();
484 if (_non_existent_class_paths != NULL) {
485 return _non_existent_class_paths->length();
486 } else {
487 return 0;
488 }
489 }
490
491 class ManifestStream: public ResourceObj {
492 private:
493 u1* _buffer_start; // Buffer bottom
494 u1* _buffer_end; // Buffer top (one past last element)
495 u1* _current; // Current buffer position
496
497 public:
498 // Constructor
499 ManifestStream(u1* buffer, int length) : _buffer_start(buffer),
500 _current(buffer) {
501 _buffer_end = buffer + length;
502 }
503
1133
1134 if (is_heap_region) {
1135 assert(!DynamicDumpSharedSpaces, "must be");
1136 assert((base - (char*)CompressedKlassPointers::base()) % HeapWordSize == 0, "Sanity");
1137 if (base != NULL) {
1138 _addr._offset = (intx)CompressedOops::encode_not_null((oop)base);
1139 } else {
1140 _addr._offset = 0;
1141 }
1142 } else {
1143 _addr._base = base;
1144 }
1145 _used = size;
1146 _read_only = read_only;
1147 _allow_exec = allow_exec;
1148 _crc = crc;
1149 }
1150
1151 void FileMapInfo::write_region(int region, char* base, size_t size,
1152 bool read_only, bool allow_exec) {
1153 Arguments::assert_is_dumping_archive();
1154
1155 FileMapRegion* si = space_at(region);
1156 char* target_base = base;
1157 if (DynamicDumpSharedSpaces) {
1158 assert(!HeapShared::is_heap_region(region), "dynamic archive doesn't support heap regions");
1159 target_base = DynamicArchive::buffer_to_target(base);
1160 }
1161
1162 si->set_file_offset(_file_offset);
1163 log_info(cds)("Shared file region %d: " SIZE_FORMAT_HEX_W(08)
1164 " bytes, addr " INTPTR_FORMAT " file offset " SIZE_FORMAT_HEX_W(08),
1165 region, size, p2i(target_base), _file_offset);
1166
1167 int crc = ClassLoader::crc32(0, base, (jint)size);
1168 si->init(HeapShared::is_heap_region(region), target_base, size, read_only, allow_exec, crc);
1169
1170 if (base != NULL) {
1171 write_bytes_aligned(base, size);
1172 }
1173 }
|