< prev index next >

src/hotspot/share/oops/cpCache.cpp

Print this page

 32 #include "classfile/systemDictionaryShared.hpp"
 33 #include "classfile/vmClasses.hpp"
 34 #include "code/codeCache.hpp"
 35 #include "interpreter/bytecodeStream.hpp"
 36 #include "interpreter/bytecodes.hpp"
 37 #include "interpreter/interpreter.hpp"
 38 #include "interpreter/linkResolver.hpp"
 39 #include "interpreter/rewriter.hpp"
 40 #include "logging/log.hpp"
 41 #include "logging/logStream.hpp"
 42 #include "memory/metadataFactory.hpp"
 43 #include "memory/metaspaceClosure.hpp"
 44 #include "memory/resourceArea.hpp"
 45 #include "oops/access.inline.hpp"
 46 #include "oops/compressedOops.hpp"
 47 #include "oops/constantPool.inline.hpp"
 48 #include "oops/cpCache.inline.hpp"
 49 #include "oops/method.inline.hpp"
 50 #include "oops/objArrayOop.inline.hpp"
 51 #include "oops/oop.inline.hpp"

 52 #include "oops/resolvedFieldEntry.hpp"
 53 #include "oops/resolvedIndyEntry.hpp"
 54 #include "oops/resolvedMethodEntry.hpp"
 55 #include "prims/methodHandles.hpp"
 56 #include "runtime/arguments.hpp"
 57 #include "runtime/atomic.hpp"
 58 #include "runtime/handles.inline.hpp"
 59 #include "runtime/mutexLocker.hpp"
 60 #include "runtime/synchronizer.hpp"
 61 #include "runtime/vm_version.hpp"
 62 #include "utilities/macros.hpp"
 63 
 64 // Implementation of ConstantPoolCache
 65 
 66 template <class T>
 67 static Array<T>* initialize_resolved_entries_array(ClassLoaderData* loader_data, GrowableArray<T> entries, TRAPS) {
 68   Array<T>* resolved_entries;
 69   if (entries.length() != 0) {
 70     resolved_entries = MetadataFactory::new_array<T>(loader_data, entries.length(), CHECK_NULL);
 71     for (int i = 0; i < entries.length(); i++) {

159     }
160     default:
161       ShouldNotReachHere();
162       break;
163   }
164 
165   // Note:  byte_no also appears in TemplateTable::resolve.
166   if (byte_no == 1) {
167     assert(invoke_code != Bytecodes::_invokevirtual &&
168            invoke_code != Bytecodes::_invokeinterface, "");
169     bool do_resolve = true;
170     // Don't mark invokespecial to method as resolved if sender is an interface.  The receiver
171     // has to be checked that it is a subclass of the current class every time this bytecode
172     // is executed.
173     if (invoke_code == Bytecodes::_invokespecial && sender_is_interface &&
174         method->name() != vmSymbols::object_initializer_name()) {
175       do_resolve = false;
176     }
177     if (invoke_code == Bytecodes::_invokestatic) {
178       assert(method->method_holder()->is_initialized() ||
179              method->method_holder()->is_reentrant_initialization(JavaThread::current()),

180              "invalid class initialization state for invoke_static");
181 
182       if (!VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
183         // Don't mark invokestatic to method as resolved if the holder class has not yet completed
184         // initialization. An invokestatic must only proceed if the class is initialized, but if
185         // we resolve it before then that class initialization check is skipped.
186         //
187         // When fast class initialization checks are supported (VM_Version::supports_fast_class_init_checks() == true),
188         // template interpreter supports fast class initialization check for
189         // invokestatic which doesn't require call site re-resolution to
190         // enforce class initialization barrier.
191         do_resolve = false;
192       }
193     }
194     if (do_resolve) {
195       method_entry->set_bytecode1(invoke_code);
196     }
197   } else if (byte_no == 2)  {
198     if (change_to_virtual) {
199       assert(invoke_code == Bytecodes::_invokeinterface, "");

401   assert(CDSConfig::is_dumping_archive(), "sanity");
402 
403   if (_resolved_indy_entries != nullptr) {
404     remove_resolved_indy_entries_if_non_deterministic();
405   }
406   if (_resolved_field_entries != nullptr) {
407     remove_resolved_field_entries_if_non_deterministic();
408   }
409   if (_resolved_method_entries != nullptr) {
410     remove_resolved_method_entries_if_non_deterministic();
411   }
412 }
413 
414 void ConstantPoolCache::remove_resolved_field_entries_if_non_deterministic() {
415   ConstantPool* cp = constant_pool();
416   ConstantPool* src_cp =  ArchiveBuilder::current()->get_source_addr(cp);
417   for (int i = 0; i < _resolved_field_entries->length(); i++) {
418     ResolvedFieldEntry* rfi = _resolved_field_entries->adr_at(i);
419     int cp_index = rfi->constant_pool_index();
420     bool archived = false;
421     bool resolved = rfi->is_resolved(Bytecodes::_getfield)  ||


422                     rfi->is_resolved(Bytecodes::_putfield);
423     if (resolved && AOTConstantPoolResolver::is_resolution_deterministic(src_cp, cp_index)) {
424       rfi->mark_and_relocate();
425       archived = true;
426     } else {
427       rfi->remove_unshareable_info();
428     }
429     if (resolved) {
430       LogStreamHandle(Trace, cds, resolve) log;
431       if (log.is_enabled()) {
432         ResourceMark rm;
433         int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index);
434         Symbol* klass_name = cp->klass_name_at(klass_cp_index);
435         Symbol* name = cp->uncached_name_ref_at(cp_index);
436         Symbol* signature = cp->uncached_signature_ref_at(cp_index);
437         log.print("%s field  CP entry [%3d]: %s => %s.%s:%s",
438                   (archived ? "archived" : "reverted"),
439                   cp_index,
440                   cp->pool_holder()->name()->as_C_string(),
441                   klass_name->as_C_string(), name->as_C_string(), signature->as_C_string());
442       }
443     }
444     ArchiveBuilder::alloc_stats()->record_field_cp_entry(archived, resolved && !archived);
445   }
446 }
447 
448 void ConstantPoolCache::remove_resolved_method_entries_if_non_deterministic() {
449   ConstantPool* cp = constant_pool();
450   ConstantPool* src_cp =  ArchiveBuilder::current()->get_source_addr(cp);
451   for (int i = 0; i < _resolved_method_entries->length(); i++) {
452     ResolvedMethodEntry* rme = _resolved_method_entries->adr_at(i);
453     int cp_index = rme->constant_pool_index();
454     bool archived = false;
455     bool resolved = rme->is_resolved(Bytecodes::_invokevirtual)   ||
456                     rme->is_resolved(Bytecodes::_invokespecial)   ||

457                     rme->is_resolved(Bytecodes::_invokeinterface) ||
458                     rme->is_resolved(Bytecodes::_invokehandle);
459 
460     // Just for safety -- this should not happen, but do not archive if we ever see this.
461     resolved &= !(rme->is_resolved(Bytecodes::_invokestatic));
462 
463     if (resolved && can_archive_resolved_method(src_cp, rme)) {
464       rme->mark_and_relocate(src_cp);
465       archived = true;
466     } else {
467       rme->remove_unshareable_info();
468     }
469     if (resolved) {
470       LogStreamHandle(Trace, cds, resolve) log;
471       if (log.is_enabled()) {
472         ResourceMark rm;
473         int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index);
474         Symbol* klass_name = cp->klass_name_at(klass_cp_index);
475         Symbol* name = cp->uncached_name_ref_at(cp_index);
476         Symbol* signature = cp->uncached_signature_ref_at(cp_index);
477         log.print("%s%s method CP entry [%3d]: %s %s.%s:%s",
478                   (archived ? "archived" : "reverted"),
479                   (rme->is_resolved(Bytecodes::_invokeinterface) ? " interface" : ""),
480                   cp_index,
481                   cp->pool_holder()->name()->as_C_string(),
482                   klass_name->as_C_string(), name->as_C_string(), signature->as_C_string());

540     // update the vtable_index in method_entry (not implemented)
541     return false;
542   }
543 
544   if (!method_entry->is_resolved(Bytecodes::_invokevirtual)) {
545     if (method_entry->method() == nullptr) {
546       return false;
547     }
548     if (method_entry->method()->is_continuation_native_intrinsic()) {
549       return false; // FIXME: corresponding stub is generated on demand during method resolution (see LinkResolver::resolve_static_call).
550     }
551   }
552 
553   int cp_index = method_entry->constant_pool_index();
554   assert(src_cp->tag_at(cp_index).is_method() || src_cp->tag_at(cp_index).is_interface_method(), "sanity");
555 
556   if (!AOTConstantPoolResolver::is_resolution_deterministic(src_cp, cp_index)) {
557     return false;
558   }
559 
560   if (method_entry->is_resolved(Bytecodes::_invokeinterface) ||

561       method_entry->is_resolved(Bytecodes::_invokevirtual) ||
562       method_entry->is_resolved(Bytecodes::_invokespecial)) {
563     return true;
564   } else if (method_entry->is_resolved(Bytecodes::_invokehandle)) {
565     if (CDSConfig::is_dumping_invokedynamic()) {
566       // invokehandle depends on archived MethodType and LambdaForms.
567       return true;
568     } else {
569       return false;
570     }
571   } else {
572     return false;
573   }
574 }
575 #endif // INCLUDE_CDS
576 
577 void ConstantPoolCache::deallocate_contents(ClassLoaderData* data) {
578   assert(!is_shared(), "shared caches are not deallocated");
579   data->remove_handle(_resolved_references);
580   set_resolved_references(OopHandle());

 32 #include "classfile/systemDictionaryShared.hpp"
 33 #include "classfile/vmClasses.hpp"
 34 #include "code/codeCache.hpp"
 35 #include "interpreter/bytecodeStream.hpp"
 36 #include "interpreter/bytecodes.hpp"
 37 #include "interpreter/interpreter.hpp"
 38 #include "interpreter/linkResolver.hpp"
 39 #include "interpreter/rewriter.hpp"
 40 #include "logging/log.hpp"
 41 #include "logging/logStream.hpp"
 42 #include "memory/metadataFactory.hpp"
 43 #include "memory/metaspaceClosure.hpp"
 44 #include "memory/resourceArea.hpp"
 45 #include "oops/access.inline.hpp"
 46 #include "oops/compressedOops.hpp"
 47 #include "oops/constantPool.inline.hpp"
 48 #include "oops/cpCache.inline.hpp"
 49 #include "oops/method.inline.hpp"
 50 #include "oops/objArrayOop.inline.hpp"
 51 #include "oops/oop.inline.hpp"
 52 #include "oops/method.inline.hpp"
 53 #include "oops/resolvedFieldEntry.hpp"
 54 #include "oops/resolvedIndyEntry.hpp"
 55 #include "oops/resolvedMethodEntry.hpp"
 56 #include "prims/methodHandles.hpp"
 57 #include "runtime/arguments.hpp"
 58 #include "runtime/atomic.hpp"
 59 #include "runtime/handles.inline.hpp"
 60 #include "runtime/mutexLocker.hpp"
 61 #include "runtime/synchronizer.hpp"
 62 #include "runtime/vm_version.hpp"
 63 #include "utilities/macros.hpp"
 64 
 65 // Implementation of ConstantPoolCache
 66 
 67 template <class T>
 68 static Array<T>* initialize_resolved_entries_array(ClassLoaderData* loader_data, GrowableArray<T> entries, TRAPS) {
 69   Array<T>* resolved_entries;
 70   if (entries.length() != 0) {
 71     resolved_entries = MetadataFactory::new_array<T>(loader_data, entries.length(), CHECK_NULL);
 72     for (int i = 0; i < entries.length(); i++) {

160     }
161     default:
162       ShouldNotReachHere();
163       break;
164   }
165 
166   // Note:  byte_no also appears in TemplateTable::resolve.
167   if (byte_no == 1) {
168     assert(invoke_code != Bytecodes::_invokevirtual &&
169            invoke_code != Bytecodes::_invokeinterface, "");
170     bool do_resolve = true;
171     // Don't mark invokespecial to method as resolved if sender is an interface.  The receiver
172     // has to be checked that it is a subclass of the current class every time this bytecode
173     // is executed.
174     if (invoke_code == Bytecodes::_invokespecial && sender_is_interface &&
175         method->name() != vmSymbols::object_initializer_name()) {
176       do_resolve = false;
177     }
178     if (invoke_code == Bytecodes::_invokestatic) {
179       assert(method->method_holder()->is_initialized() ||
180              method->method_holder()->is_reentrant_initialization(JavaThread::current()) ||
181              (CDSConfig::is_dumping_archive() && VM_Version::supports_fast_class_init_checks()),
182              "invalid class initialization state for invoke_static");
183 
184       if (!VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
185         // Don't mark invokestatic to method as resolved if the holder class has not yet completed
186         // initialization. An invokestatic must only proceed if the class is initialized, but if
187         // we resolve it before then that class initialization check is skipped.
188         //
189         // When fast class initialization checks are supported (VM_Version::supports_fast_class_init_checks() == true),
190         // template interpreter supports fast class initialization check for
191         // invokestatic which doesn't require call site re-resolution to
192         // enforce class initialization barrier.
193         do_resolve = false;
194       }
195     }
196     if (do_resolve) {
197       method_entry->set_bytecode1(invoke_code);
198     }
199   } else if (byte_no == 2)  {
200     if (change_to_virtual) {
201       assert(invoke_code == Bytecodes::_invokeinterface, "");

403   assert(CDSConfig::is_dumping_archive(), "sanity");
404 
405   if (_resolved_indy_entries != nullptr) {
406     remove_resolved_indy_entries_if_non_deterministic();
407   }
408   if (_resolved_field_entries != nullptr) {
409     remove_resolved_field_entries_if_non_deterministic();
410   }
411   if (_resolved_method_entries != nullptr) {
412     remove_resolved_method_entries_if_non_deterministic();
413   }
414 }
415 
416 void ConstantPoolCache::remove_resolved_field_entries_if_non_deterministic() {
417   ConstantPool* cp = constant_pool();
418   ConstantPool* src_cp =  ArchiveBuilder::current()->get_source_addr(cp);
419   for (int i = 0; i < _resolved_field_entries->length(); i++) {
420     ResolvedFieldEntry* rfi = _resolved_field_entries->adr_at(i);
421     int cp_index = rfi->constant_pool_index();
422     bool archived = false;
423     bool resolved = rfi->is_resolved(Bytecodes::_getstatic) ||
424                     rfi->is_resolved(Bytecodes::_putstatic) ||
425                     rfi->is_resolved(Bytecodes::_getfield)  ||
426                     rfi->is_resolved(Bytecodes::_putfield);
427     if (resolved && AOTConstantPoolResolver::is_resolution_deterministic(src_cp, cp_index)) {
428       rfi->mark_and_relocate();
429       archived = true;
430     } else {
431       rfi->remove_unshareable_info();
432     }
433     if (resolved) {
434       LogStreamHandle(Trace, cds, resolve) log;
435       if (log.is_enabled()) {
436         ResourceMark rm;
437         int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index);
438         Symbol* klass_name = cp->klass_name_at(klass_cp_index);
439         Symbol* name = cp->uncached_name_ref_at(cp_index);
440         Symbol* signature = cp->uncached_signature_ref_at(cp_index);
441         log.print("%s field  CP entry [%3d]: %s => %s.%s:%s",
442                   (archived ? "archived" : "reverted"),
443                   cp_index,
444                   cp->pool_holder()->name()->as_C_string(),
445                   klass_name->as_C_string(), name->as_C_string(), signature->as_C_string());
446       }
447     }
448     ArchiveBuilder::alloc_stats()->record_field_cp_entry(archived, resolved && !archived);
449   }
450 }
451 
452 void ConstantPoolCache::remove_resolved_method_entries_if_non_deterministic() {
453   ConstantPool* cp = constant_pool();
454   ConstantPool* src_cp =  ArchiveBuilder::current()->get_source_addr(cp);
455   for (int i = 0; i < _resolved_method_entries->length(); i++) {
456     ResolvedMethodEntry* rme = _resolved_method_entries->adr_at(i);
457     int cp_index = rme->constant_pool_index();
458     bool archived = false;
459     bool resolved = rme->is_resolved(Bytecodes::_invokevirtual)   ||
460                     rme->is_resolved(Bytecodes::_invokespecial)   ||
461                   //rme->is_resolved(Bytecodes::_invokestatic)    || // FIXME -- leyden+JEP483 merge
462                     rme->is_resolved(Bytecodes::_invokeinterface) ||
463                     rme->is_resolved(Bytecodes::_invokehandle);




464     if (resolved && can_archive_resolved_method(src_cp, rme)) {
465       rme->mark_and_relocate(src_cp);
466       archived = true;
467     } else {
468       rme->remove_unshareable_info();
469     }
470     if (resolved) {
471       LogStreamHandle(Trace, cds, resolve) log;
472       if (log.is_enabled()) {
473         ResourceMark rm;
474         int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index);
475         Symbol* klass_name = cp->klass_name_at(klass_cp_index);
476         Symbol* name = cp->uncached_name_ref_at(cp_index);
477         Symbol* signature = cp->uncached_signature_ref_at(cp_index);
478         log.print("%s%s method CP entry [%3d]: %s %s.%s:%s",
479                   (archived ? "archived" : "reverted"),
480                   (rme->is_resolved(Bytecodes::_invokeinterface) ? " interface" : ""),
481                   cp_index,
482                   cp->pool_holder()->name()->as_C_string(),
483                   klass_name->as_C_string(), name->as_C_string(), signature->as_C_string());

541     // update the vtable_index in method_entry (not implemented)
542     return false;
543   }
544 
545   if (!method_entry->is_resolved(Bytecodes::_invokevirtual)) {
546     if (method_entry->method() == nullptr) {
547       return false;
548     }
549     if (method_entry->method()->is_continuation_native_intrinsic()) {
550       return false; // FIXME: corresponding stub is generated on demand during method resolution (see LinkResolver::resolve_static_call).
551     }
552   }
553 
554   int cp_index = method_entry->constant_pool_index();
555   assert(src_cp->tag_at(cp_index).is_method() || src_cp->tag_at(cp_index).is_interface_method(), "sanity");
556 
557   if (!AOTConstantPoolResolver::is_resolution_deterministic(src_cp, cp_index)) {
558     return false;
559   }
560 
561   if (method_entry->is_resolved(Bytecodes::_invokestatic) ||
562       method_entry->is_resolved(Bytecodes::_invokeinterface) ||
563       method_entry->is_resolved(Bytecodes::_invokevirtual) ||
564       method_entry->is_resolved(Bytecodes::_invokespecial)) {
565     return true;
566   } else if (method_entry->is_resolved(Bytecodes::_invokehandle)) {
567     if (CDSConfig::is_dumping_invokedynamic()) {
568       // invokehandle depends on archived MethodType and LambdaForms.
569       return true;
570     } else {
571       return false;
572     }
573   } else {
574     return false;
575   }
576 }
577 #endif // INCLUDE_CDS
578 
579 void ConstantPoolCache::deallocate_contents(ClassLoaderData* data) {
580   assert(!is_shared(), "shared caches are not deallocated");
581   data->remove_handle(_resolved_references);
582   set_resolved_references(OopHandle());
< prev index next >