mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-14 09:53:18 +00:00
8367475: Incorrect lock usage in LambdaFormInvokers::regenerate_holder_classes
Reviewed-by: dholmes, matsaave, liach
This commit is contained in:
parent
ef291d2d5d
commit
c85c5cb50e
@ -862,7 +862,11 @@ CDSConfig::DumperThreadMark::~DumperThreadMark() {
|
||||
|
||||
bool CDSConfig::current_thread_is_vm_or_dumper() {
|
||||
Thread* t = Thread::current();
|
||||
return t != nullptr && (t->is_VM_thread() || t == _dumper_thread);
|
||||
return t->is_VM_thread() || t == _dumper_thread;
|
||||
}
|
||||
|
||||
bool CDSConfig::current_thread_is_dumper() {
|
||||
return Thread::current() == _dumper_thread;
|
||||
}
|
||||
|
||||
const char* CDSConfig::type_of_archive_being_loaded() {
|
||||
|
||||
@ -216,6 +216,7 @@ public:
|
||||
~DumperThreadMark();
|
||||
};
|
||||
|
||||
static bool current_thread_is_dumper() NOT_CDS_RETURN_(false);
|
||||
static bool current_thread_is_vm_or_dumper() NOT_CDS_RETURN_(false);
|
||||
};
|
||||
|
||||
|
||||
@ -53,6 +53,7 @@
|
||||
|
||||
GrowableArrayCHeap<char*, mtClassShared>* LambdaFormInvokers::_lambdaform_lines = nullptr;
|
||||
Array<u4>* LambdaFormInvokers::_static_archive_invokers = nullptr;
|
||||
static bool _stop_appending = false;
|
||||
|
||||
#define NUM_FILTER 4
|
||||
static const char* filter[NUM_FILTER] = {"java.lang.invoke.Invokers$Holder",
|
||||
@ -71,7 +72,12 @@ static bool should_be_archived(char* line) {
|
||||
#undef NUM_FILTER
|
||||
|
||||
void LambdaFormInvokers::append(char* line) {
|
||||
// This function can be called by concurrent Java threads, even after
|
||||
// LambdaFormInvokers::regenerate_holder_classes() has been called.
|
||||
MutexLocker ml(Thread::current(), LambdaFormInvokers_lock);
|
||||
if (_stop_appending) {
|
||||
return;
|
||||
}
|
||||
if (_lambdaform_lines == nullptr) {
|
||||
_lambdaform_lines = new GrowableArrayCHeap<char*, mtClassShared>(150);
|
||||
}
|
||||
@ -112,12 +118,6 @@ void LambdaFormInvokers::regenerate_holder_classes(TRAPS) {
|
||||
return;
|
||||
}
|
||||
|
||||
PrintLambdaFormMessage plm;
|
||||
if (_lambdaform_lines == nullptr || _lambdaform_lines->length() == 0) {
|
||||
log_info(aot)("Nothing to regenerate for holder classes");
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
// Filter out AOT tooling classes like java.lang.invoke.GenerateJLIClassesHelper, etc.
|
||||
@ -127,18 +127,27 @@ void LambdaFormInvokers::regenerate_holder_classes(TRAPS) {
|
||||
Klass* cds_klass = SystemDictionary::resolve_or_null(cds_name, THREAD);
|
||||
guarantee(cds_klass != nullptr, "jdk/internal/misc/CDS must exist!");
|
||||
|
||||
assert(CDSConfig::current_thread_is_dumper(), "not supposed to be called from other threads");
|
||||
{
|
||||
// Stop other threads from recording into _lambdaform_lines.
|
||||
MutexLocker ml(Thread::current(), LambdaFormInvokers_lock);
|
||||
_stop_appending = true;
|
||||
}
|
||||
|
||||
PrintLambdaFormMessage plm;
|
||||
if (_lambdaform_lines == nullptr || _lambdaform_lines->length() == 0) {
|
||||
log_info(aot)("Nothing to regenerate for lambda form holder classes");
|
||||
return;
|
||||
}
|
||||
|
||||
HandleMark hm(THREAD);
|
||||
int len = _lambdaform_lines->length();
|
||||
objArrayHandle list_lines;
|
||||
{
|
||||
MutexLocker ml(Thread::current(), LambdaFormInvokers_lock);
|
||||
list_lines = oopFactory::new_objArray_handle(vmClasses::String_klass(), len, CHECK);
|
||||
for (int i = 0; i < len; i++) {
|
||||
Handle h_line = java_lang_String::create_from_str(_lambdaform_lines->at(i), CHECK);
|
||||
list_lines->obj_at_put(i, h_line());
|
||||
}
|
||||
} // Before calling into java, release vm lock.
|
||||
//
|
||||
objArrayHandle list_lines = oopFactory::new_objArray_handle(vmClasses::String_klass(), len, CHECK);
|
||||
for (int i = 0; i < len; i++) {
|
||||
Handle h_line = java_lang_String::create_from_str(_lambdaform_lines->at(i), CHECK);
|
||||
list_lines->obj_at_put(i, h_line());
|
||||
}
|
||||
|
||||
// Object[] CDS.generateLambdaFormHolderClasses(String[] lines)
|
||||
// the returned Object[] layout:
|
||||
// name, byte[], name, byte[] ....
|
||||
@ -232,6 +241,7 @@ void LambdaFormInvokers::regenerate_class(char* class_name, ClassFileStream& st,
|
||||
}
|
||||
|
||||
void LambdaFormInvokers::dump_static_archive_invokers() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "no concurrent update to _lambdaform_lines");
|
||||
if (_lambdaform_lines != nullptr && _lambdaform_lines->length() > 0) {
|
||||
int count = 0;
|
||||
int len = _lambdaform_lines->length();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user