39
39
#include " memory/oopFactory.hpp"
40
40
#include " memory/resourceArea.hpp"
41
41
#include " oops/instanceKlass.hpp"
42
- #include " oops/klass.hpp"
42
+ #include " oops/klass.inline. hpp"
43
43
#include " oops/objArrayKlass.hpp"
44
44
#include " oops/objArrayOop.hpp"
45
45
#include " oops/oop.inline.hpp"
46
+ #include " oops/oopHandle.inline.hpp"
46
47
#include " oops/typeArrayOop.inline.hpp"
47
48
#include " runtime/handles.inline.hpp"
48
49
#include " runtime/javaCalls.hpp"
49
50
#include " runtime/mutexLocker.hpp"
50
51
51
52
GrowableArrayCHeap<char *, mtClassShared>* LambdaFormInvokers::_lambdaform_lines = nullptr ;
52
53
Array<Array<char >*>* LambdaFormInvokers::_static_archive_invokers = nullptr ;
54
+ GrowableArrayCHeap<OopHandle, mtClassShared>* LambdaFormInvokers::_regenerated_mirrors = nullptr ;
53
55
54
56
#define NUM_FILTER 4
55
57
static const char * filter[NUM_FILTER] = {" java.lang.invoke.Invokers$Holder" ,
@@ -81,6 +83,25 @@ void LambdaFormInvokers::append(char* line) {
81
83
_lambdaform_lines->append (line);
82
84
}
83
85
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
+
84
105
// convenient output
85
106
class PrintLambdaFormMessage {
86
107
public:
@@ -155,12 +176,11 @@ void LambdaFormInvokers::regenerate_holder_classes(TRAPS) {
155
176
char *buf = NEW_RESOURCE_ARRAY (char , len);
156
177
memcpy (buf, (char *)h_bytes->byte_at_addr (0 ), len);
157
178
ClassFileStream st ((u1*)buf, len, NULL , ClassFileStream::verify);
158
- reload_class (class_name, st, CHECK);
179
+ regenerate_class (class_name, st, CHECK);
159
180
}
160
181
}
161
182
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) {
164
184
Symbol* class_name = SymbolTable::new_symbol ((const char *)name);
165
185
// the class must exist
166
186
Klass* klass = SystemDictionary::resolve_or_null (class_name, THREAD);
@@ -180,6 +200,9 @@ void LambdaFormInvokers::reload_class(char* name, ClassFileStream& st, TRAPS) {
180
200
cl_info,
181
201
CHECK);
182
202
203
+ assert (result->java_mirror () != nullptr , " must be" );
204
+ add_regenerated_class (result->java_mirror ());
205
+
183
206
{
184
207
MutexLocker mu_r (THREAD, Compile_lock); // add_to_hierarchy asserts this.
185
208
SystemDictionary::add_to_hierarchy (result);
@@ -191,7 +214,7 @@ void LambdaFormInvokers::reload_class(char* name, ClassFileStream& st, TRAPS) {
191
214
// exclude the existing class from dump
192
215
SystemDictionaryShared::set_excluded (InstanceKlass::cast (klass));
193
216
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,
195
218
name, p2i (klass), p2i (result));
196
219
}
197
220
0 commit comments