1 /* 2 * Copyright (c) 2025, 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 #ifndef SHARE_OOPS_LAYOUTKIND_HPP 26 #define SHARE_OOPS_LAYOUTKIND_HPP 27 28 #include "utilities/globalDefinitions.hpp" 29 30 // LayoutKind is an enum used to indicate which layout has been used for a given value field. 31 // Each layout has its own properties and its own access protocol that is detailed below. 32 // 33 // REFERENCE : this layout uses a pointer to a heap allocated instance (no flattening). 34 // When used, field_flags().is_flat() is false . The field can be nullable or 35 // null-restricted, in the later case, field_flags().is_null_free_inline_type() is true. 36 // In case of a null-restricted field, putfield and putstatic must perform a null-check 37 // before writing a new value. Still for null-restricted fields, if getfield reads a null pointer 38 // from the receiver, it means that the field was not initialized yet, and getfield must substitute 39 // the null reference with the default value of the field's class. 40 // NON_ATOMIC_FLAT : this layout is the simplest form of flattening. Any field embedded inside the flat field 41 // can be accessed independently. The field is null-restricted, meaning putfield must perform a 42 // null-check before performing a field update. 43 // ATOMIC_FLAT : this flat layout is designed for atomic updates, with size and alignment that make use of 44 // atomic instructions possible. All accesses, reads and writes, must be performed atomically. 45 // The field is null-restricted, meaning putfield must perform a null-check before performing a 46 // field update. 47 // NULLABLE_ATOMIC_FLAT : this is the flat layout designed for JEP 401. It is designed for atomic updates, 48 // with size and alignment that make use of atomic instructions possible. All accesses, reads and 49 // writes, must be performed atomically. The layout includes a null marker which indicates if the 50 // field's value must be considered as null or not. The null marker is a byte, with the value zero 51 // meaning the field's value is null, and a non-zero value meaning the field's value is not null. 52 // A getfield must check the value of the null marker before returning a value. If the null marker 53 // is zero, getfield must return the null reference, otherwise it returns the field's value read 54 // from the receiver. When a putfield writes a non-null value to such field, the update, including 55 // the field's value and the null marker, must be performed in a single atomic operation. If the 56 // source of the value is a heap allocated instance of the field's class, it is allowed to set the 57 // null marker to non-zero in the heap allocated instance before copying the value to the receiver 58 // (the BUFFERED layout used in heap allocated values guarantees that the space for the null marker 59 // is included, but has no meaning for the heap allocated instance which is always non-null, and that 60 // the whole payload is correctly aligned for atomic operations). When a putfield writes null to such 61 // field, the null marker must be set to zero. However, if the field contains oops, those oops must be 62 // cleared too in order to prevent memory leaks. In order to simplify such operation, value classes 63 // supporting a NULLABLE_ATOMIC_FLAT layout have a pre-allocated reset value instance, filled with 64 // zeros, which can be used to simply overwrite the whole flat field and reset everything (oops and 65 // null marker). The reset value instance is needed because the VM needs an instance guaranteed to 66 // always be filled with zeros, and the default value could have its null marker set to non-zero if 67 // it is used as a source to update a NULLABLE_ATOMIC_FLAT field. 68 // BUFFERED: this layout is only used in heap buffered instances of a value class. It is computed to be compatible 69 // to be compatible in size and alignment with all other flat layouts supported by the value class. 70 // 71 // 72 // IMPORTANT: The REFERENCE layout must always be associated with the numerical value zero, because the implementation 73 // of the lava.lang.invoke.MemberName class relies on this property. 74 75 enum class LayoutKind : uint32_t { 76 REFERENCE = 0, // indirection to a heap allocated instance 77 BUFFERED = 1, // layout used in heap allocated standalone instances 78 NON_ATOMIC_FLAT = 2, // flat, no guarantee of atomic updates, no null marker 79 ATOMIC_FLAT = 3, // flat, size compatible with atomic updates, alignment requirement is equal to the size 80 NULLABLE_ATOMIC_FLAT = 4, // flat, include a null marker, plus same properties as ATOMIC layout 81 UNKNOWN = 5 // used for uninitialized fields of type LayoutKind 82 }; 83 84 #endif // SHARE_OOPS_LAYOUTKIND_HPP