1 /*
 2  * Copyright (c) 2026, 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_ARRAYPROPERTIES_HPP
26 #define SHARE_OOPS_ARRAYPROPERTIES_HPP
27 
28 #include "utilities/globalDefinitions.hpp"
29 #include "utilities/ostream.hpp"
30 
31 class ArrayProperties {
32 public:
33   // This type is mirrored in the compiler so we need to be careful changing it
34   typedef uint32_t Type;
35 
36 private:
37   Type _flags;
38 
39   enum class Property : Type {
40     NullRestricted = 1 << 0,
41     NonAtomic      = 1 << 1,
42     Invalid        = 1 << 2, // This needs to be last for asserts
43   };
44 
45   ArrayProperties with_property(Property prop, bool enabled = true) const {
46     return enabled
47         ? ArrayProperties(_flags | static_cast<Type>(prop))
48         : ArrayProperties(_flags &~ static_cast<Type>(prop));
49   }
50 
51   bool check_flag(Property prop) const { return (_flags & static_cast<Type>(prop)) != 0; }
52 
53 public:
54   explicit ArrayProperties(Type flags = 0) : _flags(flags) {
55     assert((flags & ~((Type(Property::Invalid) << 1) - 1)) == 0, "invalid flags set");
56   }
57 
58   static ArrayProperties Default() { return ArrayProperties(); }
59   static ArrayProperties Invalid() { return ArrayProperties().with_property(Property::Invalid, true); }
60 
61   ArrayProperties with_null_restricted(bool b = true) const { return with_property(Property::NullRestricted, b); }
62   ArrayProperties with_non_atomic(bool b = true) const { return with_property(Property::NonAtomic, b); }
63 
64   bool is_null_restricted() const { return check_flag(Property::NullRestricted); }
65   bool is_non_atomic() const { return check_flag(Property::NonAtomic); }
66   bool is_invalid() const { return check_flag(Property::Invalid); }
67   bool is_valid() const { return !check_flag(Property::Invalid); }
68 
69   Type value() const { return _flags; }
70 
71   const char* as_string() {
72     // Caller must have set a ResourceMark
73     stringStream ss;
74     if (is_invalid()) {
75       return "INVALID";
76     } else {
77       ss.print("%s", is_null_restricted() ? "NULL_RESTRICTED " : "NULLABLE ");
78       ss.print("%s", is_non_atomic() ? "NON_ATOMIC " : "ATOMIC ");
79     }
80     return ss.as_string();
81   }
82 };
83 
84 inline bool operator==(ArrayProperties a, ArrayProperties b) {
85   return a.value() == b.value();
86 }
87 
88 inline bool operator!=(ArrayProperties a, ArrayProperties b) {
89   return !(a == b);
90 }
91 
92 #endif // SHARE_OOPS_ARRAYPROPERTIES_HPP