< prev index next >

src/hotspot/share/oops/cpCache.cpp

Print this page

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

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

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

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

411 
412 #if INCLUDE_CDS_JAVA_HEAP
413   _archived_references_index = -1;
414   if (CDSConfig::is_dumping_heap()) {
415     ConstantPool* src_cp = ArchiveBuilder::current()->get_source_addr(constant_pool());
416     oop rr = HeapShared::scratch_resolved_references(src_cp);
417     if (rr != nullptr) {
418       _archived_references_index = HeapShared::append_root(rr);
419     }
420   }
421 #endif
422 }
423 
424 void ConstantPoolCache::remove_resolved_field_entries_if_non_deterministic() {
425   ConstantPool* cp = constant_pool();
426   ConstantPool* src_cp =  ArchiveBuilder::current()->get_source_addr(cp);
427   for (int i = 0; i < _resolved_field_entries->length(); i++) {
428     ResolvedFieldEntry* rfi = _resolved_field_entries->adr_at(i);
429     int cp_index = rfi->constant_pool_index();
430     bool archived = false;
431     bool resolved = rfi->is_resolved(Bytecodes::_getfield)  ||


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

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

550     // update the vtable_index in method_entry (not implemented)
551     return false;
552   }
553 
554   if (!method_entry->is_resolved(Bytecodes::_invokevirtual)) {
555     if (method_entry->method() == nullptr) {
556       return false;
557     }
558     if (method_entry->method()->is_continuation_native_intrinsic()) {
559       return false; // FIXME: corresponding stub is generated on demand during method resolution (see LinkResolver::resolve_static_call).
560     }
561   }
562 
563   int cp_index = method_entry->constant_pool_index();
564   assert(src_cp->tag_at(cp_index).is_method() || src_cp->tag_at(cp_index).is_interface_method(), "sanity");
565 
566   if (!AOTConstantPoolResolver::is_resolution_deterministic(src_cp, cp_index)) {
567     return false;
568   }
569 
570   if (method_entry->is_resolved(Bytecodes::_invokeinterface) ||

571       method_entry->is_resolved(Bytecodes::_invokevirtual) ||
572       method_entry->is_resolved(Bytecodes::_invokespecial)) {
573     return true;
574   } else if (method_entry->is_resolved(Bytecodes::_invokehandle)) {
575     if (CDSConfig::is_dumping_invokedynamic()) {
576       // invokehandle depends on archived MethodType and LambdaForms.
577       return true;
578     } else {
579       return false;
580     }
581   } else {
582     return false;
583   }
584 }
585 #endif // INCLUDE_CDS
586 
587 void ConstantPoolCache::deallocate_contents(ClassLoaderData* data) {
588   assert(!is_shared(), "shared caches are not deallocated");
589   data->remove_handle(_resolved_references);
590   set_resolved_references(OopHandle());

 31 #include "classfile/systemDictionaryShared.hpp"
 32 #include "classfile/vmClasses.hpp"
 33 #include "code/codeCache.hpp"
 34 #include "interpreter/bytecodeStream.hpp"
 35 #include "interpreter/bytecodes.hpp"
 36 #include "interpreter/interpreter.hpp"
 37 #include "interpreter/linkResolver.hpp"
 38 #include "interpreter/rewriter.hpp"
 39 #include "logging/log.hpp"
 40 #include "logging/logStream.hpp"
 41 #include "memory/metadataFactory.hpp"
 42 #include "memory/metaspaceClosure.hpp"
 43 #include "memory/resourceArea.hpp"
 44 #include "oops/access.inline.hpp"
 45 #include "oops/compressedOops.hpp"
 46 #include "oops/constantPool.inline.hpp"
 47 #include "oops/cpCache.inline.hpp"
 48 #include "oops/method.inline.hpp"
 49 #include "oops/objArrayOop.inline.hpp"
 50 #include "oops/oop.inline.hpp"
 51 #include "oops/method.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              (CDSConfig::is_dumping_archive() && VM_Version::supports_fast_class_init_checks()),
181              "invalid class initialization state for invoke_static");
182 
183       if (!VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
184         // Don't mark invokestatic to method as resolved if the holder class has not yet completed
185         // initialization. An invokestatic must only proceed if the class is initialized, but if
186         // we resolve it before then that class initialization check is skipped.
187         //
188         // When fast class initialization checks are supported (VM_Version::supports_fast_class_init_checks() == true),
189         // template interpreter supports fast class initialization check for
190         // invokestatic which doesn't require call site re-resolution to
191         // enforce class initialization barrier.
192         do_resolve = false;
193       }
194     }
195     if (do_resolve) {
196       method_entry->set_bytecode1(invoke_code);
197     }
198   } else if (byte_no == 2)  {
199     if (change_to_virtual) {
200       assert(invoke_code == Bytecodes::_invokeinterface, "");

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




474     if (resolved && can_archive_resolved_method(src_cp, rme)) {
475       rme->mark_and_relocate(src_cp);
476       archived = true;
477     } else {
478       rme->remove_unshareable_info();
479     }
480     if (resolved) {
481       LogStreamHandle(Trace, cds, resolve) log;
482       if (log.is_enabled()) {
483         ResourceMark rm;
484         int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index);
485         Symbol* klass_name = cp->klass_name_at(klass_cp_index);
486         Symbol* name = cp->uncached_name_ref_at(cp_index);
487         Symbol* signature = cp->uncached_signature_ref_at(cp_index);
488         log.print("%s%s method CP entry [%3d]: %s %s.%s:%s",
489                   (archived ? "archived" : "reverted"),
490                   (rme->is_resolved(Bytecodes::_invokeinterface) ? " interface" : ""),
491                   cp_index,
492                   cp->pool_holder()->name()->as_C_string(),
493                   klass_name->as_C_string(), name->as_C_string(), signature->as_C_string());

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