3636#include " memory/resourceArea.hpp"
3737#include " oops/constantPool.inline.hpp"
3838#include " runtime/handles.inline.hpp"
39+ #include " runtime/mutexLocker.hpp"
3940
4041static FinalImageRecipes* _final_image_recipes = nullptr ;
4142
4243void * FinalImageRecipes::operator new (size_t size) throw () {
4344 return ArchiveBuilder::current ()->ro_region_alloc (size);
4445}
4546
46- void FinalImageRecipes::record_recipes_impl () {
47- assert (CDSConfig::is_dumping_preimage_static_archive (), " must be" );
47+ void FinalImageRecipes::record_all_classes () {
48+ _all_klasses = ArchiveUtils::archive_array (ArchiveBuilder::current ()->klasses ());
49+ ArchivePtrMarker::mark_pointer (&_all_klasses);
50+ }
51+
52+ void FinalImageRecipes::record_recipes_for_constantpool () {
4853 ResourceMark rm;
49- GrowableArray<Klass*>* klasses = ArchiveBuilder::current ()->klasses ();
5054
51- // Record the indys that have been resolved in the training run. These indys will be
52- // resolved during the final image assembly.
55+ // The recipes are recorded regardless of CDSConfig::is_dumping_{invokedynamic,dynamic_proxies,reflection_data}().
56+ // If some of these options are not enabled, the corresponding recipes will be
57+ // ignored during the final image assembly.
58+
59+ GrowableArray<Array<int >*> tmp_cp_recipes;
60+ GrowableArray<int > tmp_cp_flags;
5361
54- GrowableArray<InstanceKlass*> tmp_indy_klasses;
55- GrowableArray<Array<int >*> tmp_indy_cp_indices;
56- int total_indys_to_resolve = 0 ;
62+ GrowableArray<Klass*>* klasses = ArchiveBuilder::current ()->klasses ();
5763 for (int i = 0 ; i < klasses->length (); i++) {
64+ GrowableArray<int > cp_indices;
65+ int flags = 0 ;
66+
5867 Klass* k = klasses->at (i);
5968 if (k->is_instance_klass ()) {
6069 InstanceKlass* ik = InstanceKlass::cast (k);
61- GrowableArray<int > indices;
70+ ConstantPool* cp = ik->constants ();
71+ ConstantPoolCache* cp_cache = cp->cache ();
72+
73+ for (int cp_index = 1 ; cp_index < cp->length (); cp_index++) { // Index 0 is unused
74+ if (cp->tag_at (cp_index).value () == JVM_CONSTANT_Class) {
75+ Klass* k = cp->resolved_klass_at (cp_index);
76+ if (k->is_instance_klass ()) {
77+ cp_indices.append (cp_index);
78+ flags |= HAS_CLASS;
79+ }
80+ }
81+ }
82+
83+ if (cp_cache != nullptr ) {
84+ Array<ResolvedFieldEntry>* field_entries = cp_cache->resolved_field_entries ();
85+ if (field_entries != nullptr ) {
86+ for (int i = 0 ; i < field_entries->length (); i++) {
87+ ResolvedFieldEntry* rfe = field_entries->adr_at (i);
88+ if (rfe->is_resolved (Bytecodes::_getfield) ||
89+ rfe->is_resolved (Bytecodes::_putfield)) {
90+ cp_indices.append (rfe->constant_pool_index ());
91+ flags |= HAS_FIELD_AND_METHOD;
92+ }
93+ }
94+ }
6295
63- if (ik->constants ()->cache () != nullptr ) {
64- Array<ResolvedIndyEntry>* tmp_indy_entries = ik->constants ()->cache ()->resolved_indy_entries ();
65- if (tmp_indy_entries != nullptr ) {
66- for (int i = 0 ; i < tmp_indy_entries->length (); i++) {
67- ResolvedIndyEntry* rie = tmp_indy_entries->adr_at (i);
96+ Array<ResolvedMethodEntry>* method_entries = cp_cache->resolved_method_entries ();
97+ if (method_entries != nullptr ) {
98+ for (int i = 0 ; i < method_entries->length (); i++) {
99+ ResolvedMethodEntry* rme = method_entries->adr_at (i);
100+ if (rme->is_resolved (Bytecodes::_invokevirtual) ||
101+ rme->is_resolved (Bytecodes::_invokespecial) ||
102+ rme->is_resolved (Bytecodes::_invokeinterface) ||
103+ rme->is_resolved (Bytecodes::_invokestatic) ||
104+ rme->is_resolved (Bytecodes::_invokehandle)) {
105+ cp_indices.append (rme->constant_pool_index ());
106+ flags |= HAS_FIELD_AND_METHOD;
107+ }
108+ }
109+ }
110+
111+ Array<ResolvedIndyEntry>* indy_entries = cp_cache->resolved_indy_entries ();
112+ if (indy_entries != nullptr ) {
113+ for (int i = 0 ; i < indy_entries->length (); i++) {
114+ ResolvedIndyEntry* rie = indy_entries->adr_at (i);
68115 int cp_index = rie->constant_pool_index ();
69116 if (rie->is_resolved ()) {
70- indices.append (cp_index);
117+ cp_indices.append (cp_index);
118+ flags |= HAS_INDY;
71119 }
72120 }
73121 }
74122 }
123+ }
75124
76- if (indices.length () > 0 ) {
77- tmp_indy_klasses.append (ArchiveBuilder::current ()->get_buffered_addr (ik));
78- tmp_indy_cp_indices.append (ArchiveUtils::archive_array (&indices));
79- total_indys_to_resolve += indices.length ();
80- }
125+ if (cp_indices.length () > 0 ) {
126+ tmp_cp_recipes.append (ArchiveUtils::archive_array (&cp_indices));
127+ } else {
128+ tmp_cp_recipes.append (nullptr );
81129 }
130+ tmp_cp_flags.append (flags);
82131 }
83132
84- _all_klasses = ArchiveUtils::archive_array (klasses);
85- ArchivePtrMarker::mark_pointer (&_all_klasses);
133+ _cp_recipes = ArchiveUtils::archive_array (&tmp_cp_recipes);
134+ ArchivePtrMarker::mark_pointer (&_cp_recipes);
135+
136+ _cp_flags = ArchiveUtils::archive_array (&tmp_cp_flags);
137+ ArchivePtrMarker::mark_pointer (&_cp_flags);
138+ }
86139
87- assert (tmp_indy_klasses.length () == tmp_indy_cp_indices.length (), " must be" );
88- if (tmp_indy_klasses.length () > 0 ) {
89- _indy_klasses = ArchiveUtils::archive_array (&tmp_indy_klasses);
90- _indy_cp_indices = ArchiveUtils::archive_array (&tmp_indy_cp_indices);
140+ void FinalImageRecipes::apply_recipes_for_constantpool (JavaThread* current) {
141+ assert (CDSConfig::is_dumping_final_static_archive (), " must be" );
91142
92- ArchivePtrMarker::mark_pointer (&_indy_klasses);
93- ArchivePtrMarker::mark_pointer (&_indy_cp_indices);
143+ for (int i = 0 ; i < _all_klasses->length (); i++) {
144+ Array<int >* cp_indices = _cp_recipes->at (i);
145+ int flags = _cp_flags->at (i);
146+ if (cp_indices != nullptr ) {
147+ InstanceKlass* ik = InstanceKlass::cast (_all_klasses->at (i));
148+ if (ik->is_loaded ()) {
149+ ResourceMark rm (current);
150+ ConstantPool* cp = ik->constants ();
151+ GrowableArray<bool > preresolve_list (cp->length (), cp->length (), false );
152+ for (int j = 0 ; j < cp_indices->length (); j++) {
153+ preresolve_list.at_put (cp_indices->at (j), true );
154+ }
155+ if ((flags & HAS_CLASS) != 0 ) {
156+ AOTConstantPoolResolver::preresolve_class_cp_entries (current, ik, &preresolve_list);
157+ }
158+ if ((flags & HAS_FIELD_AND_METHOD) != 0 ) {
159+ AOTConstantPoolResolver::preresolve_field_and_method_cp_entries (current, ik, &preresolve_list);
160+ }
161+ if ((flags & HAS_INDY) != 0 ) {
162+ AOTConstantPoolResolver::preresolve_indy_cp_entries (current, ik, &preresolve_list);
163+ }
164+ }
165+ }
94166 }
95- log_info (cds)(" %d indies in %d classes will be resolved in final CDS image" , total_indys_to_resolve, tmp_indy_klasses.length ());
96167}
97168
98169void FinalImageRecipes::load_all_classes (TRAPS) {
@@ -122,27 +193,11 @@ void FinalImageRecipes::load_all_classes(TRAPS) {
122193 }
123194}
124195
125- void FinalImageRecipes::apply_recipes_for_invokedynamic (TRAPS) {
126- assert (CDSConfig::is_dumping_final_static_archive (), " must be" );
127-
128- if (CDSConfig::is_dumping_invokedynamic () && _indy_klasses != nullptr ) {
129- assert (_indy_cp_indices != nullptr , " must be" );
130- for (int i = 0 ; i < _indy_klasses->length (); i++) {
131- InstanceKlass* ik = _indy_klasses->at (i);
132- ConstantPool* cp = ik->constants ();
133- Array<int >* cp_indices = _indy_cp_indices->at (i);
134- GrowableArray<bool > preresolve_list (cp->length (), cp->length (), false );
135- for (int j = 0 ; j < cp_indices->length (); j++) {
136- preresolve_list.at_put (cp_indices->at (j), true );
137- }
138- AOTConstantPoolResolver::preresolve_indy_cp_entries (THREAD, ik, &preresolve_list);
139- }
140- }
141- }
142-
143196void FinalImageRecipes::record_recipes () {
197+ assert (CDSConfig::is_dumping_preimage_static_archive (), " must be" );
144198 _final_image_recipes = new FinalImageRecipes ();
145- _final_image_recipes->record_recipes_impl ();
199+ _final_image_recipes->record_all_classes ();
200+ _final_image_recipes->record_recipes_for_constantpool ();
146201}
147202
148203void FinalImageRecipes::apply_recipes (TRAPS) {
@@ -163,7 +218,7 @@ void FinalImageRecipes::apply_recipes(TRAPS) {
163218
164219void FinalImageRecipes::apply_recipes_impl (TRAPS) {
165220 load_all_classes (CHECK);
166- apply_recipes_for_invokedynamic (CHECK );
221+ apply_recipes_for_constantpool (THREAD );
167222}
168223
169224void FinalImageRecipes::serialize (SerializeClosure* soc) {
0 commit comments