src/hotspot/share/memory/filemap.cpp
changeset 50039 9fec54fe663d
parent 49982 9042ffe5b7fe
child 50199 83d8b3a25f25
equal deleted inserted replaced
50038:3db7884546a1 50039:9fec54fe663d
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "jvm.h"
    26 #include "jvm.h"
    27 #include "classfile/classLoader.inline.hpp"
    27 #include "classfile/classLoader.inline.hpp"
       
    28 #include "classfile/classLoaderExt.hpp"
    28 #include "classfile/compactHashtable.inline.hpp"
    29 #include "classfile/compactHashtable.inline.hpp"
    29 #include "classfile/sharedClassUtil.hpp"
       
    30 #include "classfile/stringTable.hpp"
    30 #include "classfile/stringTable.hpp"
    31 #include "classfile/symbolTable.hpp"
    31 #include "classfile/symbolTable.hpp"
    32 #include "classfile/systemDictionaryShared.hpp"
    32 #include "classfile/systemDictionaryShared.hpp"
    33 #include "classfile/altHashing.hpp"
    33 #include "classfile/altHashing.hpp"
    34 #include "logging/log.hpp"
    34 #include "logging/log.hpp"
   157   assert(_current_info == NULL, "must be singleton"); // not thread safe
   157   assert(_current_info == NULL, "must be singleton"); // not thread safe
   158   _current_info = this;
   158   _current_info = this;
   159   memset((void*)this, 0, sizeof(FileMapInfo));
   159   memset((void*)this, 0, sizeof(FileMapInfo));
   160   _file_offset = 0;
   160   _file_offset = 0;
   161   _file_open = false;
   161   _file_open = false;
   162   _header = SharedClassUtil::allocate_file_map_header();
   162   _header = new FileMapHeader();
   163   _header->_version = _invalid_version;
   163   _header->_version = _invalid_version;
       
   164   _header->_has_platform_or_app_classes = true;
   164 }
   165 }
   165 
   166 
   166 FileMapInfo::~FileMapInfo() {
   167 FileMapInfo::~FileMapInfo() {
   167   assert(_current_info == this, "must be singleton"); // not thread safe
   168   assert(_current_info == this, "must be singleton"); // not thread safe
   168   _current_info = NULL;
   169   _current_info = NULL;
   169 }
   170 }
   170 
   171 
   171 void FileMapInfo::populate_header(size_t alignment) {
   172 void FileMapInfo::populate_header(size_t alignment) {
   172   _header->populate(this, alignment);
   173   _header->populate(this, alignment);
   173 }
       
   174 
       
   175 size_t FileMapInfo::FileMapHeader::data_size() {
       
   176   return SharedClassUtil::file_map_header_size() - sizeof(FileMapInfo::FileMapHeaderBase);
       
   177 }
   174 }
   178 
   175 
   179 void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
   176 void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
   180   _magic = 0xf00baba2;
   177   _magic = 0xf00baba2;
   181   _version = _current_version;
   178   _version = _current_version;
   196   // will function correctly with this JVM and the bootclasspath it's
   193   // will function correctly with this JVM and the bootclasspath it's
   197   // invoked with.
   194   // invoked with.
   198 
   195 
   199   // JVM version string ... changes on each build.
   196   // JVM version string ... changes on each build.
   200   get_header_version(_jvm_ident);
   197   get_header_version(_jvm_ident);
       
   198 
       
   199   ClassLoaderExt::finalize_shared_paths_misc_info();
       
   200   _app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index();
       
   201   _app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index();
       
   202 
       
   203   _verify_local = BytecodeVerificationLocal;
       
   204   _verify_remote = BytecodeVerificationRemote;
       
   205   _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
   201 }
   206 }
   202 
   207 
   203 void SharedClassPathEntry::init(const char* name, TRAPS) {
   208 void SharedClassPathEntry::init(const char* name, TRAPS) {
   204   _timestamp = 0;
   209   _timestamp = 0;
   205   _filesize  = 0;
   210   _filesize  = 0;
   276   ClassPathEntry* jrt = ClassLoader::get_jrt_entry();
   281   ClassPathEntry* jrt = ClassLoader::get_jrt_entry();
   277 
   282 
   278   assert(jrt != NULL,
   283   assert(jrt != NULL,
   279          "No modular java runtime image present when allocating the CDS classpath entry table");
   284          "No modular java runtime image present when allocating the CDS classpath entry table");
   280 
   285 
   281   size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); // assert ( should be 8 byte aligned??)
   286   size_t entry_size = sizeof(SharedClassPathEntry); // assert ( should be 8 byte aligned??)
   282   int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
   287   int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
   283   int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
   288   int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
   284   int num_module_path_entries = ClassLoader::num_module_path_entries();
   289   int num_module_path_entries = ClassLoader::num_module_path_entries();
   285   int num_entries = num_boot_classpath_entries + num_app_classpath_entries + num_module_path_entries;
   290   int num_entries = num_boot_classpath_entries + num_app_classpath_entries + num_module_path_entries;
   286   size_t bytes = entry_size * num_entries;
   291   size_t bytes = entry_size * num_entries;
   297     log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
   302     log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
   298     SharedClassPathEntry* ent = shared_path(i);
   303     SharedClassPathEntry* ent = shared_path(i);
   299     ent->init(cpe->name(), THREAD);
   304     ent->init(cpe->name(), THREAD);
   300     if (cpe != jrt) { // No need to do jimage.
   305     if (cpe != jrt) { // No need to do jimage.
   301       EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
   306       EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
   302       SharedClassUtil::update_shared_classpath(cpe, ent, THREAD);
   307       update_shared_classpath(cpe, ent, THREAD);
   303     }
   308     }
   304     cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
   309     cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
   305     i++;
   310     i++;
   306   }
   311   }
   307   assert(i == num_boot_classpath_entries,
   312   assert(i == num_boot_classpath_entries,
   312   while (acpe != NULL) {
   317   while (acpe != NULL) {
   313     log_info(class, path)("add app shared path %s", acpe->name());
   318     log_info(class, path)("add app shared path %s", acpe->name());
   314     SharedClassPathEntry* ent = shared_path(i);
   319     SharedClassPathEntry* ent = shared_path(i);
   315     ent->init(acpe->name(), THREAD);
   320     ent->init(acpe->name(), THREAD);
   316     EXCEPTION_MARK;
   321     EXCEPTION_MARK;
   317     SharedClassUtil::update_shared_classpath(acpe, ent, THREAD);
   322     update_shared_classpath(acpe, ent, THREAD);
   318     acpe = acpe->next();
   323     acpe = acpe->next();
   319     i++;
   324     i++;
   320   }
   325   }
   321 
   326 
   322   // 3. module path
   327   // 3. module path
   324   while (mpe != NULL) {
   329   while (mpe != NULL) {
   325     log_info(class, path)("add module path %s",mpe->name());
   330     log_info(class, path)("add module path %s",mpe->name());
   326     SharedClassPathEntry* ent = shared_path(i);
   331     SharedClassPathEntry* ent = shared_path(i);
   327     ent->init(mpe->name(), THREAD);
   332     ent->init(mpe->name(), THREAD);
   328     EXCEPTION_MARK;
   333     EXCEPTION_MARK;
   329     SharedClassUtil::update_shared_classpath(mpe, ent, THREAD);
   334     update_shared_classpath(mpe, ent, THREAD);
   330     mpe = mpe->next();
   335     mpe = mpe->next();
   331     i++;
   336     i++;
   332   }
   337   }
   333   assert(i == num_entries, "number of shared path entry mismatch");
   338   assert(i == num_entries, "number of shared path entry mismatch");
   334 }
   339 }
   358   if (has_nonempty_dir) {
   363   if (has_nonempty_dir) {
   359     ClassLoader::exit_with_path_failure("Cannot have non-empty directory in paths", NULL);
   364     ClassLoader::exit_with_path_failure("Cannot have non-empty directory in paths", NULL);
   360   }
   365   }
   361 }
   366 }
   362 
   367 
       
   368 class ManifestStream: public ResourceObj {
       
   369   private:
       
   370   u1*   _buffer_start; // Buffer bottom
       
   371   u1*   _buffer_end;   // Buffer top (one past last element)
       
   372   u1*   _current;      // Current buffer position
       
   373 
       
   374  public:
       
   375   // Constructor
       
   376   ManifestStream(u1* buffer, int length) : _buffer_start(buffer),
       
   377                                            _current(buffer) {
       
   378     _buffer_end = buffer + length;
       
   379   }
       
   380 
       
   381   static bool is_attr(u1* attr, const char* name) {
       
   382     return strncmp((const char*)attr, name, strlen(name)) == 0;
       
   383   }
       
   384 
       
   385   static char* copy_attr(u1* value, size_t len) {
       
   386     char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
       
   387     strncpy(buf, (char*)value, len);
       
   388     buf[len] = 0;
       
   389     return buf;
       
   390   }
       
   391 
       
   392   // The return value indicates if the JAR is signed or not
       
   393   bool check_is_signed() {
       
   394     u1* attr = _current;
       
   395     bool isSigned = false;
       
   396     while (_current < _buffer_end) {
       
   397       if (*_current == '\n') {
       
   398         *_current = '\0';
       
   399         u1* value = (u1*)strchr((char*)attr, ':');
       
   400         if (value != NULL) {
       
   401           assert(*(value+1) == ' ', "Unrecognized format" );
       
   402           if (strstr((char*)attr, "-Digest") != NULL) {
       
   403             isSigned = true;
       
   404             break;
       
   405           }
       
   406         }
       
   407         *_current = '\n'; // restore
       
   408         attr = _current + 1;
       
   409       }
       
   410       _current ++;
       
   411     }
       
   412     return isSigned;
       
   413   }
       
   414 };
       
   415 
       
   416 void FileMapInfo::update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) {
       
   417   ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
       
   418   ResourceMark rm(THREAD);
       
   419   jint manifest_size;
       
   420   bool isSigned;
       
   421 
       
   422   if (cpe->is_jar_file()) {
       
   423     char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK);
       
   424     if (manifest != NULL) {
       
   425       ManifestStream* stream = new ManifestStream((u1*)manifest,
       
   426                                                   manifest_size);
       
   427       isSigned = stream->check_is_signed();
       
   428       if (isSigned) {
       
   429         ent->set_is_signed(true);
       
   430       } else {
       
   431         // Copy the manifest into the shared archive
       
   432         manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK);
       
   433         Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
       
   434                                                         manifest_size,
       
   435                                                         THREAD);
       
   436         char* p = (char*)(buf->data());
       
   437         memcpy(p, manifest, manifest_size);
       
   438         ent->set_manifest(buf);
       
   439         ent->set_is_signed(false);
       
   440       }
       
   441     }
       
   442   }
       
   443 }
       
   444 
       
   445 
   363 bool FileMapInfo::validate_shared_path_table() {
   446 bool FileMapInfo::validate_shared_path_table() {
   364   assert(UseSharedSpaces, "runtime only");
   447   assert(UseSharedSpaces, "runtime only");
   365 
   448 
   366   _validating_shared_path_table = true;
   449   _validating_shared_path_table = true;
   367   _shared_path_table = _header->_shared_path_table;
   450   _shared_path_table = _header->_shared_path_table;
   368   _shared_path_entry_size = _header->_shared_path_entry_size;
   451   _shared_path_entry_size = _header->_shared_path_entry_size;
   369   _shared_path_table_size = _header->_shared_path_table_size;
   452   _shared_path_table_size = _header->_shared_path_table_size;
   370 
   453 
   371   FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
   454   int module_paths_start_index = _header->_app_module_paths_start_index;
   372   int module_paths_start_index = header->_app_module_paths_start_index;
       
   373 
   455 
   374   // If the shared archive contain app or platform classes, validate all entries
   456   // If the shared archive contain app or platform classes, validate all entries
   375   // in the shared path table. Otherwise, only validate the boot path entries (with
   457   // in the shared path table. Otherwise, only validate the boot path entries (with
   376   // entry index < _app_class_paths_start_index).
   458   // entry index < _app_class_paths_start_index).
   377   int count = header->has_platform_or_app_classes() ?
   459   int count = _header->has_platform_or_app_classes() ?
   378               _shared_path_table_size : header->_app_class_paths_start_index;
   460               _shared_path_table_size : _header->_app_class_paths_start_index;
   379 
   461 
   380   for (int i=0; i<count; i++) {
   462   for (int i=0; i<count; i++) {
   381     if (i < module_paths_start_index) {
   463     if (i < module_paths_start_index) {
   382       if (shared_path(i)->validate()) {
   464       if (shared_path(i)->validate()) {
   383         log_info(class, path)("ok");
   465         log_info(class, path)("ok");
  1076                   _compact_strings ? "enabled" : "disabled",
  1158                   _compact_strings ? "enabled" : "disabled",
  1077                   CompactStrings   ? "enabled" : "disabled");
  1159                   CompactStrings   ? "enabled" : "disabled");
  1078     return false;
  1160     return false;
  1079   }
  1161   }
  1080 
  1162 
       
  1163   // This must be done after header validation because it might change the
       
  1164   // header data
       
  1165   const char* prop = Arguments::get_property("java.system.class.loader");
       
  1166   if (prop != NULL) {
       
  1167     warning("Archived non-system classes are disabled because the "
       
  1168             "java.system.class.loader property is specified (value = \"%s\"). "
       
  1169             "To use archived non-system classes, this property must be not be set", prop);
       
  1170     _has_platform_or_app_classes = false;
       
  1171   }
       
  1172 
       
  1173   // For backwards compatibility, we don't check the verification setting
       
  1174   // if the archive only contains system classes.
       
  1175   if (_has_platform_or_app_classes &&
       
  1176       ((!_verify_local && BytecodeVerificationLocal) ||
       
  1177        (!_verify_remote && BytecodeVerificationRemote))) {
       
  1178     FileMapInfo::fail_continue("The shared archive file was created with less restrictive "
       
  1179                   "verification setting than the current setting.");
       
  1180     return false;
       
  1181   }
       
  1182 
  1081   return true;
  1183   return true;
  1082 }
  1184 }
  1083 
  1185 
  1084 bool FileMapInfo::validate_header() {
  1186 bool FileMapInfo::validate_header() {
  1085   bool status = _header->validate();
  1187   bool status = _header->validate();