1 /*
  2  * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  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 "ci/ciField.hpp"
 27 #include "ci/ciInstance.hpp"
 28 #include "ci/ciInstanceKlass.hpp"
 29 #include "ci/ciUtilities.inline.hpp"
 30 #include "classfile/javaClasses.hpp"
 31 #include "classfile/vmClasses.hpp"
 32 #include "memory/allocation.hpp"
 33 #include "memory/allocation.inline.hpp"
 34 #include "memory/resourceArea.hpp"
 35 #include "oops/instanceKlass.inline.hpp"
 36 #include "oops/klass.inline.hpp"
 37 #include "oops/oop.inline.hpp"
 38 #include "oops/fieldStreams.inline.hpp"
 39 #include "runtime/fieldDescriptor.inline.hpp"
 40 #include "runtime/handles.inline.hpp"
 41 #include "runtime/jniHandles.inline.hpp"
 42 
 43 // ciInstanceKlass
 44 //
 45 // This class represents a Klass* in the HotSpot virtual machine
 46 // whose Klass part in an InstanceKlass.
 47 
 48 
 49 // ------------------------------------------------------------------
 50 // ciInstanceKlass::ciInstanceKlass
 51 //
 52 // Loaded instance klass.
 53 ciInstanceKlass::ciInstanceKlass(Klass* k) :
 54   ciKlass(k)
 55 {
 56   assert(get_Klass()->is_instance_klass(), "wrong type");
 57 
 58   InstanceKlass* ik = get_instanceKlass();
 59 
 60 #ifdef ASSERT
 61   if (!ik->is_loaded()) {
 62     ResourceMark rm;
 63     ik->print_on(tty);
 64     assert(false, "must be at least loaded: %s", ik->name()->as_C_string());
 65   }
 66 #endif // ASSERT
 67 
 68   AccessFlags access_flags = ik->access_flags();
 69   _flags = ciFlags(access_flags);
 70   _has_finalizer = ik->has_finalizer();
 71   _has_subklass = flags().is_final() ? subklass_false : subklass_unknown;
 72   _init_state = compute_init_state(ik); // _init_state
 73   _has_nonstatic_fields = ik->has_nonstatic_fields();
 74   _has_nonstatic_concrete_methods = ik->has_nonstatic_concrete_methods();
 75   _is_hidden = ik->is_hidden();
 76   _is_record = ik->is_record();
 77   _nonstatic_fields = nullptr; // initialized lazily by compute_nonstatic_fields:
 78   _has_injected_fields = -1;
 79   _implementor = nullptr; // we will fill these lazily
 80   _transitive_interfaces = nullptr;
 81 
 82   // Ensure that the metadata wrapped by the ciMetadata is kept alive by GC.
 83   // This is primarily useful for metadata which is considered as weak roots
 84   // by the GC but need to be strong roots if reachable from a current compilation.
 85   // InstanceKlass are created for both weak and strong metadata.  Ensuring this metadata
 86   // alive covers the cases where there are weak roots without performance cost.
 87   oop holder = ik->klass_holder();
 88   if (ik->class_loader_data()->has_class_mirror_holder()) {
 89     // Though ciInstanceKlass records class loader oop, it's not enough to keep
 90     // non-strong hidden classes alive (loader == nullptr). Klass holder should
 91     // be used instead. It is enough to record a ciObject, since cached elements are never removed
 92     // during ciObjectFactory lifetime. ciObjectFactory itself is created for
 93     // every compilation and lives for the whole duration of the compilation.
 94     assert(holder != nullptr, "holder of hidden class is the mirror which is never null");
 95     (void)CURRENT_ENV->get_object(holder);
 96   }
 97 
 98   JavaThread *thread = JavaThread::current();
 99   if (ciObjectFactory::is_initialized()) {
100     _loader = JNIHandles::make_local(thread, ik->class_loader());
101     _protection_domain = JNIHandles::make_local(thread,
102                                                 ik->protection_domain());
103     _is_shared = false;
104   } else {
105     Handle h_loader(thread, ik->class_loader());
106     Handle h_protection_domain(thread, ik->protection_domain());
107     _loader = JNIHandles::make_global(h_loader);
108     _protection_domain = JNIHandles::make_global(h_protection_domain);
109     _is_shared = true;
110   }
111 
112   _has_trusted_loader = compute_has_trusted_loader();
113 
114   // Lazy fields get filled in only upon request.
115   _super  = nullptr;
116   _java_mirror = nullptr;
117 
118   if (is_shared()) {
119     if (k != vmClasses::Object_klass()) {
120       super();
121     }
122     //compute_nonstatic_fields();  // done outside of constructor
123   }
124 
125   _field_cache = nullptr;
126 }
127 
128 // Version for unloaded classes:
129 ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
130                                  jobject loader, jobject protection_domain)
131   : ciKlass(name, T_OBJECT)
132 {
133   assert(name->char_at(0) != JVM_SIGNATURE_ARRAY, "not an instance klass");
134   _init_state = (InstanceKlass::ClassState)0;
135   _has_nonstatic_fields = false;
136   _nonstatic_fields = nullptr;
137   _has_injected_fields = -1;
138   _is_hidden = false;
139   _is_record = false;
140   _loader = loader;
141   _protection_domain = protection_domain;
142   _is_shared = false;
143   _super = nullptr;
144   _java_mirror = nullptr;
145   _field_cache = nullptr;
146   _has_trusted_loader = compute_has_trusted_loader();
147 }
148 
149 
150 
151 // ------------------------------------------------------------------
152 // ciInstanceKlass::compute_shared_is_initialized
153 void ciInstanceKlass::compute_shared_init_state() {
154   GUARDED_VM_ENTRY(
155     InstanceKlass* ik = get_instanceKlass();
156     _init_state = compute_init_state(ik);
157   )
158 }
159 
160 InstanceKlass::ClassState ciInstanceKlass::compute_init_state(InstanceKlass* ik) {
161   ASSERT_IN_VM;
162   ciEnv* env = CURRENT_ENV;
163   if (env != nullptr && env->is_precompiled()) {
164     return env->compute_init_state_for_precompiled(ik);
165   } else {
166     return ik->init_state();
167   }
168 }
169 
170 // ------------------------------------------------------------------
171 // ciInstanceKlass::compute_shared_has_subklass
172 bool ciInstanceKlass::compute_shared_has_subklass() {
173   GUARDED_VM_ENTRY(
174     InstanceKlass* ik = get_instanceKlass();
175     _has_subklass = ik->subklass() != nullptr ? subklass_true : subklass_false;
176     return _has_subklass == subklass_true;
177   )
178 }
179 
180 // ------------------------------------------------------------------
181 // ciInstanceKlass::loader
182 oop ciInstanceKlass::loader() {
183   ASSERT_IN_VM;
184   return JNIHandles::resolve(_loader);
185 }
186 
187 // ------------------------------------------------------------------
188 // ciInstanceKlass::loader_handle
189 jobject ciInstanceKlass::loader_handle() {
190   return _loader;
191 }
192 
193 // ------------------------------------------------------------------
194 // ciInstanceKlass::protection_domain
195 oop ciInstanceKlass::protection_domain() {
196   ASSERT_IN_VM;
197   return JNIHandles::resolve(_protection_domain);
198 }
199 
200 // ------------------------------------------------------------------
201 // ciInstanceKlass::protection_domain_handle
202 jobject ciInstanceKlass::protection_domain_handle() {
203   return _protection_domain;
204 }
205 
206 // ------------------------------------------------------------------
207 // ciInstanceKlass::field_cache
208 //
209 // Get the field cache associated with this klass.
210 ciConstantPoolCache* ciInstanceKlass::field_cache() {
211   if (is_shared()) {
212     return nullptr;
213   }
214   if (_field_cache == nullptr) {
215     assert(!is_java_lang_Object(), "Object has no fields");
216     Arena* arena = CURRENT_ENV->arena();
217     _field_cache = new (arena) ciConstantPoolCache(arena, 5);
218   }
219   return _field_cache;
220 }
221 
222 // ------------------------------------------------------------------
223 // ciInstanceKlass::get_canonical_holder
224 //
225 ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) {
226   #ifdef ASSERT
227   if (!(offset >= 0 && offset < layout_helper_size_in_bytes())) {
228     tty->print("*** get_canonical_holder(%d) on ", offset);
229     this->print();
230     tty->print_cr(" ***");
231   };
232   assert(offset >= 0 && offset < layout_helper_size_in_bytes(), "offset must be tame");
233   #endif
234 
235   if (offset < instanceOopDesc::base_offset_in_bytes()) {
236     // All header offsets belong properly to java/lang/Object.
237     return CURRENT_ENV->Object_klass();
238   }
239 
240   ciInstanceKlass* self = this;
241   assert(self->is_loaded(), "must be loaded to access field info");
242   ciField* field = self->get_field_by_offset(offset, false);
243   if (field != nullptr) {
244     return field->holder();
245   } else {
246     for (;;) {
247       assert(self->is_loaded(), "must be loaded to have size");
248       ciInstanceKlass* super = self->super();
249       if (super == nullptr ||
250           super->nof_nonstatic_fields() == 0 ||
251           super->layout_helper_size_in_bytes() <= offset) {
252         return self;
253       } else {
254         self = super;  // return super->get_canonical_holder(offset)
255       }
256     }
257   }
258 }
259 
260 // ------------------------------------------------------------------
261 // ciInstanceKlass::is_java_lang_Object
262 //
263 // Is this klass java.lang.Object?
264 bool ciInstanceKlass::is_java_lang_Object() const {
265   return equals(CURRENT_ENV->Object_klass());
266 }
267 
268 // ------------------------------------------------------------------
269 // ciInstanceKlass::uses_default_loader
270 bool ciInstanceKlass::uses_default_loader() const {
271   // Note:  We do not need to resolve the handle or enter the VM
272   // in order to test null-ness.
273   return _loader == nullptr;
274 }
275 
276 // ------------------------------------------------------------------
277 
278 /**
279  * Return basic type of boxed value for box klass or T_OBJECT if not.
280  */
281 BasicType ciInstanceKlass::box_klass_type() const {
282   if (uses_default_loader() && is_loaded()) {
283     return vmClasses::box_klass_type(get_Klass());
284   } else {
285     return T_OBJECT;
286   }
287 }
288 
289 /**
290  * Is this boxing klass?
291  */
292 bool ciInstanceKlass::is_box_klass() const {
293   return is_java_primitive(box_klass_type());
294 }
295 
296 /**
297  *  Is this boxed value offset?
298  */
299 bool ciInstanceKlass::is_boxed_value_offset(int offset) const {
300   BasicType bt = box_klass_type();
301   return is_java_primitive(bt) &&
302          (offset == java_lang_boxing_object::value_offset(bt));
303 }
304 
305 // ------------------------------------------------------------------
306 // ciInstanceKlass::is_in_package
307 //
308 // Is this klass in the given package?
309 bool ciInstanceKlass::is_in_package(const char* packagename, int len) {
310   // To avoid class loader mischief, this test always rejects application classes.
311   if (!uses_default_loader())
312     return false;
313   GUARDED_VM_ENTRY(
314     return is_in_package_impl(packagename, len);
315   )
316 }
317 
318 bool ciInstanceKlass::is_in_package_impl(const char* packagename, int len) {
319   ASSERT_IN_VM;
320 
321   // If packagename contains trailing '/' exclude it from the
322   // prefix-test since we test for it explicitly.
323   if (packagename[len - 1] == '/')
324     len--;
325 
326   if (!name()->starts_with(packagename, len))
327     return false;
328 
329   // Test if the class name is something like "java/lang".
330   if ((len + 1) > name()->utf8_length())
331     return false;
332 
333   // Test for trailing '/'
334   if (name()->char_at(len) != '/')
335     return false;
336 
337   // Make sure it's not actually in a subpackage:
338   if (name()->index_of_at(len+1, "/", 1) >= 0)
339     return false;
340 
341   return true;
342 }
343 
344 // ------------------------------------------------------------------
345 // ciInstanceKlass::print_impl
346 //
347 // Implementation of the print method.
348 void ciInstanceKlass::print_impl(outputStream* st) {
349   ciKlass::print_impl(st);
350   GUARDED_VM_ENTRY(st->print(" loader=" INTPTR_FORMAT, p2i(loader()));)
351   if (is_loaded()) {
352     st->print(" initialized=%s finalized=%s subklass=%s size=%d flags=",
353               bool_to_str(is_initialized()),
354               bool_to_str(has_finalizer()),
355               bool_to_str(has_subklass()),
356               layout_helper());
357 
358     _flags.print_klass_flags(st);
359 
360     if (_super) {
361       st->print(" super=");
362       _super->print_name_on(st);
363     }
364     if (_java_mirror) {
365       st->print(" mirror=PRESENT");
366     }
367   }
368 }
369 
370 // ------------------------------------------------------------------
371 // ciInstanceKlass::super
372 //
373 // Get the superklass of this klass.
374 ciInstanceKlass* ciInstanceKlass::super() {
375   assert(is_loaded(), "must be loaded");
376   if (_super == nullptr && !is_java_lang_Object()) {
377     GUARDED_VM_ENTRY(
378       Klass* super_klass = get_instanceKlass()->super();
379       _super = CURRENT_ENV->get_instance_klass(super_klass);
380     )
381   }
382   return _super;
383 }
384 
385 // ------------------------------------------------------------------
386 // ciInstanceKlass::java_mirror
387 //
388 // Get the instance of java.lang.Class corresponding to this klass.
389 // Cache it on this->_java_mirror.
390 ciInstance* ciInstanceKlass::java_mirror() {
391   if (is_shared()) {
392     return ciKlass::java_mirror();
393   }
394   if (_java_mirror == nullptr) {
395     _java_mirror = ciKlass::java_mirror();
396   }
397   return _java_mirror;
398 }
399 
400 // ------------------------------------------------------------------
401 // ciInstanceKlass::unique_concrete_subklass
402 ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() {
403   if (!is_loaded())     return nullptr; // No change if class is not loaded
404   if (!is_abstract())   return nullptr; // Only applies to abstract classes.
405   if (!has_subklass())  return nullptr; // Must have at least one subklass.
406   VM_ENTRY_MARK;
407   InstanceKlass* ik = get_instanceKlass();
408   Klass* up = ik->up_cast_abstract();
409   assert(up->is_instance_klass(), "must be InstanceKlass");
410   if (ik == up) {
411     return nullptr;
412   }
413   return CURRENT_THREAD_ENV->get_instance_klass(up);
414 }
415 
416 // ------------------------------------------------------------------
417 // ciInstanceKlass::has_finalizable_subclass
418 bool ciInstanceKlass::has_finalizable_subclass() {
419   if (!is_loaded())     return true;
420   VM_ENTRY_MARK;
421   return Dependencies::find_finalizable_subclass(get_instanceKlass()) != nullptr;
422 }
423 
424 // ------------------------------------------------------------------
425 // ciInstanceKlass::contains_field_offset
426 bool ciInstanceKlass::contains_field_offset(int offset) {
427   VM_ENTRY_MARK;
428   return get_instanceKlass()->contains_field_offset(offset);
429 }
430 
431 // ------------------------------------------------------------------
432 // ciInstanceKlass::get_field_by_offset
433 ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) {
434   if (!is_static) {
435     for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) {
436       ciField* field = _nonstatic_fields->at(i);
437       int  field_off = field->offset_in_bytes();
438       if (field_off == field_offset)
439         return field;
440       if (field_off > field_offset)
441         break;
442       // could do binary search or check bins, but probably not worth it
443     }
444     return nullptr;
445   }
446   VM_ENTRY_MARK;
447   InstanceKlass* k = get_instanceKlass();
448   fieldDescriptor fd;
449   if (!k->find_field_from_offset(field_offset, is_static, &fd)) {
450     return nullptr;
451   }
452   ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
453   return field;
454 }
455 
456 // ------------------------------------------------------------------
457 // ciInstanceKlass::get_field_by_name
458 ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) {
459   VM_ENTRY_MARK;
460   InstanceKlass* k = get_instanceKlass();
461   fieldDescriptor fd;
462   Klass* def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd);
463   if (def == nullptr) {
464     return nullptr;
465   }
466   ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
467   return field;
468 }
469 
470 
471 static int sort_field_by_offset(ciField** a, ciField** b) {
472   return (*a)->offset_in_bytes() - (*b)->offset_in_bytes();
473   // (no worries about 32-bit overflow...)
474 }
475 
476 // ------------------------------------------------------------------
477 // ciInstanceKlass::compute_nonstatic_fields
478 int ciInstanceKlass::compute_nonstatic_fields() {
479   assert(is_loaded(), "must be loaded");
480 
481   if (_nonstatic_fields != nullptr)
482     return _nonstatic_fields->length();
483 
484   if (!has_nonstatic_fields()) {
485     Arena* arena = CURRENT_ENV->arena();
486     _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, nullptr);
487     return 0;
488   }
489   assert(!is_java_lang_Object(), "bootstrap OK");
490 
491   ciInstanceKlass* super = this->super();
492   GrowableArray<ciField*>* super_fields = nullptr;
493   if (super != nullptr && super->has_nonstatic_fields()) {
494     int super_flen   = super->nof_nonstatic_fields();
495     super_fields = super->_nonstatic_fields;
496     assert(super_flen == 0 || super_fields != nullptr, "first get nof_fields");
497   }
498 
499   GrowableArray<ciField*>* fields = nullptr;
500   GUARDED_VM_ENTRY({
501       fields = compute_nonstatic_fields_impl(super_fields);
502     });
503 
504   if (fields == nullptr) {
505     // This can happen if this class (java.lang.Class) has invisible fields.
506     if (super_fields != nullptr) {
507       _nonstatic_fields = super_fields;
508       return super_fields->length();
509     } else {
510       return 0;
511     }
512   }
513 
514   int flen = fields->length();
515 
516   // Now sort them by offset, ascending.
517   // (In principle, they could mix with superclass fields.)
518   fields->sort(sort_field_by_offset);
519   _nonstatic_fields = fields;
520   return flen;
521 }
522 
523 GrowableArray<ciField*>*
524 ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>*
525                                                super_fields) {
526   ASSERT_IN_VM;
527   Arena* arena = CURRENT_ENV->arena();
528   int flen = 0;
529   GrowableArray<ciField*>* fields = nullptr;
530   InstanceKlass* k = get_instanceKlass();
531   for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
532     if (fs.access_flags().is_static())  continue;
533     flen += 1;
534   }
535 
536   // allocate the array:
537   if (flen == 0) {
538     return nullptr;  // return nothing if none are locally declared
539   }
540   if (super_fields != nullptr) {
541     flen += super_fields->length();
542   }
543   fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, nullptr);
544   if (super_fields != nullptr) {
545     fields->appendAll(super_fields);
546   }
547 
548   for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
549     if (fs.access_flags().is_static())  continue;
550     fieldDescriptor& fd = fs.field_descriptor();
551     ciField* field = new (arena) ciField(&fd);
552     fields->append(field);
553   }
554   assert(fields->length() == flen, "sanity");
555   return fields;
556 }
557 
558 bool ciInstanceKlass::compute_injected_fields_helper() {
559   ASSERT_IN_VM;
560   InstanceKlass* k = get_instanceKlass();
561 
562   for (InternalFieldStream fs(k); !fs.done(); fs.next()) {
563     if (fs.access_flags().is_static())  continue;
564     return true;
565   }
566   return false;
567 }
568 
569 void ciInstanceKlass::compute_injected_fields() {
570   assert(is_loaded(), "must be loaded");
571 
572   int has_injected_fields = 0;
573   if (super() != nullptr && super()->has_injected_fields()) {
574     has_injected_fields = 1;
575   } else {
576     GUARDED_VM_ENTRY({
577         has_injected_fields = compute_injected_fields_helper() ? 1 : 0;
578       });
579   }
580   // may be concurrently initialized for shared ciInstanceKlass objects
581   assert(_has_injected_fields == -1 || _has_injected_fields == has_injected_fields, "broken concurrent initialization");
582   _has_injected_fields = has_injected_fields;
583 }
584 
585 bool ciInstanceKlass::has_object_fields() const {
586   GUARDED_VM_ENTRY(
587       return get_instanceKlass()->nonstatic_oop_map_size() > 0;
588     );
589 }
590 
591 bool ciInstanceKlass::compute_has_trusted_loader() {
592   ASSERT_IN_VM;
593   oop loader_oop = loader();
594   if (loader_oop == nullptr) {
595     return true; // bootstrap class loader
596   }
597   return java_lang_ClassLoader::is_trusted_loader(loader_oop);
598 }
599 
600 // ------------------------------------------------------------------
601 // ciInstanceKlass::find_method
602 //
603 // Find a method in this klass.
604 ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) {
605   VM_ENTRY_MARK;
606   InstanceKlass* k = get_instanceKlass();
607   Symbol* name_sym = name->get_symbol();
608   Symbol* sig_sym= signature->get_symbol();
609 
610   Method* m = k->find_method(name_sym, sig_sym);
611   if (m == nullptr)  return nullptr;
612 
613   return CURRENT_THREAD_ENV->get_method(m);
614 }
615 
616 // ------------------------------------------------------------------
617 // ciInstanceKlass::is_leaf_type
618 bool ciInstanceKlass::is_leaf_type() {
619   assert(is_loaded(), "must be loaded");
620   if (is_shared()) {
621     return is_final();  // approximately correct
622   } else {
623     return !has_subklass() && (nof_implementors() == 0);
624   }
625 }
626 
627 // ------------------------------------------------------------------
628 // ciInstanceKlass::implementor
629 //
630 // Report an implementor of this interface.
631 // Note that there are various races here, since my copy
632 // of _nof_implementors might be out of date with respect
633 // to results returned by InstanceKlass::implementor.
634 // This is OK, since any dependencies we decide to assert
635 // will be checked later under the Compile_lock.
636 ciInstanceKlass* ciInstanceKlass::implementor() {
637   ciInstanceKlass* impl = _implementor;
638   if (impl == nullptr) {
639     if (is_shared()) {
640       impl = this; // assume a well-known interface never has a unique implementor
641     } else {
642       // Go into the VM to fetch the implementor.
643       VM_ENTRY_MARK;
644       InstanceKlass* ik = get_instanceKlass();
645       Klass* implk = ik->implementor();
646       if (implk != nullptr) {
647         if (implk == ik) {
648           // More than one implementors. Use 'this' in this case.
649           impl = this;
650         } else {
651           impl = CURRENT_THREAD_ENV->get_instance_klass(implk);
652         }
653       }
654     }
655     // Memoize this result.
656     _implementor = impl;
657   }
658   return impl;
659 }
660 
661 // Utility class for printing of the contents of the static fields for
662 // use by compilation replay.  It only prints out the information that
663 // could be consumed by the compiler, so for primitive types it prints
664 // out the actual value.  For Strings it's the actual string value.
665 // For array types it it's first level array size since that's the
666 // only value which statically unchangeable.  For all other reference
667 // types it simply prints out the dynamic type.
668 
669 class StaticFinalFieldPrinter : public FieldClosure {
670   outputStream* _out;
671   const char*   _holder;
672  public:
673   StaticFinalFieldPrinter(outputStream* out, const char* holder) :
674     _out(out),
675     _holder(holder) {
676   }
677   void do_field(fieldDescriptor* fd) {
678     if (fd->is_final() && !fd->has_initial_value()) {
679       ResourceMark rm;
680       oop mirror = fd->field_holder()->java_mirror();
681       _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());
682       BasicType field_type = fd->field_type();
683       switch (field_type) {
684         case T_BYTE:    _out->print_cr("%d", mirror->byte_field(fd->offset()));   break;
685         case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset()));   break;
686         case T_SHORT:   _out->print_cr("%d", mirror->short_field(fd->offset()));  break;
687         case T_CHAR:    _out->print_cr("%d", mirror->char_field(fd->offset()));   break;
688         case T_INT:     _out->print_cr("%d", mirror->int_field(fd->offset()));    break;
689         case T_LONG:    _out->print_cr(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset())));   break;
690         case T_FLOAT: {
691           float f = mirror->float_field(fd->offset());
692           _out->print_cr("%d", *(int*)&f);
693           break;
694         }
695         case T_DOUBLE: {
696           double d = mirror->double_field(fd->offset());
697           _out->print_cr(INT64_FORMAT, *(int64_t*)&d);
698           break;
699         }
700         case T_ARRAY:  // fall-through
701         case T_OBJECT: {
702           oop value =  mirror->obj_field_acquire(fd->offset());
703           if (value == nullptr) {
704             if (field_type == T_ARRAY) {
705               _out->print("%d", -1);
706             }
707             _out->cr();
708           } else if (value->is_instance()) {
709             assert(field_type == T_OBJECT, "");
710             if (value->is_a(vmClasses::String_klass())) {
711               const char* ascii_value = java_lang_String::as_quoted_ascii(value);
712               _out->print_cr("\"%s\"", (ascii_value != nullptr) ? ascii_value : "");
713             } else {
714               const char* klass_name  = value->klass()->name()->as_quoted_ascii();
715               _out->print_cr("%s", klass_name);
716             }
717           } else if (value->is_array()) {
718             typeArrayOop ta = (typeArrayOop)value;
719             _out->print("%d", ta->length());
720             if (value->is_objArray()) {
721               objArrayOop oa = (objArrayOop)value;
722               const char* klass_name  = value->klass()->name()->as_quoted_ascii();
723               _out->print(" %s", klass_name);
724             }
725             _out->cr();
726           } else {
727             ShouldNotReachHere();
728           }
729           break;
730         }
731         default:
732           ShouldNotReachHere();
733         }
734     }
735   }
736 };
737 
738 const char *ciInstanceKlass::replay_name() const {
739   return CURRENT_ENV->replay_name(get_instanceKlass());
740 }
741 
742 void ciInstanceKlass::dump_replay_instanceKlass(outputStream* out, InstanceKlass* ik) {
743   if (ik->is_hidden()) {
744     const char *name = CURRENT_ENV->dyno_name(ik);
745     if (name != nullptr) {
746       out->print_cr("instanceKlass %s # %s", name, ik->name()->as_quoted_ascii());
747     } else {
748       out->print_cr("# instanceKlass %s", ik->name()->as_quoted_ascii());
749     }
750   } else {
751     out->print_cr("instanceKlass %s", ik->name()->as_quoted_ascii());
752   }
753 }
754 
755 GrowableArray<ciInstanceKlass*>* ciInstanceKlass::transitive_interfaces() const{
756   if (_transitive_interfaces == nullptr) {
757     const_cast<ciInstanceKlass*>(this)->compute_transitive_interfaces();
758   }
759   return _transitive_interfaces;
760 }
761 
762 void ciInstanceKlass::compute_transitive_interfaces() {
763   GUARDED_VM_ENTRY(
764           InstanceKlass* ik = get_instanceKlass();
765           Array<InstanceKlass*>* interfaces = ik->transitive_interfaces();
766           int orig_length = interfaces->length();
767           Arena* arena = CURRENT_ENV->arena();
768           int transitive_interfaces_len = orig_length + (is_interface() ? 1 : 0);
769           GrowableArray<ciInstanceKlass*>* transitive_interfaces = new(arena)GrowableArray<ciInstanceKlass*>(arena, transitive_interfaces_len,
770                                                                                                              0, nullptr);
771           for (int i = 0; i < orig_length; i++) {
772             transitive_interfaces->append(CURRENT_ENV->get_instance_klass(interfaces->at(i)));
773           }
774           if (is_interface()) {
775             transitive_interfaces->append(this);
776           }
777           _transitive_interfaces = transitive_interfaces;
778   );
779 }
780 
781 void ciInstanceKlass::dump_replay_data(outputStream* out) {
782   ResourceMark rm;
783 
784   InstanceKlass* ik = get_instanceKlass();
785   ConstantPool*  cp = ik->constants();
786 
787   // Try to record related loaded classes
788   Klass* sub = ik->subklass();
789   while (sub != nullptr) {
790     if (sub->is_instance_klass()) {
791       InstanceKlass *isub = InstanceKlass::cast(sub);
792       dump_replay_instanceKlass(out, isub);
793     }
794     sub = sub->next_sibling();
795   }
796 
797   // Dump out the state of the constant pool tags.  During replay the
798   // tags will be validated for things which shouldn't change and
799   // classes will be resolved if the tags indicate that they were
800   // resolved at compile time.
801   const char *name = replay_name();
802   out->print("ciInstanceKlass %s %d %d %d", name,
803              is_linked(), is_initialized(), cp->length());
804   for (int index = 1; index < cp->length(); index++) {
805     out->print(" %d", cp->tags()->at(index));
806   }
807   out->cr();
808   if (is_initialized()) {
809     //  Dump out the static final fields in case the compilation relies
810     //  on their value for correct replay.
811     StaticFinalFieldPrinter sffp(out, name);
812     ik->do_local_static_fields(&sffp);
813   }
814 }
815 
816 #ifdef ASSERT
817 bool ciInstanceKlass::debug_final_field_at(int offset) {
818   GUARDED_VM_ENTRY(
819     InstanceKlass* ik = get_instanceKlass();
820     fieldDescriptor fd;
821     if (ik->find_field_from_offset(offset, false, &fd)) {
822       return fd.is_final();
823     }
824   );
825   return false;
826 }
827 
828 bool ciInstanceKlass::debug_stable_field_at(int offset) {
829   GUARDED_VM_ENTRY(
830     InstanceKlass* ik = get_instanceKlass();
831     fieldDescriptor fd;
832     if (ik->find_field_from_offset(offset, false, &fd)) {
833       return fd.is_stable();
834     }
835   );
836   return false;
837 }
838 #endif