xref: /aosp_15_r20/art/compiler/optimizing/reference_type_info.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_COMPILER_OPTIMIZING_REFERENCE_TYPE_INFO_H_
18 #define ART_COMPILER_OPTIMIZING_REFERENCE_TYPE_INFO_H_
19 
20 #include <iosfwd>
21 
22 #include "base/globals.h"
23 #include "base/logging.h"
24 #include "base/macros.h"
25 #include "base/value_object.h"
26 #include "handle.h"
27 #include "mirror/class-inl.h"
28 
29 namespace art HIDDEN {
30 
31 class ReferenceTypeInfo : ValueObject {
32  public:
33   using TypeHandle = Handle<mirror::Class>;
34 
Create(TypeHandle type_handle,bool is_exact)35   static ReferenceTypeInfo Create(TypeHandle type_handle, bool is_exact) {
36     if (kIsDebugBuild) {
37       DCheckValidTypeInfo(type_handle, is_exact);
38     }
39     return ReferenceTypeInfo(type_handle, is_exact);
40   }
41 
Create(TypeHandle type_handle)42   static ReferenceTypeInfo Create(TypeHandle type_handle) REQUIRES_SHARED(Locks::mutator_lock_) {
43     return Create(type_handle, type_handle->CannotBeAssignedFromOtherTypes());
44   }
45 
CreateUnchecked(TypeHandle type_handle,bool is_exact)46   static ReferenceTypeInfo CreateUnchecked(TypeHandle type_handle, bool is_exact) {
47     return ReferenceTypeInfo(type_handle, is_exact);
48   }
49 
CreateInvalid()50   static ReferenceTypeInfo CreateInvalid() { return ReferenceTypeInfo(); }
51 
IsValidHandle(TypeHandle handle)52   static bool IsValidHandle(TypeHandle handle) {
53     return handle.GetReference() != nullptr;
54   }
55 
IsValid()56   bool IsValid() const {
57     return IsValidHandle(type_handle_);
58   }
59 
IsExact()60   bool IsExact() const { return is_exact_; }
61 
IsObjectClass()62   bool IsObjectClass() const REQUIRES_SHARED(Locks::mutator_lock_) {
63     DCHECK(IsValid());
64     return GetTypeHandle()->IsObjectClass();
65   }
66 
IsStringClass()67   bool IsStringClass() const REQUIRES_SHARED(Locks::mutator_lock_) {
68     DCHECK(IsValid());
69     return GetTypeHandle()->IsStringClass();
70   }
71 
IsObjectArray()72   bool IsObjectArray() const REQUIRES_SHARED(Locks::mutator_lock_) {
73     DCHECK(IsValid());
74     return IsArrayClass() && GetTypeHandle()->GetComponentType()->IsObjectClass();
75   }
76 
IsInterface()77   bool IsInterface() const REQUIRES_SHARED(Locks::mutator_lock_) {
78     DCHECK(IsValid());
79     return GetTypeHandle()->IsInterface();
80   }
81 
IsArrayClass()82   bool IsArrayClass() const REQUIRES_SHARED(Locks::mutator_lock_) {
83     DCHECK(IsValid());
84     return GetTypeHandle()->IsArrayClass();
85   }
86 
IsPrimitiveArrayClass()87   bool IsPrimitiveArrayClass() const REQUIRES_SHARED(Locks::mutator_lock_) {
88     DCHECK(IsValid());
89     return GetTypeHandle()->IsPrimitiveArray();
90   }
91 
IsNonPrimitiveArrayClass()92   bool IsNonPrimitiveArrayClass() const REQUIRES_SHARED(Locks::mutator_lock_) {
93     DCHECK(IsValid());
94     return IsArrayClass() && !GetTypeHandle()->IsPrimitiveArray();
95   }
96 
CanArrayHold(ReferenceTypeInfo rti)97   bool CanArrayHold(ReferenceTypeInfo rti)  const REQUIRES_SHARED(Locks::mutator_lock_) {
98     DCHECK(IsValid());
99     if (!IsExact()) return false;
100     if (!IsArrayClass()) return false;
101     return GetTypeHandle()->GetComponentType()->IsAssignableFrom(rti.GetTypeHandle().Get());
102   }
103 
CanArrayHoldValuesOf(ReferenceTypeInfo rti)104   bool CanArrayHoldValuesOf(ReferenceTypeInfo rti)  const REQUIRES_SHARED(Locks::mutator_lock_) {
105     DCHECK(IsValid());
106     if (!IsExact()) return false;
107     if (!IsArrayClass()) return false;
108     if (!rti.IsArrayClass()) return false;
109     return GetTypeHandle()->GetComponentType()->IsAssignableFrom(
110         rti.GetTypeHandle()->GetComponentType());
111   }
112 
GetTypeHandle()113   Handle<mirror::Class> GetTypeHandle() const { return type_handle_; }
114 
IsSupertypeOf(ReferenceTypeInfo rti)115   bool IsSupertypeOf(ReferenceTypeInfo rti) const REQUIRES_SHARED(Locks::mutator_lock_) {
116     DCHECK(IsValid());
117     DCHECK(rti.IsValid());
118     return GetTypeHandle()->IsAssignableFrom(rti.GetTypeHandle().Get());
119   }
120 
121   // Returns true if the type information provide the same amount of details.
122   // Note that it does not mean that the instructions have the same actual type
123   // (because the type can be the result of a merge).
IsEqual(ReferenceTypeInfo rti)124   bool IsEqual(ReferenceTypeInfo rti) const REQUIRES_SHARED(Locks::mutator_lock_) {
125     if (!IsValid() && !rti.IsValid()) {
126       // Invalid types are equal.
127       return true;
128     }
129     if (!IsValid() || !rti.IsValid()) {
130       // One is valid, the other not.
131       return false;
132     }
133     return IsExact() == rti.IsExact() && GetTypeHandle().Get() == rti.GetTypeHandle().Get();
134   }
135 
136  private:
ReferenceTypeInfo()137   ReferenceTypeInfo() : type_handle_(TypeHandle()), is_exact_(false) {}
ReferenceTypeInfo(TypeHandle type_handle,bool is_exact)138   ReferenceTypeInfo(TypeHandle type_handle, bool is_exact)
139       : type_handle_(type_handle), is_exact_(is_exact) { }
140 
141   static void DCheckValidTypeInfo(TypeHandle type_handle, bool is_exact);
142 
143   // The class of the object.
144   TypeHandle type_handle_;
145   // Whether or not the type is exact or a superclass of the actual type.
146   // Whether or not we have any information about this type.
147   bool is_exact_;
148 };
149 
150 std::ostream& operator<<(std::ostream& os, const ReferenceTypeInfo& rhs);
151 
152 }  // namespace art
153 
154 #endif  // ART_COMPILER_OPTIMIZING_REFERENCE_TYPE_INFO_H_
155