mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8261921
: ClassListParser::current should be used only by main thread
Reviewed-by: dholmes, ccheung, coleenp
This commit is contained in:
parent
991f7c1303
commit
8cfea7c523
5 changed files with 35 additions and 17 deletions
|
@ -43,6 +43,7 @@
|
|||
#include "memory/metaspaceShared.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/constantPool.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/java.hpp"
|
||||
#include "runtime/javaCalls.hpp"
|
||||
|
@ -50,11 +51,10 @@
|
|||
#include "utilities/hashtable.inline.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
volatile Thread* ClassListParser::_parsing_thread = NULL;
|
||||
ClassListParser* ClassListParser::_instance = NULL;
|
||||
|
||||
ClassListParser::ClassListParser(const char* file) {
|
||||
assert(_instance == NULL, "must be singleton");
|
||||
_instance = this;
|
||||
_classlist_file = file;
|
||||
_file = NULL;
|
||||
// Use os::open() because neither fopen() nor os::fopen()
|
||||
|
@ -73,12 +73,22 @@ ClassListParser::ClassListParser(const char* file) {
|
|||
_line_no = 0;
|
||||
_interfaces = new (ResourceObj::C_HEAP, mtClass) GrowableArray<int>(10, mtClass);
|
||||
_indy_items = new (ResourceObj::C_HEAP, mtClass) GrowableArray<const char*>(9, mtClass);
|
||||
|
||||
// _instance should only be accessed by the thread that created _instance.
|
||||
assert(_instance == NULL, "must be singleton");
|
||||
_instance = this;
|
||||
Atomic::store(&_parsing_thread, Thread::current());
|
||||
}
|
||||
|
||||
bool ClassListParser::is_parsing_thread() {
|
||||
return Atomic::load(&_parsing_thread) == Thread::current();
|
||||
}
|
||||
|
||||
ClassListParser::~ClassListParser() {
|
||||
if (_file) {
|
||||
fclose(_file);
|
||||
}
|
||||
Atomic::store(&_parsing_thread, (Thread*)NULL);
|
||||
_instance = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#define LAMBDA_PROXY_TAG "@lambda-proxy"
|
||||
#define LAMBDA_FORM_TAG "@lambda-form-invoker"
|
||||
|
||||
class Thread;
|
||||
|
||||
class ID2KlassTable : public KVHashtable<int, InstanceKlass*, mtInternal> {
|
||||
public:
|
||||
ID2KlassTable() : KVHashtable<int, InstanceKlass*, mtInternal>(1987) {}
|
||||
|
@ -81,6 +83,7 @@ class ClassListParser : public StackObj {
|
|||
_line_buf_size = _max_allowed_line_len + _line_buf_extra
|
||||
};
|
||||
|
||||
static volatile Thread* _parsing_thread; // the thread that created _instance
|
||||
static ClassListParser* _instance; // the singleton.
|
||||
const char* _classlist_file;
|
||||
FILE* _file;
|
||||
|
@ -119,9 +122,13 @@ public:
|
|||
ClassListParser(const char* file);
|
||||
~ClassListParser();
|
||||
|
||||
static bool is_parsing_thread();
|
||||
static ClassListParser* instance() {
|
||||
assert(is_parsing_thread(), "call this only in the thread that created ClassListParsing::_instance");
|
||||
assert(_instance != NULL, "must be");
|
||||
return _instance;
|
||||
}
|
||||
|
||||
bool parse_one_line();
|
||||
void split_tokens_by_whitespace(int offset);
|
||||
int split_at_tag_from_line();
|
||||
|
|
|
@ -369,8 +369,8 @@ InstanceKlass* SystemDictionary::resolve_super_or_fail(Symbol* class_name,
|
|||
#if INCLUDE_CDS
|
||||
if (DumpSharedSpaces) {
|
||||
// Special processing for handling UNREGISTERED shared classes.
|
||||
InstanceKlass* k = SystemDictionaryShared::dump_time_resolve_super_or_fail(class_name,
|
||||
super_name, class_loader, protection_domain, is_superclass, CHECK_NULL);
|
||||
InstanceKlass* k = SystemDictionaryShared::lookup_super_for_unregistered_class(class_name,
|
||||
super_name, is_superclass);
|
||||
if (k) {
|
||||
return k;
|
||||
}
|
||||
|
|
|
@ -1196,18 +1196,23 @@ bool SystemDictionaryShared::add_unregistered_class(InstanceKlass* k, TRAPS) {
|
|||
return created;
|
||||
}
|
||||
|
||||
// This function is called to resolve the super/interfaces of shared classes for
|
||||
// non-built-in loaders. E.g., SharedClass in the below example
|
||||
// This function is called to lookup the super/interfaces of shared classes for
|
||||
// unregistered loaders. E.g., SharedClass in the below example
|
||||
// where "super:" (and optionally "interface:") have been specified.
|
||||
//
|
||||
// java/lang/Object id: 0
|
||||
// Interface id: 2 super: 0 source: cust.jar
|
||||
// SharedClass id: 4 super: 0 interfaces: 2 source: cust.jar
|
||||
InstanceKlass* SystemDictionaryShared::dump_time_resolve_super_or_fail(
|
||||
Symbol* class_name, Symbol* super_name, Handle class_loader,
|
||||
Handle protection_domain, bool is_superclass, TRAPS) {
|
||||
InstanceKlass* SystemDictionaryShared::lookup_super_for_unregistered_class(
|
||||
Symbol* class_name, Symbol* super_name, bool is_superclass) {
|
||||
|
||||
assert(DumpSharedSpaces, "only when dumping");
|
||||
assert(DumpSharedSpaces, "only when static dumping");
|
||||
|
||||
if (!ClassListParser::is_parsing_thread()) {
|
||||
// Unregistered classes can be created only by ClassListParser::_parsing_thread.
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ClassListParser* parser = ClassListParser::instance();
|
||||
if (parser == NULL) {
|
||||
|
|
|
@ -247,12 +247,8 @@ public:
|
|||
static bool is_sharing_possible(ClassLoaderData* loader_data);
|
||||
|
||||
static bool add_unregistered_class(InstanceKlass* k, TRAPS);
|
||||
static InstanceKlass* dump_time_resolve_super_or_fail(Symbol* class_name,
|
||||
Symbol* super_name,
|
||||
Handle class_loader,
|
||||
Handle protection_domain,
|
||||
bool is_superclass,
|
||||
TRAPS);
|
||||
static InstanceKlass* lookup_super_for_unregistered_class(Symbol* class_name,
|
||||
Symbol* super_name, bool is_superclass);
|
||||
|
||||
static void init_dumptime_info(InstanceKlass* k) NOT_CDS_RETURN;
|
||||
static void remove_dumptime_info(InstanceKlass* k) NOT_CDS_RETURN;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue