8140802: Clean up and refactor of class loading code for CDS
Reviewed-by: jiangli, acorn, coleenp
This commit is contained in:
parent
0580d65a1c
commit
87b0df30ed
@ -73,8 +73,9 @@ ifeq ($(INCLUDE_CDS), false)
|
|||||||
CXXFLAGS += -DINCLUDE_CDS=0
|
CXXFLAGS += -DINCLUDE_CDS=0
|
||||||
CFLAGS += -DINCLUDE_CDS=0
|
CFLAGS += -DINCLUDE_CDS=0
|
||||||
|
|
||||||
Src_Files_EXCLUDE += filemap.cpp metaspaceShared*.cpp sharedPathsMiscInfo.cpp \
|
Src_Files_EXCLUDE += classListParser.cpp classLoaderExt.cpp \
|
||||||
systemDictionaryShared.cpp classLoaderExt.cpp sharedClassUtil.cpp
|
filemap.cpp metaspaceShared*.cpp sharedClassUtil.cpp sharedPathsMiscInfo.cpp \
|
||||||
|
systemDictionaryShared.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(INCLUDE_ALL_GCS), false)
|
ifeq ($(INCLUDE_ALL_GCS), false)
|
||||||
|
66
hotspot/src/share/vm/classfile/classListParser.cpp
Normal file
66
hotspot/src/share/vm/classfile/classListParser.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.hpp"
|
||||||
|
#include "classfile/classListParser.hpp"
|
||||||
|
#include "runtime/os.hpp"
|
||||||
|
#include "runtime/java.hpp"
|
||||||
|
|
||||||
|
ClassListParser::ClassListParser(const char* file) {
|
||||||
|
_classlist_file = file;
|
||||||
|
_file = fopen(file, "r");
|
||||||
|
if (_file == NULL) {
|
||||||
|
char errmsg[JVM_MAXPATHLEN];
|
||||||
|
os::lasterror(errmsg, JVM_MAXPATHLEN);
|
||||||
|
vm_exit_during_initialization("Loading classlist failed", errmsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassListParser::~ClassListParser() {
|
||||||
|
if (_file) {
|
||||||
|
fclose(_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClassListParser::parse_one_line() {
|
||||||
|
for (;;) {
|
||||||
|
if (fgets(_line, sizeof(_line), _file) == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int line_len = (int)strlen(_line);
|
||||||
|
if (line_len > _max_allowed_line_len) {
|
||||||
|
tty->print_cr("input line too long (must be no longer than %d chars)", _max_allowed_line_len);
|
||||||
|
vm_exit_during_initialization("Loading classlist failed");
|
||||||
|
}
|
||||||
|
if (*_line == '#') { // comment
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove trailing \r\n
|
||||||
|
_line[strcspn(_line, "\r\n")] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
56
hotspot/src/share/vm/classfile/classListParser.hpp
Normal file
56
hotspot/src/share/vm/classfile/classListParser.hpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHARE_VM_MEMORY_CLASSLISTPARSER_HPP
|
||||||
|
#define SHARE_VM_MEMORY_CLASSLISTPARSER_HPP
|
||||||
|
|
||||||
|
#include "utilities/exceptions.hpp"
|
||||||
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
|
||||||
|
class ClassListParser : public StackObj {
|
||||||
|
enum {
|
||||||
|
// Max number of bytes allowed per line in the classlist.
|
||||||
|
// Theoretically Java class names could be 65535 bytes in length. In reality,
|
||||||
|
// 4K bytes is more than enough.
|
||||||
|
_max_allowed_line_len = 4096,
|
||||||
|
_line_buf_extra = 10, // for detecting input too long
|
||||||
|
_line_buf_size = _max_allowed_line_len + _line_buf_extra
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* _classlist_file;
|
||||||
|
FILE* _file;
|
||||||
|
char _line[_line_buf_size]; // The buffer that holds the current line.
|
||||||
|
|
||||||
|
public:
|
||||||
|
ClassListParser(const char* file);
|
||||||
|
~ClassListParser();
|
||||||
|
bool parse_one_line();
|
||||||
|
|
||||||
|
const char* current_class_name() {
|
||||||
|
return _line;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SHARE_VM_MEMORY_CLASSLISTPARSER_HPP
|
@ -82,7 +82,7 @@ ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Depen
|
|||||||
_keep_alive(is_anonymous || h_class_loader.is_null()),
|
_keep_alive(is_anonymous || h_class_loader.is_null()),
|
||||||
_metaspace(NULL), _unloading(false), _klasses(NULL),
|
_metaspace(NULL), _unloading(false), _klasses(NULL),
|
||||||
_claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
|
_claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
|
||||||
_next(NULL), _dependencies(dependencies),
|
_next(NULL), _dependencies(dependencies), _shared_class_loader_id(-1),
|
||||||
_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
|
_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
|
||||||
Monitor::_safepoint_check_never)) {
|
Monitor::_safepoint_check_never)) {
|
||||||
// empty
|
// empty
|
||||||
|
@ -187,6 +187,9 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||||||
// Support for walking class loader data objects
|
// Support for walking class loader data objects
|
||||||
ClassLoaderData* _next; /// Next loader_datas created
|
ClassLoaderData* _next; /// Next loader_datas created
|
||||||
|
|
||||||
|
// CDS
|
||||||
|
int _shared_class_loader_id;
|
||||||
|
|
||||||
// ReadOnly and ReadWrite metaspaces (static because only on the null
|
// ReadOnly and ReadWrite metaspaces (static because only on the null
|
||||||
// class loader for now).
|
// class loader for now).
|
||||||
static Metaspace* _ro_metaspace;
|
static Metaspace* _ro_metaspace;
|
||||||
@ -308,6 +311,15 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||||||
Metaspace* ro_metaspace();
|
Metaspace* ro_metaspace();
|
||||||
Metaspace* rw_metaspace();
|
Metaspace* rw_metaspace();
|
||||||
void initialize_shared_metaspaces();
|
void initialize_shared_metaspaces();
|
||||||
|
|
||||||
|
int shared_class_loader_id() {
|
||||||
|
return _shared_class_loader_id;
|
||||||
|
}
|
||||||
|
void set_shared_class_loader_id(int id) {
|
||||||
|
assert(id >= 0, "sanity");
|
||||||
|
assert(_shared_class_loader_id <0, "cannot be assigned more than once");
|
||||||
|
_shared_class_loader_id = id;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// An iterator that distributes Klasses to parallel worker threads.
|
// An iterator that distributes Klasses to parallel worker threads.
|
||||||
|
36
hotspot/src/share/vm/classfile/classLoaderExt.cpp
Normal file
36
hotspot/src/share/vm/classfile/classLoaderExt.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.hpp"
|
||||||
|
#include "classfile/classListParser.hpp"
|
||||||
|
#include "classfile/classLoaderExt.hpp"
|
||||||
|
#include "classfile/symbolTable.hpp"
|
||||||
|
#include "classfile/systemDictionary.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
Klass* ClassLoaderExt::load_one_class(ClassListParser* parser, TRAPS) {
|
||||||
|
TempNewSymbol class_name_symbol = SymbolTable::new_symbol(parser->current_class_name(), THREAD);
|
||||||
|
guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
|
||||||
|
return SystemDictionary::resolve_or_null(class_name_symbol, THREAD);
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -29,6 +29,8 @@
|
|||||||
#include "oops/instanceKlass.hpp"
|
#include "oops/instanceKlass.hpp"
|
||||||
#include "runtime/handles.hpp"
|
#include "runtime/handles.hpp"
|
||||||
|
|
||||||
|
class ClassListParser;
|
||||||
|
|
||||||
class ClassLoaderExt: public ClassLoader { // AllStatic
|
class ClassLoaderExt: public ClassLoader { // AllStatic
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -69,6 +71,7 @@ public:
|
|||||||
ClassLoader::add_to_list(new_entry);
|
ClassLoader::add_to_list(new_entry);
|
||||||
}
|
}
|
||||||
static void setup_search_paths() {}
|
static void setup_search_paths() {}
|
||||||
|
static Klass* load_one_class(ClassListParser* parser, TRAPS);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
|
#endif // SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
|
||||||
|
@ -23,8 +23,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
|
#include "classfile/sharedClassUtil.hpp"
|
||||||
#include "classfile/dictionary.hpp"
|
#include "classfile/dictionary.hpp"
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
|
#include "classfile/systemDictionaryShared.hpp"
|
||||||
#include "memory/iterator.hpp"
|
#include "memory/iterator.hpp"
|
||||||
#include "oops/oop.inline.hpp"
|
#include "oops/oop.inline.hpp"
|
||||||
#include "prims/jvmtiRedefineClassesTrace.hpp"
|
#include "prims/jvmtiRedefineClassesTrace.hpp"
|
||||||
@ -34,9 +36,16 @@
|
|||||||
DictionaryEntry* Dictionary::_current_class_entry = NULL;
|
DictionaryEntry* Dictionary::_current_class_entry = NULL;
|
||||||
int Dictionary::_current_class_index = 0;
|
int Dictionary::_current_class_index = 0;
|
||||||
|
|
||||||
|
size_t Dictionary::entry_size() {
|
||||||
|
if (DumpSharedSpaces) {
|
||||||
|
return SystemDictionaryShared::dictionary_entry_size();
|
||||||
|
} else {
|
||||||
|
return sizeof(DictionaryEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Dictionary::Dictionary(int table_size)
|
Dictionary::Dictionary(int table_size)
|
||||||
: TwoOopHashtable<Klass*, mtClass>(table_size, sizeof(DictionaryEntry)) {
|
: TwoOopHashtable<Klass*, mtClass>(table_size, (int)entry_size()) {
|
||||||
_current_class_index = 0;
|
_current_class_index = 0;
|
||||||
_current_class_entry = NULL;
|
_current_class_entry = NULL;
|
||||||
_pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);
|
_pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);
|
||||||
@ -45,7 +54,7 @@ Dictionary::Dictionary(int table_size)
|
|||||||
|
|
||||||
Dictionary::Dictionary(int table_size, HashtableBucket<mtClass>* t,
|
Dictionary::Dictionary(int table_size, HashtableBucket<mtClass>* t,
|
||||||
int number_of_entries)
|
int number_of_entries)
|
||||||
: TwoOopHashtable<Klass*, mtClass>(table_size, sizeof(DictionaryEntry), t, number_of_entries) {
|
: TwoOopHashtable<Klass*, mtClass>(table_size, (int)entry_size(), t, number_of_entries) {
|
||||||
_current_class_index = 0;
|
_current_class_index = 0;
|
||||||
_current_class_entry = NULL;
|
_current_class_entry = NULL;
|
||||||
_pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);
|
_pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);
|
||||||
@ -61,6 +70,9 @@ DictionaryEntry* Dictionary::new_entry(unsigned int hash, Klass* klass,
|
|||||||
entry->set_loader_data(loader_data);
|
entry->set_loader_data(loader_data);
|
||||||
entry->set_pd_set(NULL);
|
entry->set_pd_set(NULL);
|
||||||
assert(klass->is_instance_klass(), "Must be");
|
assert(klass->is_instance_klass(), "Must be");
|
||||||
|
if (DumpSharedSpaces) {
|
||||||
|
SystemDictionaryShared::init_shared_dictionary_entry(klass, entry);
|
||||||
|
}
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ private:
|
|||||||
DictionaryEntry* get_entry(int index, unsigned int hash,
|
DictionaryEntry* get_entry(int index, unsigned int hash,
|
||||||
Symbol* name, ClassLoaderData* loader_data);
|
Symbol* name, ClassLoaderData* loader_data);
|
||||||
|
|
||||||
|
protected:
|
||||||
DictionaryEntry* bucket(int i) {
|
DictionaryEntry* bucket(int i) {
|
||||||
return (DictionaryEntry*)Hashtable<Klass*, mtClass>::bucket(i);
|
return (DictionaryEntry*)Hashtable<Klass*, mtClass>::bucket(i);
|
||||||
}
|
}
|
||||||
@ -66,6 +67,7 @@ private:
|
|||||||
Hashtable<Klass*, mtClass>::add_entry(index, (HashtableEntry<Klass*, mtClass>*)new_entry);
|
Hashtable<Klass*, mtClass>::add_entry(index, (HashtableEntry<Klass*, mtClass>*)new_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t entry_size();
|
||||||
public:
|
public:
|
||||||
Dictionary(int table_size);
|
Dictionary(int table_size);
|
||||||
Dictionary(int table_size, HashtableBucket<mtClass>* t, int number_of_entries);
|
Dictionary(int table_size, HashtableBucket<mtClass>* t, int number_of_entries);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#ifndef SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
|
#ifndef SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
|
||||||
#define SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
|
#define SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
|
||||||
|
|
||||||
|
#include "classfile/classLoader.hpp"
|
||||||
#include "runtime/os.hpp"
|
#include "runtime/os.hpp"
|
||||||
|
|
||||||
// During dumping time, when processing class paths, we build up the dump-time
|
// During dumping time, when processing class paths, we build up the dump-time
|
||||||
@ -106,19 +107,6 @@ public:
|
|||||||
add_path(path, NON_EXIST);
|
add_path(path, NON_EXIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The path must exist and have required size and modification time
|
|
||||||
void add_required_file(const char* path) {
|
|
||||||
add_path(path, REQUIRED);
|
|
||||||
|
|
||||||
struct stat st;
|
|
||||||
if (os::stat(path, &st) != 0) {
|
|
||||||
assert(0, "sanity");
|
|
||||||
ClassLoader::exit_with_path_failure("failed to os::stat(%s)", path); // should not happen
|
|
||||||
}
|
|
||||||
write_time(st.st_mtime);
|
|
||||||
write_long(st.st_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The path must exist, and must contain exactly <num_entries> files/dirs
|
// The path must exist, and must contain exactly <num_entries> files/dirs
|
||||||
void add_boot_classpath(const char* path) {
|
void add_boot_classpath(const char* path) {
|
||||||
add_path(path, BOOT);
|
add_path(path, BOOT);
|
||||||
|
@ -322,6 +322,17 @@ Klass* SystemDictionary::resolve_super_or_fail(Symbol* child_name,
|
|||||||
Handle protection_domain,
|
Handle protection_domain,
|
||||||
bool is_superclass,
|
bool is_superclass,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
|
#if INCLUDE_CDS
|
||||||
|
if (DumpSharedSpaces) {
|
||||||
|
// Special processing for CDS dump time.
|
||||||
|
Klass* k = SystemDictionaryShared::dump_time_resolve_super_or_fail(child_name,
|
||||||
|
class_name, class_loader, protection_domain, is_superclass, CHECK_NULL);
|
||||||
|
if (k) {
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // INCLUDE_CDS
|
||||||
|
|
||||||
// Double-check, if child class is already loaded, just return super-class,interface
|
// Double-check, if child class is already loaded, just return super-class,interface
|
||||||
// Don't add a placedholder if already loaded, i.e. already in system dictionary
|
// Don't add a placedholder if already loaded, i.e. already in system dictionary
|
||||||
// Make sure there's a placeholder for the *child* before resolving.
|
// Make sure there's a placeholder for the *child* before resolving.
|
||||||
@ -1079,12 +1090,30 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
|
|||||||
//
|
//
|
||||||
// Note: "name" is updated.
|
// Note: "name" is updated.
|
||||||
|
|
||||||
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
|
instanceKlassHandle k;
|
||||||
|
|
||||||
|
#if INCLUDE_CDS
|
||||||
|
k = SystemDictionaryShared::lookup_from_stream(class_name,
|
||||||
|
class_loader,
|
||||||
|
protection_domain,
|
||||||
|
st,
|
||||||
|
verify,
|
||||||
|
CHECK_NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (k.not_null()) {
|
||||||
|
parsed_name = k->name();
|
||||||
|
} else {
|
||||||
|
if (st->buffer() == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
k = ClassFileParser(st).parseClassFile(class_name,
|
||||||
loader_data,
|
loader_data,
|
||||||
protection_domain,
|
protection_domain,
|
||||||
parsed_name,
|
parsed_name,
|
||||||
verify,
|
verify,
|
||||||
THREAD);
|
THREAD);
|
||||||
|
}
|
||||||
|
|
||||||
const char* pkg = "java/";
|
const char* pkg = "java/";
|
||||||
if (!HAS_PENDING_EXCEPTION &&
|
if (!HAS_PENDING_EXCEPTION &&
|
||||||
@ -1201,8 +1230,13 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
|
|||||||
|
|
||||||
if (ik->super() != NULL) {
|
if (ik->super() != NULL) {
|
||||||
Symbol* cn = ik->super()->name();
|
Symbol* cn = ik->super()->name();
|
||||||
resolve_super_or_fail(class_name, cn,
|
Klass *s = resolve_super_or_fail(class_name, cn,
|
||||||
class_loader, protection_domain, true, CHECK_(nh));
|
class_loader, protection_domain, true, CHECK_(nh));
|
||||||
|
if (s != ik->super()) {
|
||||||
|
// The dynamically resolved super class is not the same as the one we used during dump time,
|
||||||
|
// so we cannot use ik.
|
||||||
|
return nh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Array<Klass*>* interfaces = ik->local_interfaces();
|
Array<Klass*>* interfaces = ik->local_interfaces();
|
||||||
@ -1215,7 +1249,12 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
|
|||||||
// reinitialized yet (they will be once the interface classes
|
// reinitialized yet (they will be once the interface classes
|
||||||
// are loaded)
|
// are loaded)
|
||||||
Symbol* name = k->name();
|
Symbol* name = k->name();
|
||||||
resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_(nh));
|
Klass* i = resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_(nh));
|
||||||
|
if (k != i) {
|
||||||
|
// The dynamically resolved interface class is not the same as the one we used during dump time,
|
||||||
|
// so we cannot use ik.
|
||||||
|
return nh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust methods to recover missing data. They need addresses for
|
// Adjust methods to recover missing data. They need addresses for
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "classfile/classFileStream.hpp"
|
#include "classfile/classFileStream.hpp"
|
||||||
#include "classfile/classLoader.hpp"
|
#include "classfile/classLoader.hpp"
|
||||||
|
#include "classfile/systemDictionary_ext.hpp"
|
||||||
#include "oops/objArrayOop.hpp"
|
#include "oops/objArrayOop.hpp"
|
||||||
#include "oops/symbol.hpp"
|
#include "oops/symbol.hpp"
|
||||||
#include "runtime/java.hpp"
|
#include "runtime/java.hpp"
|
||||||
@ -194,15 +195,18 @@ class Ticks;
|
|||||||
do_klass(Integer_klass, java_lang_Integer, Pre ) \
|
do_klass(Integer_klass, java_lang_Integer, Pre ) \
|
||||||
do_klass(Long_klass, java_lang_Long, Pre ) \
|
do_klass(Long_klass, java_lang_Long, Pre ) \
|
||||||
\
|
\
|
||||||
|
/* Extensions */ \
|
||||||
|
WK_KLASSES_DO_EXT(do_klass) \
|
||||||
/* JVMCI classes. These are loaded on-demand. */ \
|
/* JVMCI classes. These are loaded on-demand. */ \
|
||||||
JVMCI_WK_KLASSES_DO(do_klass) \
|
JVMCI_WK_KLASSES_DO(do_klass) \
|
||||||
|
\
|
||||||
/*end*/
|
/*end*/
|
||||||
|
|
||||||
|
|
||||||
class SystemDictionary : AllStatic {
|
class SystemDictionary : AllStatic {
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
friend class SystemDictionaryHandles;
|
friend class SystemDictionaryHandles;
|
||||||
|
friend class SharedClassUtil;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum WKID {
|
enum WKID {
|
||||||
@ -667,11 +671,6 @@ protected:
|
|||||||
// Basic find on classes in the midst of being loaded
|
// Basic find on classes in the midst of being loaded
|
||||||
static Symbol* find_placeholder(Symbol* name, ClassLoaderData* loader_data);
|
static Symbol* find_placeholder(Symbol* name, ClassLoaderData* loader_data);
|
||||||
|
|
||||||
// Updating entry in dictionary
|
|
||||||
// Add a completely loaded class
|
|
||||||
static void add_klass(int index, Symbol* class_name,
|
|
||||||
ClassLoaderData* loader_data, KlassHandle obj);
|
|
||||||
|
|
||||||
// Add a placeholder for a class being loaded
|
// Add a placeholder for a class being loaded
|
||||||
static void add_placeholder(int index,
|
static void add_placeholder(int index,
|
||||||
Symbol* class_name,
|
Symbol* class_name,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,11 +22,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
|
#ifndef SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
|
||||||
#define SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
|
#define SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
|
||||||
|
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
|
#include "classfile/dictionary.hpp"
|
||||||
|
|
||||||
|
class ClassFileStream;
|
||||||
|
|
||||||
class SystemDictionaryShared: public SystemDictionary {
|
class SystemDictionaryShared: public SystemDictionary {
|
||||||
public:
|
public:
|
||||||
@ -42,6 +44,30 @@ public:
|
|||||||
oop class_loader = loader_data->class_loader();
|
oop class_loader = loader_data->class_loader();
|
||||||
return (class_loader == NULL);
|
return (class_loader == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Klass* dump_time_resolve_super_or_fail(Symbol* child_name,
|
||||||
|
Symbol* class_name,
|
||||||
|
Handle class_loader,
|
||||||
|
Handle protection_domain,
|
||||||
|
bool is_superclass,
|
||||||
|
TRAPS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t dictionary_entry_size() {
|
||||||
|
return sizeof(DictionaryEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_shared_dictionary_entry(Klass* k, DictionaryEntry* entry) {}
|
||||||
|
|
||||||
|
static InstanceKlass* lookup_from_stream(Symbol* class_name,
|
||||||
|
Handle class_loader,
|
||||||
|
Handle protection_domain,
|
||||||
|
ClassFileStream* st,
|
||||||
|
bool verify,
|
||||||
|
TRAPS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
|
#endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
|
||||||
|
30
hotspot/src/share/vm/classfile/systemDictionary_ext.hpp
Normal file
30
hotspot/src/share/vm/classfile/systemDictionary_ext.hpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
|
||||||
|
#define SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
|
||||||
|
|
||||||
|
#define WK_KLASSES_DO_EXT(do_klass)
|
||||||
|
|
||||||
|
#endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
|
@ -25,6 +25,7 @@
|
|||||||
#ifndef SHARE_VM_CLASSFILE_VMSYMBOLS_HPP
|
#ifndef SHARE_VM_CLASSFILE_VMSYMBOLS_HPP
|
||||||
#define SHARE_VM_CLASSFILE_VMSYMBOLS_HPP
|
#define SHARE_VM_CLASSFILE_VMSYMBOLS_HPP
|
||||||
|
|
||||||
|
#include "classfile/vmSymbols_ext.hpp"
|
||||||
#include "oops/symbol.hpp"
|
#include "oops/symbol.hpp"
|
||||||
#include "memory/iterator.hpp"
|
#include "memory/iterator.hpp"
|
||||||
#include "trace/traceMacros.hpp"
|
#include "trace/traceMacros.hpp"
|
||||||
@ -617,6 +618,9 @@
|
|||||||
/* trace signatures */ \
|
/* trace signatures */ \
|
||||||
TRACE_TEMPLATES(template) \
|
TRACE_TEMPLATES(template) \
|
||||||
\
|
\
|
||||||
|
/* extensions */ \
|
||||||
|
VM_SYMBOLS_DO_EXT(template, do_alias) \
|
||||||
|
\
|
||||||
/*end*/
|
/*end*/
|
||||||
|
|
||||||
// Here are all the intrinsics known to the runtime and the CI.
|
// Here are all the intrinsics known to the runtime and the CI.
|
||||||
|
31
hotspot/src/share/vm/classfile/vmSymbols_ext.hpp
Normal file
31
hotspot/src/share/vm/classfile/vmSymbols_ext.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHARE_VM_CLASSFILE_VMSYMBOLS_EXT_HPP
|
||||||
|
#define SHARE_VM_CLASSFILE_VMSYMBOLS_EXT_HPP
|
||||||
|
|
||||||
|
#define VM_SYMBOLS_DO_EXT(template, do_alias)
|
||||||
|
|
||||||
|
#endif // SHARE_VM_CLASSFILE_VMSYMBOLS_EXT_HPP
|
||||||
|
|
@ -23,6 +23,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
|
#include "classfile/classListParser.hpp"
|
||||||
|
#include "classfile/classLoaderExt.hpp"
|
||||||
#include "classfile/dictionary.hpp"
|
#include "classfile/dictionary.hpp"
|
||||||
#include "classfile/loaderConstraints.hpp"
|
#include "classfile/loaderConstraints.hpp"
|
||||||
#include "classfile/placeholders.hpp"
|
#include "classfile/placeholders.hpp"
|
||||||
@ -42,6 +44,7 @@
|
|||||||
#include "runtime/signature.hpp"
|
#include "runtime/signature.hpp"
|
||||||
#include "runtime/vmThread.hpp"
|
#include "runtime/vmThread.hpp"
|
||||||
#include "runtime/vm_operations.hpp"
|
#include "runtime/vm_operations.hpp"
|
||||||
|
#include "utilities/defaultStream.hpp"
|
||||||
#include "utilities/hashtable.inline.hpp"
|
#include "utilities/hashtable.inline.hpp"
|
||||||
|
|
||||||
int MetaspaceShared::_max_alignment = 0;
|
int MetaspaceShared::_max_alignment = 0;
|
||||||
@ -97,6 +100,10 @@ static void collect_classes(Klass* k) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void collect_classes2(Klass* k, ClassLoaderData* class_data) {
|
||||||
|
collect_classes(k);
|
||||||
|
}
|
||||||
|
|
||||||
static void remove_unshareable_in_classes() {
|
static void remove_unshareable_in_classes() {
|
||||||
for (int i = 0; i < _global_klass_objects->length(); i++) {
|
for (int i = 0; i < _global_klass_objects->length(); i++) {
|
||||||
Klass* k = _global_klass_objects->at(i);
|
Klass* k = _global_klass_objects->at(i);
|
||||||
@ -422,12 +429,15 @@ private:
|
|||||||
VirtualSpace _mc_vs;
|
VirtualSpace _mc_vs;
|
||||||
CompactHashtableWriter* _string_cht;
|
CompactHashtableWriter* _string_cht;
|
||||||
GrowableArray<MemRegion> *_string_regions;
|
GrowableArray<MemRegion> *_string_regions;
|
||||||
|
char* _md_alloc_low;
|
||||||
|
char* _md_alloc_top;
|
||||||
|
char* _md_alloc_max;
|
||||||
|
static VM_PopulateDumpSharedSpace* _instance;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VM_PopulateDumpSharedSpace(ClassLoaderData* loader_data,
|
VM_PopulateDumpSharedSpace(ClassLoaderData* loader_data,
|
||||||
GrowableArray<Klass*> *class_promote_order) :
|
GrowableArray<Klass*> *class_promote_order) :
|
||||||
_loader_data(loader_data) {
|
_loader_data(loader_data) {
|
||||||
|
|
||||||
// Split up and initialize the misc code and data spaces
|
// Split up and initialize the misc code and data spaces
|
||||||
ReservedSpace* shared_rs = MetaspaceShared::shared_rs();
|
ReservedSpace* shared_rs = MetaspaceShared::shared_rs();
|
||||||
size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize;
|
size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize;
|
||||||
@ -440,11 +450,43 @@ public:
|
|||||||
_md_vs.initialize(md_rs, SharedMiscDataSize);
|
_md_vs.initialize(md_rs, SharedMiscDataSize);
|
||||||
_mc_vs.initialize(mc_rs, SharedMiscCodeSize);
|
_mc_vs.initialize(mc_rs, SharedMiscCodeSize);
|
||||||
_class_promote_order = class_promote_order;
|
_class_promote_order = class_promote_order;
|
||||||
|
|
||||||
|
_md_alloc_low = _md_vs.low();
|
||||||
|
_md_alloc_top = _md_alloc_low + sizeof(char*);
|
||||||
|
_md_alloc_max = _md_vs.low() + SharedMiscDataSize;
|
||||||
|
|
||||||
|
assert(_instance == NULL, "must be singleton");
|
||||||
|
_instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~VM_PopulateDumpSharedSpace() {
|
||||||
|
assert(_instance == this, "must be singleton");
|
||||||
|
_instance = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VM_PopulateDumpSharedSpace* instance() {
|
||||||
|
assert(_instance != NULL, "sanity");
|
||||||
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
|
VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
|
||||||
void doit(); // outline because gdb sucks
|
void doit(); // outline because gdb sucks
|
||||||
|
|
||||||
|
char* misc_data_space_alloc(size_t num_bytes) {
|
||||||
|
size_t alignment = sizeof(char*);
|
||||||
|
num_bytes = align_size_up(num_bytes, alignment);
|
||||||
|
_md_alloc_top = (char*)align_ptr_up(_md_alloc_top, alignment);
|
||||||
|
if (_md_alloc_top + num_bytes > _md_alloc_max) {
|
||||||
|
report_out_of_shared_space(SharedMiscData);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* p = _md_alloc_top;
|
||||||
|
_md_alloc_top += num_bytes;
|
||||||
|
|
||||||
|
memset(p, 0, num_bytes);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handle_misc_data_space_failure(bool success) {
|
void handle_misc_data_space_failure(bool success) {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
@ -453,6 +495,7 @@ private:
|
|||||||
}
|
}
|
||||||
}; // class VM_PopulateDumpSharedSpace
|
}; // class VM_PopulateDumpSharedSpace
|
||||||
|
|
||||||
|
VM_PopulateDumpSharedSpace* VM_PopulateDumpSharedSpace::_instance;
|
||||||
|
|
||||||
void VM_PopulateDumpSharedSpace::doit() {
|
void VM_PopulateDumpSharedSpace::doit() {
|
||||||
Thread* THREAD = VMThread::vm_thread();
|
Thread* THREAD = VMThread::vm_thread();
|
||||||
@ -475,7 +518,11 @@ void VM_PopulateDumpSharedSpace::doit() {
|
|||||||
// that so we don't have to walk the SystemDictionary again.
|
// that so we don't have to walk the SystemDictionary again.
|
||||||
_global_klass_objects = new GrowableArray<Klass*>(1000);
|
_global_klass_objects = new GrowableArray<Klass*>(1000);
|
||||||
Universe::basic_type_classes_do(collect_classes);
|
Universe::basic_type_classes_do(collect_classes);
|
||||||
SystemDictionary::classes_do(collect_classes);
|
|
||||||
|
// Need to call SystemDictionary::classes_do(void f(Klass*, ClassLoaderData*))
|
||||||
|
// as we may have some classes with NULL ClassLoaderData* in the dictionary. Other
|
||||||
|
// variants of SystemDictionary::classes_do will skip those classes.
|
||||||
|
SystemDictionary::classes_do(collect_classes2);
|
||||||
|
|
||||||
tty->print_cr("Number of classes %d", _global_klass_objects->length());
|
tty->print_cr("Number of classes %d", _global_klass_objects->length());
|
||||||
{
|
{
|
||||||
@ -515,6 +562,10 @@ void VM_PopulateDumpSharedSpace::doit() {
|
|||||||
char* mc_top = mc_low;
|
char* mc_top = mc_low;
|
||||||
char* mc_end = _mc_vs.high();
|
char* mc_end = _mc_vs.high();
|
||||||
|
|
||||||
|
assert(_md_alloc_top != NULL, "sanity");
|
||||||
|
*(char**)_md_alloc_low = _md_alloc_top;
|
||||||
|
md_top = _md_alloc_top;
|
||||||
|
|
||||||
// Reserve space for the list of Klass*s whose vtables are used
|
// Reserve space for the list of Klass*s whose vtables are used
|
||||||
// for patching others as needed.
|
// for patching others as needed.
|
||||||
|
|
||||||
@ -735,6 +786,7 @@ void MetaspaceShared::prepare_for_dumping() {
|
|||||||
void MetaspaceShared::preload_and_dump(TRAPS) {
|
void MetaspaceShared::preload_and_dump(TRAPS) {
|
||||||
TraceTime timer("Dump Shared Spaces", TraceStartupTime);
|
TraceTime timer("Dump Shared Spaces", TraceStartupTime);
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
char class_list_path_str[JVM_MAXPATHLEN];
|
||||||
|
|
||||||
tty->print_cr("Allocated shared space: " SIZE_FORMAT " bytes at " PTR_FORMAT,
|
tty->print_cr("Allocated shared space: " SIZE_FORMAT " bytes at " PTR_FORMAT,
|
||||||
MetaspaceShared::shared_rs()->size(),
|
MetaspaceShared::shared_rs()->size(),
|
||||||
@ -747,7 +799,6 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
|
|||||||
// Construct the path to the class list (in jre/lib)
|
// Construct the path to the class list (in jre/lib)
|
||||||
// Walk up two directories from the location of the VM and
|
// Walk up two directories from the location of the VM and
|
||||||
// optionally tack on "lib" (depending on platform)
|
// optionally tack on "lib" (depending on platform)
|
||||||
char class_list_path_str[JVM_MAXPATHLEN];
|
|
||||||
os::jvm_path(class_list_path_str, sizeof(class_list_path_str));
|
os::jvm_path(class_list_path_str, sizeof(class_list_path_str));
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
char *end = strrchr(class_list_path_str, *os::file_separator());
|
char *end = strrchr(class_list_path_str, *os::file_separator());
|
||||||
@ -785,6 +836,11 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
|
|||||||
static const char map_entry_array_sig[] = "[Ljava/util/Map$Entry;";
|
static const char map_entry_array_sig[] = "[Ljava/util/Map$Entry;";
|
||||||
SymbolTable::new_permanent_symbol(map_entry_array_sig, THREAD);
|
SymbolTable::new_permanent_symbol(map_entry_array_sig, THREAD);
|
||||||
|
|
||||||
|
// Need to allocate the op here:
|
||||||
|
// op.misc_data_space_alloc() will be called during preload_and_dump().
|
||||||
|
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
|
||||||
|
VM_PopulateDumpSharedSpace op(loader_data, class_promote_order);
|
||||||
|
|
||||||
tty->print_cr("Loading classes to share ...");
|
tty->print_cr("Loading classes to share ...");
|
||||||
_has_error_classes = false;
|
_has_error_classes = false;
|
||||||
class_count += preload_and_dump(class_list_path, class_promote_order,
|
class_count += preload_and_dump(class_list_path, class_promote_order,
|
||||||
@ -809,44 +865,27 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
|
|||||||
link_and_cleanup_shared_classes(CATCH);
|
link_and_cleanup_shared_classes(CATCH);
|
||||||
tty->print_cr("Rewriting and linking classes: done");
|
tty->print_cr("Rewriting and linking classes: done");
|
||||||
|
|
||||||
// Create and dump the shared spaces. Everything so far is loaded
|
|
||||||
// with the null class loader.
|
|
||||||
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
|
|
||||||
VM_PopulateDumpSharedSpace op(loader_data, class_promote_order);
|
|
||||||
VMThread::execute(&op);
|
VMThread::execute(&op);
|
||||||
|
|
||||||
// Since various initialization steps have been undone by this process,
|
// Since various initialization steps have been undone by this process,
|
||||||
// it is not reasonable to continue running a java process.
|
// it is not reasonable to continue running a java process.
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetaspaceShared::preload_and_dump(const char * class_list_path,
|
|
||||||
|
int MetaspaceShared::preload_and_dump(const char* class_list_path,
|
||||||
GrowableArray<Klass*>* class_promote_order,
|
GrowableArray<Klass*>* class_promote_order,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
FILE* file = fopen(class_list_path, "r");
|
ClassListParser parser(class_list_path);
|
||||||
char class_name[256];
|
|
||||||
int class_count = 0;
|
int class_count = 0;
|
||||||
|
|
||||||
if (file != NULL) {
|
while (parser.parse_one_line()) {
|
||||||
while ((fgets(class_name, sizeof class_name, file)) != NULL) {
|
Klass* klass = ClassLoaderExt::load_one_class(&parser, THREAD);
|
||||||
if (*class_name == '#') { // comment
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Remove trailing newline
|
|
||||||
size_t name_len = strlen(class_name);
|
|
||||||
if (class_name[name_len-1] == '\n') {
|
|
||||||
class_name[name_len-1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Got a class name - load it.
|
|
||||||
TempNewSymbol class_name_symbol = SymbolTable::new_permanent_symbol(class_name, THREAD);
|
|
||||||
guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
|
|
||||||
Klass* klass = SystemDictionary::resolve_or_null(class_name_symbol,
|
|
||||||
THREAD);
|
|
||||||
CLEAR_PENDING_EXCEPTION;
|
CLEAR_PENDING_EXCEPTION;
|
||||||
if (klass != NULL) {
|
if (klass != NULL) {
|
||||||
if (PrintSharedSpaces && Verbose && WizardMode) {
|
if (PrintSharedSpaces && Verbose && WizardMode) {
|
||||||
tty->print_cr("Shared spaces preloaded: %s", class_name);
|
ResourceMark rm;
|
||||||
|
tty->print_cr("Shared spaces preloaded: %s", klass->external_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceKlass* ik = InstanceKlass::cast(klass);
|
InstanceKlass* ik = InstanceKlass::cast(klass);
|
||||||
@ -862,17 +901,8 @@ int MetaspaceShared::preload_and_dump(const char * class_list_path,
|
|||||||
guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
|
guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
|
||||||
|
|
||||||
class_count++;
|
class_count++;
|
||||||
} else {
|
|
||||||
//tty->print_cr("Preload failed: %s", class_name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(file);
|
|
||||||
} else {
|
|
||||||
char errmsg[JVM_MAXPATHLEN];
|
|
||||||
os::lasterror(errmsg, JVM_MAXPATHLEN);
|
|
||||||
tty->print_cr("Loading classlist failed: %s", errmsg);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return class_count;
|
return class_count;
|
||||||
}
|
}
|
||||||
@ -908,6 +938,11 @@ bool MetaspaceShared::try_link_class(InstanceKlass* ik, TRAPS) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocate misc data blocks during dumping.
|
||||||
|
char* MetaspaceShared::misc_data_space_alloc(size_t num_bytes) {
|
||||||
|
return VM_PopulateDumpSharedSpace::instance()->misc_data_space_alloc(num_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
// Closure for serializing initialization data in from a data area
|
// Closure for serializing initialization data in from a data area
|
||||||
// (ptr_array) read from the shared file.
|
// (ptr_array) read from the shared file.
|
||||||
|
|
||||||
@ -1033,6 +1068,8 @@ void MetaspaceShared::initialize_shared_spaces() {
|
|||||||
|
|
||||||
char* buffer = mapinfo->header()->region_addr(md);
|
char* buffer = mapinfo->header()->region_addr(md);
|
||||||
|
|
||||||
|
buffer = *((char**)buffer); // skip over the md_alloc'ed blocks
|
||||||
|
|
||||||
// Skip over (reserve space for) a list of addresses of C++ vtables
|
// Skip over (reserve space for) a list of addresses of C++ vtables
|
||||||
// for Klass objects. They get filled in later.
|
// for Klass objects. They get filled in later.
|
||||||
|
|
||||||
|
@ -160,5 +160,8 @@ class MetaspaceShared : AllStatic {
|
|||||||
|
|
||||||
static int count_class(const char* classlist_file);
|
static int count_class(const char* classlist_file);
|
||||||
static void estimate_regions_size() NOT_CDS_RETURN;
|
static void estimate_regions_size() NOT_CDS_RETURN;
|
||||||
|
|
||||||
|
// Allocate a block of memory from the "md" region.
|
||||||
|
static char* misc_data_space_alloc(size_t num_bytes);
|
||||||
};
|
};
|
||||||
#endif // SHARE_VM_MEMORY_METASPACESHARED_HPP
|
#endif // SHARE_VM_MEMORY_METASPACESHARED_HPP
|
||||||
|
@ -1271,6 +1271,10 @@ WB_ENTRY(void, WB_AssertMatchingSafepointCalls(JNIEnv* env, jobject o, jboolean
|
|||||||
attemptedNoSafepointValue == JNI_TRUE);
|
attemptedNoSafepointValue == JNI_TRUE);
|
||||||
WB_END
|
WB_END
|
||||||
|
|
||||||
|
WB_ENTRY(jboolean, WB_IsSharedClass(JNIEnv* env, jobject wb, jclass clazz))
|
||||||
|
return (jboolean)MetaspaceShared::is_in_shared_space(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
|
||||||
|
WB_END
|
||||||
|
|
||||||
WB_ENTRY(jboolean, WB_IsMonitorInflated(JNIEnv* env, jobject wb, jobject obj))
|
WB_ENTRY(jboolean, WB_IsMonitorInflated(JNIEnv* env, jobject wb, jobject obj))
|
||||||
oop obj_oop = JNIHandles::resolve(obj);
|
oop obj_oop = JNIHandles::resolve(obj);
|
||||||
return (jboolean) obj_oop->mark()->has_monitor();
|
return (jboolean) obj_oop->mark()->has_monitor();
|
||||||
@ -1471,6 +1475,7 @@ static JNINativeMethod methods[] = {
|
|||||||
{CC"runMemoryUnitTests", CC"()V", (void*)&WB_RunMemoryUnitTests},
|
{CC"runMemoryUnitTests", CC"()V", (void*)&WB_RunMemoryUnitTests},
|
||||||
{CC"readFromNoaccessArea",CC"()V", (void*)&WB_ReadFromNoaccessArea},
|
{CC"readFromNoaccessArea",CC"()V", (void*)&WB_ReadFromNoaccessArea},
|
||||||
{CC"stressVirtualSpaceResize",CC"(JJJ)I", (void*)&WB_StressVirtualSpaceResize},
|
{CC"stressVirtualSpaceResize",CC"(JJJ)I", (void*)&WB_StressVirtualSpaceResize},
|
||||||
|
{CC"isSharedClass", CC"(Ljava/lang/Class;)Z", (void*)&WB_IsSharedClass },
|
||||||
#if INCLUDE_ALL_GCS
|
#if INCLUDE_ALL_GCS
|
||||||
{CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
|
{CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
|
||||||
{CC"g1IsHumongous0", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous },
|
{CC"g1IsHumongous0", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous },
|
||||||
|
@ -365,6 +365,7 @@ template class RehashableHashtable<Symbol*, mtSymbol>;
|
|||||||
template class RehashableHashtable<oopDesc*, mtSymbol>;
|
template class RehashableHashtable<oopDesc*, mtSymbol>;
|
||||||
template class Hashtable<Symbol*, mtSymbol>;
|
template class Hashtable<Symbol*, mtSymbol>;
|
||||||
template class Hashtable<Klass*, mtClass>;
|
template class Hashtable<Klass*, mtClass>;
|
||||||
|
template class Hashtable<InstanceKlass*, mtClass>;
|
||||||
template class Hashtable<oop, mtClass>;
|
template class Hashtable<oop, mtClass>;
|
||||||
#if defined(SOLARIS) || defined(CHECK_UNHANDLED_OOPS)
|
#if defined(SOLARIS) || defined(CHECK_UNHANDLED_OOPS)
|
||||||
template class Hashtable<oop, mtSymbol>;
|
template class Hashtable<oop, mtSymbol>;
|
||||||
@ -378,6 +379,7 @@ template class HashtableEntry<oop, mtSymbol>;
|
|||||||
template class BasicHashtableEntry<mtSymbol>;
|
template class BasicHashtableEntry<mtSymbol>;
|
||||||
template class BasicHashtableEntry<mtCode>;
|
template class BasicHashtableEntry<mtCode>;
|
||||||
template class BasicHashtable<mtClass>;
|
template class BasicHashtable<mtClass>;
|
||||||
|
template class BasicHashtable<mtClassShared>;
|
||||||
template class BasicHashtable<mtSymbol>;
|
template class BasicHashtable<mtSymbol>;
|
||||||
template class BasicHashtable<mtCode>;
|
template class BasicHashtable<mtCode>;
|
||||||
template class BasicHashtable<mtInternal>;
|
template class BasicHashtable<mtInternal>;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user