7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "cds/archiveBuilder.hpp"
27 #include "cds/lambdaFormInvokers.hpp"
28 #include "cds/metaspaceShared.hpp"
29 #include "cds/regeneratedClasses.hpp"
30 #include "classfile/classFileStream.hpp"
31 #include "classfile/classLoadInfo.hpp"
32 #include "classfile/javaClasses.inline.hpp"
33 #include "classfile/klassFactory.hpp"
34 #include "classfile/symbolTable.hpp"
35 #include "classfile/systemDictionary.hpp"
36 #include "classfile/systemDictionaryShared.hpp"
37 #include "classfile/vmClasses.hpp"
38 #include "classfile/vmSymbols.hpp"
39 #include "logging/log.hpp"
40 #include "memory/oopFactory.hpp"
41 #include "memory/resourceArea.hpp"
42 #include "oops/instanceKlass.hpp"
43 #include "oops/klass.inline.hpp"
44 #include "oops/objArrayKlass.hpp"
45 #include "oops/objArrayOop.hpp"
46 #include "oops/oop.inline.hpp"
73 MutexLocker ml(Thread::current(), LambdaFormInvokers_lock);
74 if (_lambdaform_lines == nullptr) {
75 _lambdaform_lines = new GrowableArrayCHeap<char*, mtClassShared>(150);
76 }
77 _lambdaform_lines->append(line);
78 }
79
80
81 // convenient output
82 class PrintLambdaFormMessage {
83 public:
84 PrintLambdaFormMessage() {
85 log_info(cds)("Regenerate MethodHandle Holder classes...");
86 }
87 ~PrintLambdaFormMessage() {
88 log_info(cds)("Regenerate MethodHandle Holder classes...done");
89 }
90 };
91
92 void LambdaFormInvokers::regenerate_holder_classes(TRAPS) {
93 PrintLambdaFormMessage plm;
94 if (_lambdaform_lines == nullptr || _lambdaform_lines->length() == 0) {
95 log_info(cds)("Nothing to regenerate for holder classes");
96 return;
97 }
98
99 if (CDSConfig::is_dumping_static_archive() && CDSConfig::is_dumping_invokedynamic()) {
100 // Work around JDK-8310831, as some methods in lambda form holder classes may not get generated.
101 log_info(cds)("Archived MethodHandles may refer to lambda form holder classes. Cannot regenerate.");
102 return;
103 }
104
105 if (CDSConfig::is_dumping_dynamic_archive() && CDSConfig::is_dumping_aot_linked_classes() &&
106 CDSConfig::is_using_aot_linked_classes()) {
107 // The base archive may have some pre-resolved CP entries that point to the lambda form holder
108 // classes in the base archive. If we generate new versions of these classes, those CP entries
109 // will be pointing to invalid classes.
110 log_info(cds)("Base archive already has aot-linked lambda form holder classes. Cannot regenerate.");
111 return;
112 }
165 if (strstr(class_name, "java/lang/invoke/BoundMethodHandle$Species_") != nullptr) {
166 // The species classes are already loaded into the system dictionary
167 // during the execution of CDS.generateLambdaFormHolderClasses(). No
168 // need to regenerate.
169 TempNewSymbol class_name_sym = SymbolTable::new_symbol(class_name);
170 Klass* klass = SystemDictionary::resolve_or_null(class_name_sym, THREAD);
171 assert(klass != nullptr, "must already be loaded");
172 if (!klass->is_shared() && klass->shared_classpath_index() < 0) {
173 // Fake it, so that it will be included into the archive.
174 klass->set_shared_classpath_index(0);
175 // Set the "generated" bit, so it won't interfere with JVMTI.
176 // See SystemDictionaryShared::find_builtin_class().
177 klass->set_is_generated_shared_class();
178 }
179 } else {
180 int len = h_bytes->length();
181 // make a copy of class bytes so GC will not affect us.
182 char *buf = NEW_RESOURCE_ARRAY(char, len);
183 memcpy(buf, (char*)h_bytes->byte_at_addr(0), len);
184 ClassFileStream st((u1*)buf, len, nullptr);
185 regenerate_class(class_name, st, CHECK);
186 }
187 }
188 }
189
190 void LambdaFormInvokers::regenerate_class(char* class_name, ClassFileStream& st, TRAPS) {
191 TempNewSymbol class_name_sym = SymbolTable::new_symbol(class_name);
192 Klass* klass = SystemDictionary::resolve_or_null(class_name_sym, THREAD);
193 assert(klass != nullptr, "must exist");
194 assert(klass->is_instance_klass(), "Should be");
195
196 ClassLoaderData* cld = ClassLoaderData::the_null_class_loader_data();
197 Handle protection_domain;
198 ClassLoadInfo cl_info(protection_domain);
199
200 InstanceKlass* result = KlassFactory::create_from_stream(&st,
201 class_name_sym,
202 cld,
203 cl_info,
204 CHECK);
205
206 assert(result->java_mirror() != nullptr, "must be");
207 RegeneratedClasses::add_class(InstanceKlass::cast(klass), result);
208
209 result->add_to_hierarchy(THREAD);
210
211 // new class not linked yet.
212 MetaspaceShared::try_link_class(THREAD, result);
213 assert(!HAS_PENDING_EXCEPTION, "Invariant");
214
215 result->set_is_generated_shared_class();
216 if (!klass->is_shared()) {
217 SystemDictionaryShared::set_excluded(InstanceKlass::cast(klass)); // exclude the existing class from dump
218 }
219 log_info(cds, lambda)("Regenerated class %s, old: " INTPTR_FORMAT " new: " INTPTR_FORMAT,
220 class_name, p2i(klass), p2i(result));
221 }
222
223 void LambdaFormInvokers::dump_static_archive_invokers() {
224 if (_lambdaform_lines != nullptr && _lambdaform_lines->length() > 0) {
225 int count = 0;
226 int len = _lambdaform_lines->length();
227 for (int i = 0; i < len; i++) {
228 char* str = _lambdaform_lines->at(i);
229 if (should_be_archived(str)) {
230 count++;
231 }
232 }
233 if (count > 0) {
234 _static_archive_invokers = ArchiveBuilder::new_ro_array<u4>(count);
235 int index = 0;
236 for (int i = 0; i < len; i++) {
237 char* str = _lambdaform_lines->at(i);
238 if (should_be_archived(str)) {
239 size_t str_len = strlen(str) + 1; // including terminating zero
240 Array<char>* line = ArchiveBuilder::new_ro_array<char>((int)str_len);
241 strncpy(line->adr_at(0), str, str_len);
242
243 _static_archive_invokers->at_put(index, ArchiveBuilder::current()->any_to_offset_u4(line));
|
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "cds/archiveBuilder.hpp"
27 #include "cds/cdsConfig.hpp"
28 #include "cds/lambdaFormInvokers.hpp"
29 #include "cds/metaspaceShared.hpp"
30 #include "cds/regeneratedClasses.hpp"
31 #include "classfile/classFileStream.hpp"
32 #include "classfile/classLoadInfo.hpp"
33 #include "classfile/javaClasses.inline.hpp"
34 #include "classfile/klassFactory.hpp"
35 #include "classfile/symbolTable.hpp"
36 #include "classfile/systemDictionary.hpp"
37 #include "classfile/systemDictionaryShared.hpp"
38 #include "classfile/vmClasses.hpp"
39 #include "classfile/vmSymbols.hpp"
40 #include "logging/log.hpp"
41 #include "memory/oopFactory.hpp"
42 #include "memory/resourceArea.hpp"
43 #include "oops/instanceKlass.hpp"
44 #include "oops/klass.inline.hpp"
45 #include "oops/objArrayKlass.hpp"
46 #include "oops/objArrayOop.hpp"
47 #include "oops/oop.inline.hpp"
74 MutexLocker ml(Thread::current(), LambdaFormInvokers_lock);
75 if (_lambdaform_lines == nullptr) {
76 _lambdaform_lines = new GrowableArrayCHeap<char*, mtClassShared>(150);
77 }
78 _lambdaform_lines->append(line);
79 }
80
81
82 // convenient output
83 class PrintLambdaFormMessage {
84 public:
85 PrintLambdaFormMessage() {
86 log_info(cds)("Regenerate MethodHandle Holder classes...");
87 }
88 ~PrintLambdaFormMessage() {
89 log_info(cds)("Regenerate MethodHandle Holder classes...done");
90 }
91 };
92
93 void LambdaFormInvokers::regenerate_holder_classes(TRAPS) {
94 if (!CDSConfig::is_dumping_regenerated_lambdaform_invokers()) {
95 return;
96 }
97 PrintLambdaFormMessage plm;
98 if (_lambdaform_lines == nullptr || _lambdaform_lines->length() == 0) {
99 log_info(cds)("Nothing to regenerate for holder classes");
100 return;
101 }
102
103 if (CDSConfig::is_dumping_static_archive() && CDSConfig::is_dumping_invokedynamic()) {
104 // Work around JDK-8310831, as some methods in lambda form holder classes may not get generated.
105 log_info(cds)("Archived MethodHandles may refer to lambda form holder classes. Cannot regenerate.");
106 return;
107 }
108
109 if (CDSConfig::is_dumping_dynamic_archive() && CDSConfig::is_dumping_aot_linked_classes() &&
110 CDSConfig::is_using_aot_linked_classes()) {
111 // The base archive may have some pre-resolved CP entries that point to the lambda form holder
112 // classes in the base archive. If we generate new versions of these classes, those CP entries
113 // will be pointing to invalid classes.
114 log_info(cds)("Base archive already has aot-linked lambda form holder classes. Cannot regenerate.");
115 return;
116 }
169 if (strstr(class_name, "java/lang/invoke/BoundMethodHandle$Species_") != nullptr) {
170 // The species classes are already loaded into the system dictionary
171 // during the execution of CDS.generateLambdaFormHolderClasses(). No
172 // need to regenerate.
173 TempNewSymbol class_name_sym = SymbolTable::new_symbol(class_name);
174 Klass* klass = SystemDictionary::resolve_or_null(class_name_sym, THREAD);
175 assert(klass != nullptr, "must already be loaded");
176 if (!klass->is_shared() && klass->shared_classpath_index() < 0) {
177 // Fake it, so that it will be included into the archive.
178 klass->set_shared_classpath_index(0);
179 // Set the "generated" bit, so it won't interfere with JVMTI.
180 // See SystemDictionaryShared::find_builtin_class().
181 klass->set_is_generated_shared_class();
182 }
183 } else {
184 int len = h_bytes->length();
185 // make a copy of class bytes so GC will not affect us.
186 char *buf = NEW_RESOURCE_ARRAY(char, len);
187 memcpy(buf, (char*)h_bytes->byte_at_addr(0), len);
188 ClassFileStream st((u1*)buf, len, nullptr);
189 if (!CDSConfig::is_dumping_invokedynamic() /* work around JDK-8310831 */) {
190 regenerate_class(class_name, st, CHECK);
191 }
192 }
193 }
194 }
195
196 void LambdaFormInvokers::regenerate_class(char* class_name, ClassFileStream& st, TRAPS) {
197 TempNewSymbol class_name_sym = SymbolTable::new_symbol(class_name);
198 Klass* klass = SystemDictionary::resolve_or_null(class_name_sym, THREAD);
199 assert(klass != nullptr, "must exist");
200 assert(klass->is_instance_klass(), "Should be");
201
202 ClassLoaderData* cld = ClassLoaderData::the_null_class_loader_data();
203 Handle protection_domain;
204 ClassLoadInfo cl_info(protection_domain);
205
206 InstanceKlass* result = KlassFactory::create_from_stream(&st,
207 class_name_sym,
208 cld,
209 cl_info,
210 CHECK);
211
212 assert(result->java_mirror() != nullptr, "must be");
213 RegeneratedClasses::add_class(InstanceKlass::cast(klass), result);
214
215 result->add_to_hierarchy(THREAD);
216
217 // new class not linked yet.
218 MetaspaceShared::try_link_class(THREAD, result);
219 assert(!HAS_PENDING_EXCEPTION, "Invariant");
220
221 result->set_is_generated_shared_class();
222 if (!klass->is_shared()) {
223 SystemDictionaryShared::set_excluded(InstanceKlass::cast(klass)); // exclude the existing class from dump
224 }
225 log_info(cds, lambda)("Regenerated class %s, old: " INTPTR_FORMAT " new: " INTPTR_FORMAT,
226 class_name, p2i(klass), p2i(result));
227 }
228
229 void LambdaFormInvokers::dump_static_archive_invokers() {
230 if (CDSConfig::is_dumping_preimage_static_archive() ||
231 CDSConfig::is_dumping_final_static_archive()) {
232 // This function writes the "names" of the invokers.
233 // This is not supported in new CDS workflow for now.
234 return;
235 }
236
237 if (_lambdaform_lines != nullptr && _lambdaform_lines->length() > 0) {
238 int count = 0;
239 int len = _lambdaform_lines->length();
240 for (int i = 0; i < len; i++) {
241 char* str = _lambdaform_lines->at(i);
242 if (should_be_archived(str)) {
243 count++;
244 }
245 }
246 if (count > 0) {
247 _static_archive_invokers = ArchiveBuilder::new_ro_array<u4>(count);
248 int index = 0;
249 for (int i = 0; i < len; i++) {
250 char* str = _lambdaform_lines->at(i);
251 if (should_be_archived(str)) {
252 size_t str_len = strlen(str) + 1; // including terminating zero
253 Array<char>* line = ArchiveBuilder::new_ro_array<char>((int)str_len);
254 strncpy(line->adr_at(0), str, str_len);
255
256 _static_archive_invokers->at_put(index, ArchiveBuilder::current()->any_to_offset_u4(line));
|