Skip to content

Commit e4852c6

Browse files
committed
8277998: runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java#custom-cl-zgc failed "assert(ZAddress::is_marked(addr)) failed: Should be marked"
Reviewed-by: iklam, minqi
1 parent 37921e3 commit e4852c6

File tree

4 files changed

+38
-8
lines changed

4 files changed

+38
-8
lines changed

src/hotspot/share/cds/dynamicArchive.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ class VM_PopulateDynamicDumpSharedSpace: public VM_GC_Sync_Operation {
354354

355355
_builder.doit();
356356
}
357+
~VM_PopulateDynamicDumpSharedSpace() {
358+
LambdaFormInvokers::cleanup_regenerated_classes();
359+
}
357360
};
358361

359362
void DynamicArchive::check_for_dynamic_dump() {

src/hotspot/share/cds/lambdaFormInvokers.cpp

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,19 @@
3939
#include "memory/oopFactory.hpp"
4040
#include "memory/resourceArea.hpp"
4141
#include "oops/instanceKlass.hpp"
42-
#include "oops/klass.hpp"
42+
#include "oops/klass.inline.hpp"
4343
#include "oops/objArrayKlass.hpp"
4444
#include "oops/objArrayOop.hpp"
4545
#include "oops/oop.inline.hpp"
46+
#include "oops/oopHandle.inline.hpp"
4647
#include "oops/typeArrayOop.inline.hpp"
4748
#include "runtime/handles.inline.hpp"
4849
#include "runtime/javaCalls.hpp"
4950
#include "runtime/mutexLocker.hpp"
5051

5152
GrowableArrayCHeap<char*, mtClassShared>* LambdaFormInvokers::_lambdaform_lines = nullptr;
5253
Array<Array<char>*>* LambdaFormInvokers::_static_archive_invokers = nullptr;
54+
GrowableArrayCHeap<OopHandle, mtClassShared>* LambdaFormInvokers::_regenerated_mirrors = nullptr;
5355

5456
#define NUM_FILTER 4
5557
static const char* filter[NUM_FILTER] = {"java.lang.invoke.Invokers$Holder",
@@ -81,6 +83,25 @@ void LambdaFormInvokers::append(char* line) {
8183
_lambdaform_lines->append(line);
8284
}
8385

86+
// The regenerated Klass is not added to any class loader, so we need
87+
// to keep its java_mirror alive to avoid class unloading.
88+
void LambdaFormInvokers::add_regenerated_class(oop regenerated_class) {
89+
if (_regenerated_mirrors == nullptr) {
90+
_regenerated_mirrors = new GrowableArrayCHeap<OopHandle, mtClassShared>(150);
91+
}
92+
_regenerated_mirrors->append(OopHandle(Universe::vm_global(), regenerated_class));
93+
}
94+
95+
void LambdaFormInvokers::cleanup_regenerated_classes() {
96+
if (_regenerated_mirrors == nullptr) return;
97+
98+
for (int i = 0; i < _regenerated_mirrors->length(); i++) {
99+
_regenerated_mirrors->at(i).release(Universe::vm_global());
100+
}
101+
delete _regenerated_mirrors;
102+
_regenerated_mirrors = nullptr;
103+
}
104+
84105
// convenient output
85106
class PrintLambdaFormMessage {
86107
public:
@@ -155,12 +176,11 @@ void LambdaFormInvokers::regenerate_holder_classes(TRAPS) {
155176
char *buf = NEW_RESOURCE_ARRAY(char, len);
156177
memcpy(buf, (char*)h_bytes->byte_at_addr(0), len);
157178
ClassFileStream st((u1*)buf, len, NULL, ClassFileStream::verify);
158-
reload_class(class_name, st, CHECK);
179+
regenerate_class(class_name, st, CHECK);
159180
}
160181
}
161182

162-
// class_handle - the class name, bytes_handle - the class bytes
163-
void LambdaFormInvokers::reload_class(char* name, ClassFileStream& st, TRAPS) {
183+
void LambdaFormInvokers::regenerate_class(char* name, ClassFileStream& st, TRAPS) {
164184
Symbol* class_name = SymbolTable::new_symbol((const char*)name);
165185
// the class must exist
166186
Klass* klass = SystemDictionary::resolve_or_null(class_name, THREAD);
@@ -180,6 +200,9 @@ void LambdaFormInvokers::reload_class(char* name, ClassFileStream& st, TRAPS) {
180200
cl_info,
181201
CHECK);
182202

203+
assert(result->java_mirror() != nullptr, "must be");
204+
add_regenerated_class(result->java_mirror());
205+
183206
{
184207
MutexLocker mu_r(THREAD, Compile_lock); // add_to_hierarchy asserts this.
185208
SystemDictionary::add_to_hierarchy(result);
@@ -191,7 +214,7 @@ void LambdaFormInvokers::reload_class(char* name, ClassFileStream& st, TRAPS) {
191214
// exclude the existing class from dump
192215
SystemDictionaryShared::set_excluded(InstanceKlass::cast(klass));
193216
SystemDictionaryShared::init_dumptime_info(result);
194-
log_info(cds, lambda)("Replaced class %s, old: " INTPTR_FORMAT " new: " INTPTR_FORMAT,
217+
log_info(cds, lambda)("Regenerated class %s, old: " INTPTR_FORMAT " new: " INTPTR_FORMAT,
195218
name, p2i(klass), p2i(result));
196219
}
197220

src/hotspot/share/cds/lambdaFormInvokers.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#ifndef SHARE_CDS_LAMBDAFORMINVOKERS_HPP
2626
#define SHARE_CDS_LAMBDAFORMINVOKERS_HPP
2727
#include "memory/allStatic.hpp"
28+
#include "oops/oopHandle.hpp"
2829
#include "runtime/handles.hpp"
2930
#include "utilities/growableArray.hpp"
3031

@@ -37,13 +38,16 @@ class LambdaFormInvokers : public AllStatic {
3738
static GrowableArrayCHeap<char*, mtClassShared>* _lambdaform_lines;
3839
// For storing LF form lines (LF_RESOLVE only) in read only table.
3940
static Array<Array<char>*>* _static_archive_invokers;
40-
static void reload_class(char* name, ClassFileStream& st, TRAPS);
41+
static GrowableArrayCHeap<OopHandle, mtClassShared>* _regenerated_mirrors;
42+
static void regenerate_class(char* name, ClassFileStream& st, TRAPS);
43+
static void add_regenerated_class(oop regenerated_class);
4144
public:
4245
static void append(char* line);
4346
static void append_filtered(char* line);
4447
static void dump_static_archive_invokers();
4548
static void read_static_archive_invokers();
4649
static void regenerate_holder_classes(TRAPS);
4750
static void serialize(SerializeClosure* soc);
51+
static void cleanup_regenerated_classes();
4852
};
4953
#endif // SHARE_CDS_LAMBDAFORMINVOKERS_HPP

test/hotspot/jtreg/runtime/cds/appcds/DumpClassListWithLF.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
3333
*/
3434

3535
public class DumpClassListWithLF extends ClassListFormatBase {
36-
static final String REPLACE_OK = "Replaced class java/lang/invoke/DirectMethodHandle$Holder";
36+
static final String REPLACE_OK = "Regenerated class java/lang/invoke/DirectMethodHandle$Holder";
3737

3838
public static void main(String[] args) throws Throwable {
3939
String appJar = JarBuilder.getOrCreateHelloJar();

0 commit comments

Comments
 (0)