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/aotClassLinker.hpp"
27 #include "cds/aotConstantPoolResolver.hpp"
28 #include "cds/archiveBuilder.hpp"
29 #include "cds/cdsConfig.hpp"
30 #include "classfile/systemDictionary.hpp"
31 #include "classfile/systemDictionaryShared.hpp"
32 #include "classfile/vmClasses.hpp"
33 #include "interpreter/bytecodeStream.hpp"
34 #include "interpreter/interpreterRuntime.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "oops/constantPool.inline.hpp"
37 #include "oops/instanceKlass.hpp"
38 #include "oops/klass.inline.hpp"
39 #include "runtime/handles.inline.hpp"
40
41 AOTConstantPoolResolver::ClassesTable* AOTConstantPoolResolver::_processed_classes = nullptr;
42
43 void AOTConstantPoolResolver::initialize() {
44 assert(_processed_classes == nullptr, "must be");
45 _processed_classes = new (mtClass)ClassesTable();
46 }
47
48 void AOTConstantPoolResolver::dispose() {
49 assert(_processed_classes != nullptr, "must be");
50 delete _processed_classes;
51 _processed_classes = nullptr;
52 }
53
54 // Returns true if we CAN PROVE that cp_index will always resolve to
55 // the same information at both dump time and run time. This is a
56 // necessary (but not sufficient) condition for pre-resolving cp_index
57 // during CDS archive assembly.
58 bool AOTConstantPoolResolver::is_resolution_deterministic(ConstantPool* cp, int cp_index) {
59 assert(!is_in_archivebuilder_buffer(cp), "sanity");
147
148 void AOTConstantPoolResolver::dumptime_resolve_constants(InstanceKlass* ik, TRAPS) {
149 if (!ik->is_linked()) {
150 return;
151 }
152 bool first_time;
153 _processed_classes->put_if_absent(ik, &first_time);
154 if (!first_time) {
155 // We have already resolved the constants in class, so no need to do it again.
156 return;
157 }
158
159 constantPoolHandle cp(THREAD, ik->constants());
160 for (int cp_index = 1; cp_index < cp->length(); cp_index++) { // Index 0 is unused
161 switch (cp->tag_at(cp_index).value()) {
162 case JVM_CONSTANT_String:
163 resolve_string(cp, cp_index, CHECK); // may throw OOM when interning strings.
164 break;
165 }
166 }
167 }
168
169 // This works only for the boot/platform/app loaders
170 Klass* AOTConstantPoolResolver::find_loaded_class(Thread* current, oop class_loader, Symbol* name) {
171 HandleMark hm(current);
172 Handle h_loader(current, class_loader);
173 Klass* k = SystemDictionary::find_instance_or_array_klass(current, name,
174 h_loader,
175 Handle());
176 if (k != nullptr) {
177 return k;
178 }
179 if (h_loader() == SystemDictionary::java_system_loader()) {
180 return find_loaded_class(current, SystemDictionary::java_platform_loader(), name);
181 } else if (h_loader() == SystemDictionary::java_platform_loader()) {
182 return find_loaded_class(current, nullptr, name);
183 } else {
184 assert(h_loader() == nullptr, "This function only works for boot/platform/app loaders %p %p %p",
185 cast_from_oop<address>(h_loader()),
186 cast_from_oop<address>(SystemDictionary::java_system_loader()),
188 }
189
190 return nullptr;
191 }
192
193 Klass* AOTConstantPoolResolver::find_loaded_class(Thread* current, ConstantPool* cp, int class_cp_index) {
194 Symbol* name = cp->klass_name_at(class_cp_index);
195 return find_loaded_class(current, cp->pool_holder()->class_loader(), name);
196 }
197
198 #if INCLUDE_CDS_JAVA_HEAP
199 void AOTConstantPoolResolver::resolve_string(constantPoolHandle cp, int cp_index, TRAPS) {
200 if (CDSConfig::is_dumping_heap()) {
201 int cache_index = cp->cp_to_object_index(cp_index);
202 ConstantPool::string_at_impl(cp, cp_index, cache_index, CHECK);
203 }
204 }
205 #endif
206
207 void AOTConstantPoolResolver::preresolve_class_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray<bool>* preresolve_list) {
208 if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) {
209 return;
210 }
211
212 JavaThread* THREAD = current;
213 constantPoolHandle cp(THREAD, ik->constants());
214 for (int cp_index = 1; cp_index < cp->length(); cp_index++) {
215 if (cp->tag_at(cp_index).value() == JVM_CONSTANT_UnresolvedClass) {
216 if (preresolve_list != nullptr && preresolve_list->at(cp_index) == false) {
217 // This class was not resolved during trial run. Don't attempt to resolve it. Otherwise
218 // the compiler may generate less efficient code.
219 continue;
220 }
221 if (find_loaded_class(current, cp(), cp_index) == nullptr) {
222 // Do not resolve any class that has not been loaded yet
223 continue;
224 }
225 Klass* resolved_klass = cp->klass_at(cp_index, THREAD);
226 if (HAS_PENDING_EXCEPTION) {
227 CLEAR_PENDING_EXCEPTION; // just ignore
229 log_trace(cds, resolve)("Resolved class [%3d] %s -> %s", cp_index, ik->external_name(),
230 resolved_klass->external_name());
231 }
232 }
233 }
234 }
235
236 void AOTConstantPoolResolver::preresolve_field_and_method_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray<bool>* preresolve_list) {
237 JavaThread* THREAD = current;
238 constantPoolHandle cp(THREAD, ik->constants());
239 if (cp->cache() == nullptr) {
240 return;
241 }
242 for (int i = 0; i < ik->methods()->length(); i++) {
243 Method* m = ik->methods()->at(i);
244 BytecodeStream bcs(methodHandle(THREAD, m));
245 while (!bcs.is_last_bytecode()) {
246 bcs.next();
247 Bytecodes::Code raw_bc = bcs.raw_code();
248 switch (raw_bc) {
249 case Bytecodes::_getfield:
250 case Bytecodes::_putfield:
251 maybe_resolve_fmi_ref(ik, m, raw_bc, bcs.get_index_u2(), preresolve_list, THREAD);
252 if (HAS_PENDING_EXCEPTION) {
253 CLEAR_PENDING_EXCEPTION; // just ignore
254 }
255 break;
256 case Bytecodes::_invokehandle:
257 case Bytecodes::_invokespecial:
258 case Bytecodes::_invokevirtual:
259 case Bytecodes::_invokeinterface:
260 maybe_resolve_fmi_ref(ik, m, raw_bc, bcs.get_index_u2(), preresolve_list, THREAD);
261 if (HAS_PENDING_EXCEPTION) {
262 CLEAR_PENDING_EXCEPTION; // just ignore
263 }
264 break;
265 default:
266 break;
267 }
268 }
269 }
270 }
271
272 void AOTConstantPoolResolver::maybe_resolve_fmi_ref(InstanceKlass* ik, Method* m, Bytecodes::Code bc, int raw_index,
273 GrowableArray<bool>* preresolve_list, TRAPS) {
274 methodHandle mh(THREAD, m);
275 constantPoolHandle cp(THREAD, ik->constants());
276 HandleMark hm(THREAD);
277 int cp_index = cp->to_cp_index(raw_index, bc);
278
279 if (cp->is_resolved(raw_index, bc)) {
280 return;
281 }
282
283 if (preresolve_list != nullptr && preresolve_list->at(cp_index) == false) {
284 // This field wasn't resolved during the trial run. Don't attempt to resolve it. Otherwise
285 // the compiler may generate less efficient code.
286 return;
287 }
288
289 int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index);
290 if (find_loaded_class(THREAD, cp(), klass_cp_index) == nullptr) {
291 // Do not resolve any field/methods from a class that has not been loaded yet.
292 return;
293 }
294
295 Klass* resolved_klass = cp->klass_ref_at(raw_index, bc, CHECK);
296
297 switch (bc) {
298 case Bytecodes::_getfield:
299 case Bytecodes::_putfield:
300 InterpreterRuntime::resolve_get_put(bc, raw_index, mh, cp, false /*initialize_holder*/, CHECK);
301 break;
302
303 case Bytecodes::_invokevirtual:
304 case Bytecodes::_invokespecial:
305 case Bytecodes::_invokeinterface:
306 InterpreterRuntime::cds_resolve_invoke(bc, raw_index, cp, CHECK);
307 break;
308
309 case Bytecodes::_invokehandle:
310 InterpreterRuntime::cds_resolve_invokehandle(raw_index, cp, CHECK);
311 break;
312
313 default:
314 ShouldNotReachHere();
315 }
316
317 if (log_is_enabled(Trace, cds, resolve)) {
318 ResourceMark rm(THREAD);
319 bool resolved = cp->is_resolved(raw_index, bc);
320 Symbol* name = cp->name_ref_at(raw_index, bc);
321 Symbol* signature = cp->signature_ref_at(raw_index, bc);
322 log_trace(cds, resolve)("%s %s [%3d] %s -> %s.%s:%s",
323 (resolved ? "Resolved" : "Failed to resolve"),
324 Bytecodes::name(bc), cp_index, ik->external_name(),
325 resolved_klass->external_name(),
326 name->as_C_string(), signature->as_C_string());
327 }
328 }
329
330 void AOTConstantPoolResolver::preresolve_indy_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray<bool>* preresolve_list) {
331 JavaThread* THREAD = current;
332 constantPoolHandle cp(THREAD, ik->constants());
333 if (!CDSConfig::is_dumping_invokedynamic() || cp->cache() == nullptr) {
334 return;
335 }
336
337 assert(preresolve_list != nullptr, "preresolve_indy_cp_entries() should not be called for "
338 "regenerated LambdaForm Invoker classes, which should not have indys anyway.");
339
340 Array<ResolvedIndyEntry>* indy_entries = cp->cache()->resolved_indy_entries();
341 for (int i = 0; i < indy_entries->length(); i++) {
342 ResolvedIndyEntry* rie = indy_entries->adr_at(i);
343 int cp_index = rie->constant_pool_index();
344 if (preresolve_list->at(cp_index) == true) {
345 if (!rie->is_resolved() && is_indy_resolution_deterministic(cp(), cp_index)) {
346 InterpreterRuntime::cds_resolve_invokedynamic(i, cp, THREAD);
554
555 // dynamicMethodType
556 if (!check_lambda_metafactory_methodtype_arg(cp, bsms_attribute_index, 2)) {
557 return false;
558 }
559
560 return true;
561 }
562
563 return false;
564 }
565 #ifdef ASSERT
566 bool AOTConstantPoolResolver::is_in_archivebuilder_buffer(address p) {
567 if (!Thread::current()->is_VM_thread() || ArchiveBuilder::current() == nullptr) {
568 return false;
569 } else {
570 return ArchiveBuilder::current()->is_in_buffer_space(p);
571 }
572 }
573 #endif
|
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/aotClassLinker.hpp"
27 #include "cds/aotConstantPoolResolver.hpp"
28 #include "cds/archiveBuilder.hpp"
29 #include "cds/archiveUtils.inline.hpp"
30 #include "cds/cdsConfig.hpp"
31 #include "cds/classListWriter.hpp"
32 #include "cds/finalImageRecipes.hpp"
33 #include "cds/heapShared.hpp"
34 #include "cds/lambdaFormInvokers.inline.hpp"
35 #include "classfile/classLoader.hpp"
36 #include "classfile/classLoaderExt.hpp"
37 #include "classfile/dictionary.hpp"
38 #include "classfile/symbolTable.hpp"
39 #include "classfile/systemDictionary.hpp"
40 #include "classfile/systemDictionaryShared.hpp"
41 #include "classfile/vmClasses.hpp"
42 #include "interpreter/bytecodeStream.hpp"
43 #include "interpreter/interpreterRuntime.hpp"
44 #include "memory/resourceArea.hpp"
45 #include "oops/constantPool.inline.hpp"
46 #include "oops/instanceKlass.hpp"
47 #include "oops/klass.inline.hpp"
48 #include "runtime/handles.inline.hpp"
49 #include "runtime/javaCalls.hpp"
50
51 AOTConstantPoolResolver::ClassesTable* AOTConstantPoolResolver::_processed_classes = nullptr;
52
53 void AOTConstantPoolResolver::initialize() {
54 assert(_processed_classes == nullptr, "must be");
55 _processed_classes = new (mtClass)ClassesTable();
56 }
57
58 void AOTConstantPoolResolver::dispose() {
59 assert(_processed_classes != nullptr, "must be");
60 delete _processed_classes;
61 _processed_classes = nullptr;
62 }
63
64 // Returns true if we CAN PROVE that cp_index will always resolve to
65 // the same information at both dump time and run time. This is a
66 // necessary (but not sufficient) condition for pre-resolving cp_index
67 // during CDS archive assembly.
68 bool AOTConstantPoolResolver::is_resolution_deterministic(ConstantPool* cp, int cp_index) {
69 assert(!is_in_archivebuilder_buffer(cp), "sanity");
157
158 void AOTConstantPoolResolver::dumptime_resolve_constants(InstanceKlass* ik, TRAPS) {
159 if (!ik->is_linked()) {
160 return;
161 }
162 bool first_time;
163 _processed_classes->put_if_absent(ik, &first_time);
164 if (!first_time) {
165 // We have already resolved the constants in class, so no need to do it again.
166 return;
167 }
168
169 constantPoolHandle cp(THREAD, ik->constants());
170 for (int cp_index = 1; cp_index < cp->length(); cp_index++) { // Index 0 is unused
171 switch (cp->tag_at(cp_index).value()) {
172 case JVM_CONSTANT_String:
173 resolve_string(cp, cp_index, CHECK); // may throw OOM when interning strings.
174 break;
175 }
176 }
177
178 // Normally, we don't want to archive any CP entries that were not resolved
179 // in the training run. Otherwise the AOT/JIT may inline too much code that has not
180 // been executed.
181 //
182 // However, we want to aggressively resolve all klass/field/method constants for
183 // LambdaForm Invoker Holder classes, Lambda Proxy classes, and LambdaForm classes,
184 // so that the compiler can inline through them.
185 if (SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) {
186 bool eager_resolve = false;
187
188 if (LambdaFormInvokers::may_be_regenerated_class(ik->name())) {
189 eager_resolve = true;
190 }
191 if (ik->is_hidden() && HeapShared::is_archivable_hidden_klass(ik)) {
192 eager_resolve = true;
193 }
194
195 if (eager_resolve) {
196 preresolve_class_cp_entries(THREAD, ik, nullptr);
197 preresolve_field_and_method_cp_entries(THREAD, ik, nullptr);
198 }
199 }
200 }
201
202 // This works only for the boot/platform/app loaders
203 Klass* AOTConstantPoolResolver::find_loaded_class(Thread* current, oop class_loader, Symbol* name) {
204 HandleMark hm(current);
205 Handle h_loader(current, class_loader);
206 Klass* k = SystemDictionary::find_instance_or_array_klass(current, name,
207 h_loader,
208 Handle());
209 if (k != nullptr) {
210 return k;
211 }
212 if (h_loader() == SystemDictionary::java_system_loader()) {
213 return find_loaded_class(current, SystemDictionary::java_platform_loader(), name);
214 } else if (h_loader() == SystemDictionary::java_platform_loader()) {
215 return find_loaded_class(current, nullptr, name);
216 } else {
217 assert(h_loader() == nullptr, "This function only works for boot/platform/app loaders %p %p %p",
218 cast_from_oop<address>(h_loader()),
219 cast_from_oop<address>(SystemDictionary::java_system_loader()),
221 }
222
223 return nullptr;
224 }
225
226 Klass* AOTConstantPoolResolver::find_loaded_class(Thread* current, ConstantPool* cp, int class_cp_index) {
227 Symbol* name = cp->klass_name_at(class_cp_index);
228 return find_loaded_class(current, cp->pool_holder()->class_loader(), name);
229 }
230
231 #if INCLUDE_CDS_JAVA_HEAP
232 void AOTConstantPoolResolver::resolve_string(constantPoolHandle cp, int cp_index, TRAPS) {
233 if (CDSConfig::is_dumping_heap()) {
234 int cache_index = cp->cp_to_object_index(cp_index);
235 ConstantPool::string_at_impl(cp, cp_index, cache_index, CHECK);
236 }
237 }
238 #endif
239
240 void AOTConstantPoolResolver::preresolve_class_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray<bool>* preresolve_list) {
241 if (!CDSConfig::is_dumping_aot_linked_classes()) {
242 // TODO: Why is this check needed in Leyden?
243 // The following 3 tests fails when this "if" check is removed (when -XX:-AOTClassLinking is NOT enabled)
244 // - runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java
245 // - runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java
246 // - runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java
247 return;
248 }
249 if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) {
250 return;
251 }
252
253 JavaThread* THREAD = current;
254 constantPoolHandle cp(THREAD, ik->constants());
255 for (int cp_index = 1; cp_index < cp->length(); cp_index++) {
256 if (cp->tag_at(cp_index).value() == JVM_CONSTANT_UnresolvedClass) {
257 if (preresolve_list != nullptr && preresolve_list->at(cp_index) == false) {
258 // This class was not resolved during trial run. Don't attempt to resolve it. Otherwise
259 // the compiler may generate less efficient code.
260 continue;
261 }
262 if (find_loaded_class(current, cp(), cp_index) == nullptr) {
263 // Do not resolve any class that has not been loaded yet
264 continue;
265 }
266 Klass* resolved_klass = cp->klass_at(cp_index, THREAD);
267 if (HAS_PENDING_EXCEPTION) {
268 CLEAR_PENDING_EXCEPTION; // just ignore
270 log_trace(cds, resolve)("Resolved class [%3d] %s -> %s", cp_index, ik->external_name(),
271 resolved_klass->external_name());
272 }
273 }
274 }
275 }
276
277 void AOTConstantPoolResolver::preresolve_field_and_method_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray<bool>* preresolve_list) {
278 JavaThread* THREAD = current;
279 constantPoolHandle cp(THREAD, ik->constants());
280 if (cp->cache() == nullptr) {
281 return;
282 }
283 for (int i = 0; i < ik->methods()->length(); i++) {
284 Method* m = ik->methods()->at(i);
285 BytecodeStream bcs(methodHandle(THREAD, m));
286 while (!bcs.is_last_bytecode()) {
287 bcs.next();
288 Bytecodes::Code raw_bc = bcs.raw_code();
289 switch (raw_bc) {
290 case Bytecodes::_getstatic: // FIXME -- leyden+JEP483 merge
291 case Bytecodes::_putstatic: // FIXME -- leyden+JEP483 merge
292 case Bytecodes::_getfield:
293 case Bytecodes::_putfield:
294 maybe_resolve_fmi_ref(ik, m, raw_bc, bcs.get_index_u2(), preresolve_list, THREAD);
295 if (HAS_PENDING_EXCEPTION) {
296 CLEAR_PENDING_EXCEPTION; // just ignore
297 }
298 break;
299 case Bytecodes::_invokehandle:
300 case Bytecodes::_invokespecial:
301 case Bytecodes::_invokevirtual:
302 case Bytecodes::_invokeinterface:
303 case Bytecodes::_invokestatic: // FIXME -- leyden+JEP483 merge
304 maybe_resolve_fmi_ref(ik, m, raw_bc, bcs.get_index_u2(), preresolve_list, THREAD);
305 if (HAS_PENDING_EXCEPTION) {
306 CLEAR_PENDING_EXCEPTION; // just ignore
307 }
308 break;
309 default:
310 break;
311 }
312 }
313 }
314 }
315
316 void AOTConstantPoolResolver::maybe_resolve_fmi_ref(InstanceKlass* ik, Method* m, Bytecodes::Code bc, int raw_index,
317 GrowableArray<bool>* preresolve_list, TRAPS) {
318 methodHandle mh(THREAD, m);
319 constantPoolHandle cp(THREAD, ik->constants());
320 HandleMark hm(THREAD);
321 int cp_index = cp->to_cp_index(raw_index, bc);
322
323 if (cp->is_resolved(raw_index, bc)) {
324 return;
325 }
326
327 if (preresolve_list != nullptr && preresolve_list->at(cp_index) == false) {
328 // This field wasn't resolved during the trial run. Don't attempt to resolve it. Otherwise
329 // the compiler may generate less efficient code.
330 return;
331 }
332
333 int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index);
334 if (find_loaded_class(THREAD, cp(), klass_cp_index) == nullptr) {
335 // Do not resolve any field/methods from a class that has not been loaded yet.
336 return;
337 }
338
339 Klass* resolved_klass = cp->klass_ref_at(raw_index, bc, CHECK);
340 const char* is_static = "";
341
342 switch (bc) {
343 #if 1 // FIXME -- leyden+JEP483 merge
344 case Bytecodes::_getstatic:
345 case Bytecodes::_putstatic:
346 if (!VM_Version::supports_fast_class_init_checks()) {
347 return; // Do not resolve since interpreter lacks fast clinit barriers support
348 }
349 InterpreterRuntime::resolve_get_put(bc, raw_index, mh, cp, false /*initialize_holder*/, CHECK);
350 is_static = " *** static";
351 break;
352 #endif
353 case Bytecodes::_getfield:
354 case Bytecodes::_putfield:
355 InterpreterRuntime::resolve_get_put(bc, raw_index, mh, cp, false /*initialize_holder*/, CHECK);
356 break;
357
358 #if 1 // FIXME -- leyden+JEP483 merge
359 case Bytecodes::_invokestatic:
360 if (!VM_Version::supports_fast_class_init_checks()) {
361 return; // Do not resolve since interpreter lacks fast clinit barriers support
362 }
363 InterpreterRuntime::cds_resolve_invoke(bc, raw_index, cp, CHECK);
364 is_static = " *** static";
365 break;
366 #endif
367
368 case Bytecodes::_invokevirtual:
369 case Bytecodes::_invokespecial:
370 case Bytecodes::_invokeinterface:
371 InterpreterRuntime::cds_resolve_invoke(bc, raw_index, cp, CHECK);
372 break;
373
374 case Bytecodes::_invokehandle:
375 InterpreterRuntime::cds_resolve_invokehandle(raw_index, cp, CHECK);
376 break;
377
378 default:
379 ShouldNotReachHere();
380 }
381
382 if (log_is_enabled(Trace, cds, resolve)) {
383 ResourceMark rm(THREAD);
384 bool resolved = cp->is_resolved(raw_index, bc);
385 Symbol* name = cp->name_ref_at(raw_index, bc);
386 Symbol* signature = cp->signature_ref_at(raw_index, bc);
387 log_trace(cds, resolve)("%s %s [%3d] %s -> %s.%s:%s%s",
388 (resolved ? "Resolved" : "Failed to resolve"),
389 Bytecodes::name(bc), cp_index, ik->external_name(),
390 resolved_klass->external_name(),
391 name->as_C_string(), signature->as_C_string(), is_static);
392 }
393 }
394
395 void AOTConstantPoolResolver::preresolve_indy_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray<bool>* preresolve_list) {
396 JavaThread* THREAD = current;
397 constantPoolHandle cp(THREAD, ik->constants());
398 if (!CDSConfig::is_dumping_invokedynamic() || cp->cache() == nullptr) {
399 return;
400 }
401
402 assert(preresolve_list != nullptr, "preresolve_indy_cp_entries() should not be called for "
403 "regenerated LambdaForm Invoker classes, which should not have indys anyway.");
404
405 Array<ResolvedIndyEntry>* indy_entries = cp->cache()->resolved_indy_entries();
406 for (int i = 0; i < indy_entries->length(); i++) {
407 ResolvedIndyEntry* rie = indy_entries->adr_at(i);
408 int cp_index = rie->constant_pool_index();
409 if (preresolve_list->at(cp_index) == true) {
410 if (!rie->is_resolved() && is_indy_resolution_deterministic(cp(), cp_index)) {
411 InterpreterRuntime::cds_resolve_invokedynamic(i, cp, THREAD);
619
620 // dynamicMethodType
621 if (!check_lambda_metafactory_methodtype_arg(cp, bsms_attribute_index, 2)) {
622 return false;
623 }
624
625 return true;
626 }
627
628 return false;
629 }
630 #ifdef ASSERT
631 bool AOTConstantPoolResolver::is_in_archivebuilder_buffer(address p) {
632 if (!Thread::current()->is_VM_thread() || ArchiveBuilder::current() == nullptr) {
633 return false;
634 } else {
635 return ArchiveBuilder::current()->is_in_buffer_space(p);
636 }
637 }
638 #endif
639
640 int AOTConstantPoolResolver::class_reflection_data_flags(InstanceKlass* ik, TRAPS) {
641 assert(java_lang_Class::has_reflection_data(ik->java_mirror()), "must be");
642
643 HandleMark hm(THREAD);
644 JavaCallArguments args(Handle(THREAD, ik->java_mirror()));
645 JavaValue result(T_INT);
646 JavaCalls::call_special(&result,
647 vmClasses::Class_klass(),
648 vmSymbols::encodeReflectionData_name(),
649 vmSymbols::void_int_signature(),
650 &args, CHECK_0);
651 int flags = result.get_jint();
652 log_info(cds)("Encode ReflectionData: %s (flags=0x%x)", ik->external_name(), flags);
653 return flags;
654 }
655
656 void AOTConstantPoolResolver::generate_reflection_data(JavaThread* current, InstanceKlass* ik, int rd_flags) {
657 log_info(cds)("Generate ReflectionData: %s (flags=" INT32_FORMAT_X ")", ik->external_name(), rd_flags);
658 JavaThread* THREAD = current; // for exception macros
659 JavaCallArguments args(Handle(THREAD, ik->java_mirror()));
660 args.push_int(rd_flags);
661 JavaValue result(T_OBJECT);
662 JavaCalls::call_special(&result,
663 vmClasses::Class_klass(),
664 vmSymbols::generateReflectionData_name(),
665 vmSymbols::int_void_signature(),
666 &args, THREAD);
667 if (HAS_PENDING_EXCEPTION) {
668 Handle exc_handle(THREAD, PENDING_EXCEPTION);
669 CLEAR_PENDING_EXCEPTION;
670
671 log_warning(cds)("Exception during Class::generateReflectionData() call for %s", ik->external_name());
672 LogStreamHandle(Debug, cds) log;
673 if (log.is_enabled()) {
674 java_lang_Throwable::print_stack_trace(exc_handle, &log);
675 }
676 }
677 }
678
679 Klass* AOTConstantPoolResolver::resolve_boot_class_or_fail(const char* class_name, TRAPS) {
680 Handle class_loader;
681 Handle protection_domain;
682 TempNewSymbol class_name_sym = SymbolTable::new_symbol(class_name);
683 return SystemDictionary::resolve_or_fail(class_name_sym, class_loader, protection_domain, true, THREAD);
684 }
685
686 void AOTConstantPoolResolver::trace_dynamic_proxy_class(oop loader, const char* proxy_name, objArrayOop interfaces, int access_flags) {
687 if (interfaces->length() < 1) {
688 return;
689 }
690 if (ClassListWriter::is_enabled()) {
691 const char* loader_name = ArchiveUtils::builtin_loader_name_or_null(loader);
692 if (loader_name != nullptr) {
693 stringStream ss;
694 ss.print("%s %s %d %d", loader_name, proxy_name, access_flags, interfaces->length());
695 for (int i = 0; i < interfaces->length(); i++) {
696 oop mirror = interfaces->obj_at(i);
697 Klass* k = java_lang_Class::as_Klass(mirror);
698 ss.print(" %s", k->name()->as_C_string());
699 }
700 ClassListWriter w;
701 w.stream()->print_cr("@dynamic-proxy %s", ss.freeze());
702 }
703 }
704 if (CDSConfig::is_dumping_preimage_static_archive()) {
705 FinalImageRecipes::add_dynamic_proxy_class(loader, proxy_name, interfaces, access_flags);
706 }
707 }
708
709 void AOTConstantPoolResolver::init_dynamic_proxy_cache(TRAPS) {
710 static bool inited = false;
711 if (inited) {
712 return;
713 }
714 inited = true;
715
716 Klass* klass = resolve_boot_class_or_fail("java/lang/reflect/Proxy", CHECK);
717 TempNewSymbol method = SymbolTable::new_symbol("initCacheForCDS");
718 TempNewSymbol signature = SymbolTable::new_symbol("(Ljava/lang/ClassLoader;Ljava/lang/ClassLoader;)V");
719
720 JavaCallArguments args;
721 args.push_oop(Handle(THREAD, SystemDictionary::java_platform_loader()));
722 args.push_oop(Handle(THREAD, SystemDictionary::java_system_loader()));
723 JavaValue result(T_VOID);
724 JavaCalls::call_static(&result,
725 klass,
726 method,
727 signature,
728 &args, CHECK);
729 }
730
731
732 void AOTConstantPoolResolver::define_dynamic_proxy_class(Handle loader, Handle proxy_name, Handle interfaces, int access_flags, TRAPS) {
733 if (!CDSConfig::is_dumping_dynamic_proxies()) {
734 return;
735 }
736 init_dynamic_proxy_cache(CHECK);
737
738 Klass* klass = resolve_boot_class_or_fail("java/lang/reflect/Proxy$ProxyBuilder", CHECK);
739 TempNewSymbol method = SymbolTable::new_symbol("defineProxyClassForCDS");
740 TempNewSymbol signature = SymbolTable::new_symbol("(Ljava/lang/ClassLoader;Ljava/lang/String;[Ljava/lang/Class;I)Ljava/lang/Class;");
741
742 JavaCallArguments args;
743 args.push_oop(Handle(THREAD, loader()));
744 args.push_oop(Handle(THREAD, proxy_name()));
745 args.push_oop(Handle(THREAD, interfaces()));
746 args.push_int(access_flags);
747 JavaValue result(T_OBJECT);
748 JavaCalls::call_static(&result,
749 klass,
750 method,
751 signature,
752 &args, CHECK);
753
754 // Assumptions:
755 // FMG is archived, which means -modulepath and -Xbootclasspath are both not specified.
756 // All named modules are loaded from the system modules files.
757 // TODO: test support for -Xbootclasspath after JDK-8322322. Some of the code below need to be changed.
758 // TODO: we just give dummy shared_classpath_index for the generated class so that it will be archived.
759 // The index is not used at runtime (see SystemDictionaryShared::load_shared_class_for_builtin_loader, which
760 // uses a null ProtectionDomain for this class)
761 oop mirror = result.get_oop();
762 assert(mirror != nullptr, "class must have been generated if not OOM");
763 InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
764 if (ik->is_shared_boot_class() || ik->is_shared_platform_class()) {
765 assert(ik->module()->is_named(), "dynamic proxies defined in unnamed modules for boot/platform loaders not supported");
766 ik->set_shared_classpath_index(0);
767 } else {
768 assert(ik->is_shared_app_class(), "must be");
769 ik->set_shared_classpath_index(ClassLoaderExt::app_class_paths_start_index());
770 }
771
772 ArchiveBuilder::alloc_stats()->record_dynamic_proxy_class();
773 if (log_is_enabled(Info, cds, dynamic, proxy)) {
774 ResourceMark rm(THREAD);
775 stringStream ss;
776 const char* prefix = "";
777 ss.print("%s (%-7s, cp index = %d) implements ", ik->external_name(),
778 ArchiveUtils::builtin_loader_name(loader()), ik->shared_classpath_index());
779 objArrayOop intfs = (objArrayOop)interfaces();
780 for (int i = 0; i < intfs->length(); i++) {
781 oop intf_mirror = intfs->obj_at(i);
782 ss.print("%s%s", prefix, java_lang_Class::as_Klass(intf_mirror)->external_name());
783 prefix = ", ";
784 }
785
786 log_info(cds, dynamic, proxy)("%s", ss.freeze());
787 }
788 }
|