1 /*
  2  * Copyright (c) 2017, 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 "cds/cdsConfig.hpp"
 27 #include "classfile/vmSymbols.hpp"
 28 #include "code/codeCache.hpp"
 29 #include "gc/shared/barrierSet.hpp"
 30 #include "gc/shared/collectedHeap.inline.hpp"
 31 #include "gc/shared/gcLocker.inline.hpp"
 32 #include "interpreter/interpreter.hpp"
 33 #include "logging/log.hpp"
 34 #include "memory/metaspaceClosure.hpp"
 35 #include "memory/metadataFactory.hpp"
 36 #include "oops/access.hpp"
 37 #include "oops/compressedOops.inline.hpp"
 38 #include "oops/fieldStreams.inline.hpp"
 39 #include "oops/flatArrayKlass.hpp"
 40 #include "oops/inlineKlass.inline.hpp"
 41 #include "oops/instanceKlass.inline.hpp"
 42 #include "oops/method.hpp"
 43 #include "oops/oop.inline.hpp"
 44 #include "oops/objArrayKlass.hpp"
 45 #include "runtime/fieldDescriptor.inline.hpp"
 46 #include "runtime/handles.inline.hpp"
 47 #include "runtime/safepointVerifiers.hpp"
 48 #include "runtime/sharedRuntime.hpp"
 49 #include "runtime/signature.hpp"
 50 #include "runtime/thread.inline.hpp"
 51 #include "utilities/copy.hpp"
 52 
 53   // Constructor
 54 InlineKlass::InlineKlass(const ClassFileParser& parser)
 55     : InstanceKlass(parser, InlineKlass::Kind) {
 56   set_prototype_header(markWord::inline_type_prototype());
 57   assert(is_inline_klass(), "sanity");
 58   assert(prototype_header().is_inline_type(), "sanity");
 59 }
 60 
 61 InlineKlass::InlineKlass() {
 62   assert(CDSConfig::is_dumping_archive() || UseSharedSpaces, "only for CDS");
 63 }
 64 
 65 void InlineKlass::init_fixed_block() {
 66   _adr_inlineklass_fixed_block = inlineklass_static_block();
 67   // Addresses used for inline type calling convention
 68   *((Array<SigEntry>**)adr_extended_sig()) = nullptr;
 69   *((Array<VMRegPair>**)adr_return_regs()) = nullptr;
 70   *((address*)adr_pack_handler()) = nullptr;
 71   *((address*)adr_pack_handler_jobject()) = nullptr;
 72   *((address*)adr_unpack_handler()) = nullptr;
 73   assert(pack_handler() == nullptr, "pack handler not null");
 74   *((int*)adr_default_value_offset()) = 0;
 75   *((address*)adr_value_array_klasses()) = nullptr;
 76 }
 77 
 78 oop InlineKlass::default_value() {
 79   assert(is_initialized() || is_being_initialized() || is_in_error_state(), "default value is set at the beginning of initialization");
 80   oop val = java_mirror()->obj_field_acquire(default_value_offset());
 81   assert(val != nullptr, "Sanity check");
 82   assert(oopDesc::is_oop(val), "Sanity check");
 83   assert(val->is_inline_type(), "Sanity check");
 84   assert(val->klass() == this, "sanity check");
 85   return val;
 86 }
 87 
 88 int InlineKlass::first_field_offset_old() {
 89 #ifdef ASSERT
 90   int first_offset = INT_MAX;
 91   for (AllFieldStream fs(this); !fs.done(); fs.next()) {
 92     if (fs.offset() < first_offset) first_offset= fs.offset();
 93   }
 94 #endif
 95   int base_offset = instanceOopDesc::base_offset_in_bytes();
 96   // The first field of line types is aligned on a long boundary
 97   base_offset = align_up(base_offset, BytesPerLong);
 98   assert(base_offset == first_offset, "inconsistent offsets");
 99   return base_offset;
100 }
101 
102 instanceOop InlineKlass::allocate_instance(TRAPS) {
103   int size = size_helper();  // Query before forming handle.
104 
105   instanceOop oop = (instanceOop)Universe::heap()->obj_allocate(this, size, CHECK_NULL);
106   assert(oop->mark().is_inline_type(), "Expected inline type");
107   return oop;
108 }
109 
110 instanceOop InlineKlass::allocate_instance_buffer(TRAPS) {
111   int size = size_helper();  // Query before forming handle.
112 
113   instanceOop oop = (instanceOop)Universe::heap()->obj_buffer_allocate(this, size, CHECK_NULL);
114   assert(oop->mark().is_inline_type(), "Expected inline type");
115   return oop;
116 }
117 
118 int InlineKlass::nonstatic_oop_count() {
119   int oops = 0;
120   int map_count = nonstatic_oop_map_count();
121   OopMapBlock* block = start_of_nonstatic_oop_maps();
122   OopMapBlock* end = block + map_count;
123   while (block != end) {
124     oops += block->count();
125     block++;
126   }
127   return oops;
128 }
129 
130 oop InlineKlass::read_flat_field(oop obj, int offset, TRAPS) {
131   oop res = nullptr;
132   assert(is_initialized() || is_being_initialized()|| is_in_error_state(),
133         "Must be initialized, initializing or in a corner case of an escaped instance of a class that failed its initialization");
134   if (is_empty_inline_type()) {
135     res = (instanceOop)default_value();
136   } else {
137     Handle obj_h(THREAD, obj);
138     res = allocate_instance_buffer(CHECK_NULL);
139     inline_copy_payload_to_new_oop(((char*)(oopDesc*)obj_h()) + offset, res);
140   }
141   assert(res != nullptr, "Must be set in one of two paths above");
142   return res;
143 }
144 
145 void InlineKlass::write_flat_field(oop obj, int offset, oop value, TRAPS) {
146   if (value == nullptr) {
147     THROW(vmSymbols::java_lang_NullPointerException());
148   }
149   if (!is_empty_inline_type()) {
150     inline_copy_oop_to_payload(value, ((char*)(oopDesc*)obj) + offset);
151   }
152 }
153 
154 // Arrays of...
155 
156 bool InlineKlass::flat_array() {
157   if (!UseFlatArray) {
158     return false;
159   }
160   // Too big
161   int elem_bytes = get_exact_size_in_bytes();
162   if ((FlatArrayElementMaxSize >= 0) && (elem_bytes > FlatArrayElementMaxSize)) {
163     return false;
164   }
165   // Too many embedded oops
166   if ((FlatArrayElementMaxOops >= 0) && (nonstatic_oop_count() > FlatArrayElementMaxOops)) {
167     return false;
168   }
169   // Declared atomic but not naturally atomic.
170   if (must_be_atomic() && !is_naturally_atomic()) {
171     return false;
172   }
173   // VM enforcing InlineArrayAtomicAccess only...
174   if (InlineArrayAtomicAccess && (!is_naturally_atomic())) {
175     return false;
176   }
177   return true;
178 }
179 
180 Klass* InlineKlass::value_array_klass(int n, TRAPS) {
181   if (Atomic::load_acquire(adr_value_array_klasses()) == nullptr) {
182     ResourceMark rm(THREAD);
183     JavaThread *jt = JavaThread::cast(THREAD);
184     {
185       // Atomic creation of array_klasses
186       MutexLocker ma(THREAD, MultiArray_lock);
187 
188       // Check if update has already taken place
189       if (value_array_klasses() == nullptr) {
190         ArrayKlass* k;
191         if (flat_array()) {
192           k = FlatArrayKlass::allocate_klass(this, CHECK_NULL);
193         } else {
194           k = ObjArrayKlass::allocate_objArray_klass(class_loader_data(), 1, this, true, CHECK_NULL);
195 
196         }
197         // use 'release' to pair with lock-free load
198         Atomic::release_store(adr_value_array_klasses(), k);
199       }
200     }
201   }
202   ArrayKlass* ak = value_array_klasses();
203   return ak->array_klass(n, THREAD);
204 }
205 
206 Klass* InlineKlass::value_array_klass_or_null(int n) {
207   // Need load-acquire for lock-free read
208   ArrayKlass* ak = Atomic::load_acquire(adr_value_array_klasses());
209   if (ak == nullptr) {
210     return nullptr;
211   } else {
212     return ak->array_klass_or_null(n);
213   }
214 }
215 
216 Klass* InlineKlass::value_array_klass(TRAPS) {
217   return value_array_klass(1, THREAD);
218 }
219 
220 Klass* InlineKlass::value_array_klass_or_null() {
221   return value_array_klass_or_null(1);
222 }
223 
224 // Inline type arguments are not passed by reference, instead each
225 // field of the inline type is passed as an argument. This helper
226 // function collects the flat field (recursively)
227 // in a list. Included with the field's type is
228 // the offset of each field in the inline type: i2c and c2i adapters
229 // need that to load or store fields. Finally, the list of fields is
230 // sorted in order of increasing offsets: the adapters and the
231 // compiled code need to agree upon the order of fields.
232 //
233 // The list of basic types that is returned starts with a T_METADATA
234 // and ends with an extra T_VOID. T_METADATA/T_VOID pairs are used as
235 // delimiters. Every entry between the two is a field of the inline
236 // type. If there's an embedded inline type in the list, it also starts
237 // with a T_METADATA and ends with a T_VOID. This is so we can
238 // generate a unique fingerprint for the method's adapters and we can
239 // generate the list of basic types from the interpreter point of view
240 // (inline types passed as reference: iterate on the list until a
241 // T_METADATA, drop everything until and including the closing
242 // T_VOID) or the compiler point of view (each field of the inline
243 // types is an argument: drop all T_METADATA/T_VOID from the list).
244 int InlineKlass::collect_fields(GrowableArray<SigEntry>* sig, int base_off) {
245   int count = 0;
246   SigEntry::add_entry(sig, T_METADATA, name(), base_off);
247   for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
248     if (fs.access_flags().is_static()) continue;
249     int offset = base_off + fs.offset() - (base_off > 0 ? first_field_offset() : 0);
250     // TODO 8284443 Use different heuristic to decide what should be scalarized in the calling convention
251     if (fs.is_flat()) {
252       // Resolve klass of flat field and recursively collect fields
253       Klass* vk = get_inline_type_field_klass(fs.index());
254       count += InlineKlass::cast(vk)->collect_fields(sig, offset);
255     } else {
256       BasicType bt = Signature::basic_type(fs.signature());
257       SigEntry::add_entry(sig, bt, fs.signature(), offset);
258       count += type2size[bt];
259     }
260   }
261   int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0);
262   SigEntry::add_entry(sig, T_VOID, name(), offset);
263   if (base_off == 0) {
264     sig->sort(SigEntry::compare);
265   }
266   assert(sig->at(0)._bt == T_METADATA && sig->at(sig->length()-1)._bt == T_VOID, "broken structure");
267   return count;
268 }
269 
270 void InlineKlass::initialize_calling_convention(TRAPS) {
271   // Because the pack and unpack handler addresses need to be loadable from generated code,
272   // they are stored at a fixed offset in the klass metadata. Since inline type klasses do
273   // not have a vtable, the vtable offset is used to store these addresses.
274   if (InlineTypeReturnedAsFields || InlineTypePassFieldsAsArgs) {
275     ResourceMark rm;
276     GrowableArray<SigEntry> sig_vk;
277     int nb_fields = collect_fields(&sig_vk);
278     Array<SigEntry>* extended_sig = MetadataFactory::new_array<SigEntry>(class_loader_data(), sig_vk.length(), CHECK);
279     *((Array<SigEntry>**)adr_extended_sig()) = extended_sig;
280     for (int i = 0; i < sig_vk.length(); i++) {
281       extended_sig->at_put(i, sig_vk.at(i));
282     }
283     if (can_be_returned_as_fields(/* init= */ true)) {
284       nb_fields++;
285       BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, nb_fields);
286       sig_bt[0] = T_METADATA;
287       SigEntry::fill_sig_bt(&sig_vk, sig_bt+1);
288       VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields);
289       int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields);
290 
291       if (total > 0) {
292         Array<VMRegPair>* return_regs = MetadataFactory::new_array<VMRegPair>(class_loader_data(), nb_fields, CHECK);
293         *((Array<VMRegPair>**)adr_return_regs()) = return_regs;
294         for (int i = 0; i < nb_fields; i++) {
295           return_regs->at_put(i, regs[i]);
296         }
297 
298         BufferedInlineTypeBlob* buffered_blob = SharedRuntime::generate_buffered_inline_type_adapter(this);
299         *((address*)adr_pack_handler()) = buffered_blob->pack_fields();
300         *((address*)adr_pack_handler_jobject()) = buffered_blob->pack_fields_jobject();
301         *((address*)adr_unpack_handler()) = buffered_blob->unpack_fields();
302         assert(CodeCache::find_blob(pack_handler()) == buffered_blob, "lost track of blob");
303         assert(can_be_returned_as_fields(), "sanity");
304       }
305     }
306     if (!can_be_returned_as_fields() && !can_be_passed_as_fields()) {
307       MetadataFactory::free_array<SigEntry>(class_loader_data(), extended_sig);
308       assert(return_regs() == nullptr, "sanity");
309     }
310   }
311 }
312 
313 void InlineKlass::deallocate_contents(ClassLoaderData* loader_data) {
314   if (extended_sig() != nullptr) {
315     MetadataFactory::free_array<SigEntry>(loader_data, extended_sig());
316   }
317   if (return_regs() != nullptr) {
318     MetadataFactory::free_array<VMRegPair>(loader_data, return_regs());
319   }
320   cleanup_blobs();
321   InstanceKlass::deallocate_contents(loader_data);
322 }
323 
324 void InlineKlass::cleanup(InlineKlass* ik) {
325   ik->cleanup_blobs();
326 }
327 
328 void InlineKlass::cleanup_blobs() {
329   if (pack_handler() != nullptr) {
330     CodeBlob* buffered_blob = CodeCache::find_blob(pack_handler());
331     assert(buffered_blob->is_buffered_inline_type_blob(), "bad blob type");
332     BufferBlob::free((BufferBlob*)buffered_blob);
333     *((address*)adr_pack_handler()) = nullptr;
334     *((address*)adr_pack_handler_jobject()) = nullptr;
335     *((address*)adr_unpack_handler()) = nullptr;
336   }
337 }
338 
339 // Can this inline type be passed as multiple values?
340 bool InlineKlass::can_be_passed_as_fields() const {
341   return InlineTypePassFieldsAsArgs;
342 }
343 
344 // Can this inline type be returned as multiple values?
345 bool InlineKlass::can_be_returned_as_fields(bool init) const {
346   return InlineTypeReturnedAsFields && (init || return_regs() != nullptr);
347 }
348 
349 // Create handles for all oop fields returned in registers that are going to be live across a safepoint
350 void InlineKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
351   Thread* thread = Thread::current();
352   const Array<SigEntry>* sig_vk = extended_sig();
353   const Array<VMRegPair>* regs = return_regs();
354   int j = 1;
355 
356   for (int i = 0; i < sig_vk->length(); i++) {
357     BasicType bt = sig_vk->at(i)._bt;
358     if (bt == T_OBJECT || bt == T_ARRAY) {
359       VMRegPair pair = regs->at(j);
360       address loc = reg_map.location(pair.first(), nullptr);
361       oop v = *(oop*)loc;
362       assert(v == nullptr || oopDesc::is_oop(v), "not an oop?");
363       assert(Universe::heap()->is_in_or_null(v), "must be heap pointer");
364       handles.push(Handle(thread, v));
365     }
366     if (bt == T_METADATA) {
367       continue;
368     }
369     if (bt == T_VOID &&
370         sig_vk->at(i-1)._bt != T_LONG &&
371         sig_vk->at(i-1)._bt != T_DOUBLE) {
372       continue;
373     }
374     j++;
375   }
376   assert(j == regs->length(), "missed a field?");
377 }
378 
379 // Update oop fields in registers from handles after a safepoint
380 void InlineKlass::restore_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
381   assert(InlineTypeReturnedAsFields, "Inline types should never be returned as fields");
382   const Array<SigEntry>* sig_vk = extended_sig();
383   const Array<VMRegPair>* regs = return_regs();
384   assert(regs != nullptr, "inconsistent");
385 
386   int j = 1;
387   for (int i = 0, k = 0; i < sig_vk->length(); i++) {
388     BasicType bt = sig_vk->at(i)._bt;
389     if (bt == T_OBJECT || bt == T_ARRAY) {
390       VMRegPair pair = regs->at(j);
391       address loc = reg_map.location(pair.first(), nullptr);
392       *(oop*)loc = handles.at(k++)();
393     }
394     if (bt == T_METADATA) {
395       continue;
396     }
397     if (bt == T_VOID &&
398         sig_vk->at(i-1)._bt != T_LONG &&
399         sig_vk->at(i-1)._bt != T_DOUBLE) {
400       continue;
401     }
402     j++;
403   }
404   assert(j == regs->length(), "missed a field?");
405 }
406 
407 // Fields are in registers. Create an instance of the inline type and
408 // initialize it with the values of the fields.
409 oop InlineKlass::realloc_result(const RegisterMap& reg_map, const GrowableArray<Handle>& handles, TRAPS) {
410   oop new_vt = allocate_instance(CHECK_NULL);
411   const Array<SigEntry>* sig_vk = extended_sig();
412   const Array<VMRegPair>* regs = return_regs();
413 
414   int j = 1;
415   int k = 0;
416   for (int i = 0; i < sig_vk->length(); i++) {
417     BasicType bt = sig_vk->at(i)._bt;
418     if (bt == T_METADATA) {
419       continue;
420     }
421     if (bt == T_VOID) {
422       if (sig_vk->at(i-1)._bt == T_LONG ||
423           sig_vk->at(i-1)._bt == T_DOUBLE) {
424         j++;
425       }
426       continue;
427     }
428     int off = sig_vk->at(i)._offset;
429     assert(off > 0, "offset in object should be positive");
430     VMRegPair pair = regs->at(j);
431     address loc = reg_map.location(pair.first(), nullptr);
432     switch(bt) {
433     case T_BOOLEAN: {
434       new_vt->bool_field_put(off, *(jboolean*)loc);
435       break;
436     }
437     case T_CHAR: {
438       new_vt->char_field_put(off, *(jchar*)loc);
439       break;
440     }
441     case T_BYTE: {
442       new_vt->byte_field_put(off, *(jbyte*)loc);
443       break;
444     }
445     case T_SHORT: {
446       new_vt->short_field_put(off, *(jshort*)loc);
447       break;
448     }
449     case T_INT: {
450       new_vt->int_field_put(off, *(jint*)loc);
451       break;
452     }
453     case T_LONG: {
454 #ifdef _LP64
455       new_vt->double_field_put(off,  *(jdouble*)loc);
456 #else
457       Unimplemented();
458 #endif
459       break;
460     }
461     case T_OBJECT:
462     case T_ARRAY: {
463       Handle handle = handles.at(k++);
464       new_vt->obj_field_put(off, handle());
465       break;
466     }
467     case T_FLOAT: {
468       new_vt->float_field_put(off,  *(jfloat*)loc);
469       break;
470     }
471     case T_DOUBLE: {
472       new_vt->double_field_put(off, *(jdouble*)loc);
473       break;
474     }
475     default:
476       ShouldNotReachHere();
477     }
478     *(intptr_t*)loc = 0xDEAD;
479     j++;
480   }
481   assert(j == regs->length(), "missed a field?");
482   assert(k == handles.length(), "missed an oop?");
483   return new_vt;
484 }
485 
486 // Check the return register for an InlineKlass oop
487 InlineKlass* InlineKlass::returned_inline_klass(const RegisterMap& map) {
488   BasicType bt = T_METADATA;
489   VMRegPair pair;
490   int nb = SharedRuntime::java_return_convention(&bt, &pair, 1);
491   assert(nb == 1, "broken");
492 
493   address loc = map.location(pair.first(), nullptr);
494   intptr_t ptr = *(intptr_t*)loc;
495   if (is_set_nth_bit(ptr, 0)) {
496     // Return value is tagged, must be an InlineKlass pointer
497     clear_nth_bit(ptr, 0);
498     assert(Metaspace::contains((void*)ptr), "should be klass");
499     InlineKlass* vk = (InlineKlass*)ptr;
500     assert(vk->can_be_returned_as_fields(), "must be able to return as fields");
501     return vk;
502   }
503   // Return value is not tagged, must be a valid oop
504   assert(oopDesc::is_oop_or_null(cast_to_oop(ptr), true),
505          "Bad oop return: " PTR_FORMAT, ptr);
506   return nullptr;
507 }
508 
509 // CDS support
510 
511 void InlineKlass::metaspace_pointers_do(MetaspaceClosure* it) {
512   InstanceKlass::metaspace_pointers_do(it);
513 
514   InlineKlass* this_ptr = this;
515   it->push((Klass**)adr_value_array_klasses());
516 }
517 
518 void InlineKlass::remove_unshareable_info() {
519   InstanceKlass::remove_unshareable_info();
520 
521   *((Array<SigEntry>**)adr_extended_sig()) = nullptr;
522   *((Array<VMRegPair>**)adr_return_regs()) = nullptr;
523   *((address*)adr_pack_handler()) = nullptr;
524   *((address*)adr_pack_handler_jobject()) = nullptr;
525   *((address*)adr_unpack_handler()) = nullptr;
526   assert(pack_handler() == nullptr, "pack handler not null");
527   if (value_array_klasses() != nullptr) {
528     value_array_klasses()->remove_unshareable_info();
529   }
530 }
531 
532 void InlineKlass::remove_java_mirror() {
533   InstanceKlass::remove_java_mirror();
534   if (value_array_klasses() != nullptr) {
535     value_array_klasses()->remove_java_mirror();
536   }
537 }
538 
539 void InlineKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, PackageEntry* pkg_entry, TRAPS) {
540   // We are no longer bookkeeping pointer to fixed block during serialization, hence reinitializing
541   // fixed block address since its size was already accounted by InstanceKlass::size() and it will
542   // anyways be part of shared archive.
543   _adr_inlineklass_fixed_block = inlineklass_static_block();
544   InstanceKlass::restore_unshareable_info(loader_data, protection_domain, pkg_entry, CHECK);
545   if (value_array_klasses() != nullptr) {
546     value_array_klasses()->restore_unshareable_info(ClassLoaderData::the_null_class_loader_data(), Handle(), CHECK);
547   }
548 }
549 
550 // oop verify
551 
552 void InlineKlass::verify_on(outputStream* st) {
553   InstanceKlass::verify_on(st);
554   guarantee(prototype_header().is_inline_type(), "Prototype header is not inline type");
555 }
556 
557 void InlineKlass::oop_verify_on(oop obj, outputStream* st) {
558   InstanceKlass::oop_verify_on(obj, st);
559   guarantee(obj->mark().is_inline_type(), "Header is not inline type");
560 }