1 /*
2  * Copyright (C) 2018 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_RUNTIME_CLASS_ROOT_H_
18 #define ART_RUNTIME_CLASS_ROOT_H_
19 
20 #include "class_linker-inl.h"
21 #include "gc_root-inl.h"
22 #include "mirror/class.h"
23 #include "mirror/object_array-inl.h"
24 #include "obj_ptr-inl.h"
25 #include "runtime.h"
26 
27 namespace art {
28 
29 namespace mirror {
30 class ArrayElementVarHandle;
31 class ByteArrayViewVarHandle;
32 class ByteBufferViewVarHandle;
33 class CallSite;
34 class ClassExt;
35 class ClassLoader;
36 class Constructor;
37 class DexCache;
38 class EmulatedStackFrame;
39 class Field;
40 class FieldVarHandle;
41 class Method;
42 class MethodHandleImpl;
43 class MethodHandlesLookup;
44 class MethodType;
45 class Object;
46 class Proxy;
47 template<typename T> class PrimitiveArray;
48 class Reference;
49 class StackTraceElement;
50 class String;
51 class Throwable;
52 class VarHandle;
53 }  // namespace mirror
54 
55 #define CLASS_ROOT_LIST(M)                                                                                                                          \
56   M(kJavaLangClass,                         "Ljava/lang/Class;",                          mirror::Class)                                            \
57   M(kJavaLangObject,                        "Ljava/lang/Object;",                         mirror::Object)                                           \
58   M(kClassArrayClass,                       "[Ljava/lang/Class;",                         mirror::ObjectArray<mirror::Class>)                       \
59   M(kObjectArrayClass,                      "[Ljava/lang/Object;",                        mirror::ObjectArray<mirror::Object>)                      \
60   M(kJavaLangString,                        "Ljava/lang/String;",                         mirror::String)                                           \
61   M(kJavaLangDexCache,                      "Ljava/lang/DexCache;",                       mirror::DexCache)                                         \
62   M(kJavaLangRefReference,                  "Ljava/lang/ref/Reference;",                  mirror::Reference)                                        \
63   M(kJavaLangReflectConstructor,            "Ljava/lang/reflect/Constructor;",            mirror::Constructor)                                      \
64   M(kJavaLangReflectField,                  "Ljava/lang/reflect/Field;",                  mirror::Field)                                            \
65   M(kJavaLangReflectMethod,                 "Ljava/lang/reflect/Method;",                 mirror::Method)                                           \
66   M(kJavaLangReflectProxy,                  "Ljava/lang/reflect/Proxy;",                  mirror::Proxy)                                            \
67   M(kJavaLangStringArrayClass,              "[Ljava/lang/String;",                        mirror::ObjectArray<mirror::String>)                      \
68   M(kJavaLangReflectConstructorArrayClass,  "[Ljava/lang/reflect/Constructor;",           mirror::ObjectArray<mirror::Constructor>)                 \
69   M(kJavaLangReflectFieldArrayClass,        "[Ljava/lang/reflect/Field;",                 mirror::ObjectArray<mirror::Field>)                       \
70   M(kJavaLangReflectMethodArrayClass,       "[Ljava/lang/reflect/Method;",                mirror::ObjectArray<mirror::Method>)                      \
71   M(kJavaLangInvokeCallSite,                "Ljava/lang/invoke/CallSite;",                mirror::CallSite)                                         \
72   M(kJavaLangInvokeMethodHandle,            "Ljava/lang/invoke/MethodHandle;",            mirror::MethodHandle)                                     \
73   M(kJavaLangInvokeMethodHandleImpl,        "Ljava/lang/invoke/MethodHandleImpl;",        mirror::MethodHandleImpl)                                 \
74   M(kJavaLangInvokeMethodHandlesLookup,     "Ljava/lang/invoke/MethodHandles$Lookup;",    mirror::MethodHandlesLookup)                              \
75   M(kJavaLangInvokeMethodType,              "Ljava/lang/invoke/MethodType;",              mirror::MethodType)                                       \
76   M(kJavaLangInvokeVarHandle,               "Ljava/lang/invoke/VarHandle;",               mirror::VarHandle)                                        \
77   M(kJavaLangInvokeFieldVarHandle,          "Ljava/lang/invoke/FieldVarHandle;",          mirror::FieldVarHandle)                                   \
78   M(kJavaLangInvokeArrayElementVarHandle,   "Ljava/lang/invoke/ArrayElementVarHandle;",   mirror::ArrayElementVarHandle)                            \
79   M(kJavaLangInvokeByteArrayViewVarHandle,  "Ljava/lang/invoke/ByteArrayViewVarHandle;",  mirror::ByteArrayViewVarHandle)                           \
80   M(kJavaLangInvokeByteBufferViewVarHandle, "Ljava/lang/invoke/ByteBufferViewVarHandle;", mirror::ByteBufferViewVarHandle)                          \
81   M(kJavaLangClassLoader,                   "Ljava/lang/ClassLoader;",                    mirror::ClassLoader)                                      \
82   M(kJavaLangThrowable,                     "Ljava/lang/Throwable;",                      mirror::Throwable)                                        \
83   M(kJavaLangClassNotFoundException,        "Ljava/lang/ClassNotFoundException;",         detail::NoMirrorType<detail::ClassNotFoundExceptionTag>)  \
84   M(kJavaLangStackTraceElement,             "Ljava/lang/StackTraceElement;",              mirror::StackTraceElement)                                \
85   M(kDalvikSystemEmulatedStackFrame,        "Ldalvik/system/EmulatedStackFrame;",         mirror::EmulatedStackFrame)                               \
86   M(kPrimitiveBoolean,                      "Z",                                          detail::NoMirrorType<uint8_t>)                            \
87   M(kPrimitiveByte,                         "B",                                          detail::NoMirrorType<int8_t>)                             \
88   M(kPrimitiveChar,                         "C",                                          detail::NoMirrorType<uint16_t>)                           \
89   M(kPrimitiveDouble,                       "D",                                          detail::NoMirrorType<double>)                             \
90   M(kPrimitiveFloat,                        "F",                                          detail::NoMirrorType<float>)                              \
91   M(kPrimitiveInt,                          "I",                                          detail::NoMirrorType<int32_t>)                            \
92   M(kPrimitiveLong,                         "J",                                          detail::NoMirrorType<int64_t>)                            \
93   M(kPrimitiveShort,                        "S",                                          detail::NoMirrorType<int16_t>)                            \
94   M(kPrimitiveVoid,                         "V",                                          detail::NoMirrorType<void>)                               \
95   M(kBooleanArrayClass,                     "[Z",                                         mirror::PrimitiveArray<uint8_t>)                          \
96   M(kByteArrayClass,                        "[B",                                         mirror::PrimitiveArray<int8_t>)                           \
97   M(kCharArrayClass,                        "[C",                                         mirror::PrimitiveArray<uint16_t>)                         \
98   M(kDoubleArrayClass,                      "[D",                                         mirror::PrimitiveArray<double>)                           \
99   M(kFloatArrayClass,                       "[F",                                         mirror::PrimitiveArray<float>)                            \
100   M(kIntArrayClass,                         "[I",                                         mirror::PrimitiveArray<int32_t>)                          \
101   M(kLongArrayClass,                        "[J",                                         mirror::PrimitiveArray<int64_t>)                          \
102   M(kShortArrayClass,                       "[S",                                         mirror::PrimitiveArray<int16_t>)                          \
103   M(kJavaLangStackTraceElementArrayClass,   "[Ljava/lang/StackTraceElement;",             mirror::ObjectArray<mirror::StackTraceElement>)           \
104   M(kJavaLangClassLoaderArrayClass,         "[Ljava/lang/ClassLoader;",                   mirror::ObjectArray<mirror::ClassLoader>)                 \
105   M(kDalvikSystemClassExt,                  "Ldalvik/system/ClassExt;",                   mirror::ClassExt)
106 
107 // Well known mirror::Class roots accessed via ClassLinker::GetClassRoots().
108 enum class ClassRoot : uint32_t {
109 #define CLASS_ROOT_ENUMERATOR(name, descriptor, mirror_type) name,
110   CLASS_ROOT_LIST(CLASS_ROOT_ENUMERATOR)
111 #undef CLASS_ROOT_ENUMERATOR
112   kMax,
113 };
114 
115 const char* GetClassRootDescriptor(ClassRoot class_root);
116 
117 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
GetClassRoot(ClassRoot class_root,ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots)118 inline ObjPtr<mirror::Class> GetClassRoot(
119     ClassRoot class_root,
120     ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots) REQUIRES_SHARED(Locks::mutator_lock_) {
121   DCHECK(class_roots != nullptr);
122   if (kReadBarrierOption == kWithReadBarrier) {
123     // With read barrier all references must point to the to-space.
124     // Without read barrier, this check could fail.
125     DCHECK_EQ(class_roots, Runtime::Current()->GetClassLinker()->GetClassRoots());
126   }
127   DCHECK_LT(static_cast<uint32_t>(class_root), static_cast<uint32_t>(ClassRoot::kMax));
128   int32_t index = static_cast<int32_t>(class_root);
129   ObjPtr<mirror::Class> klass =
130       class_roots->GetWithoutChecks<kDefaultVerifyFlags, kReadBarrierOption>(index);
131   DCHECK(klass != nullptr);
132   return klass;
133 }
134 
135 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
GetClassRoot(ClassRoot class_root,ClassLinker * linker)136 inline ObjPtr<mirror::Class> GetClassRoot(ClassRoot class_root, ClassLinker* linker)
137     REQUIRES_SHARED(Locks::mutator_lock_) {
138   return GetClassRoot<kReadBarrierOption>(class_root, linker->GetClassRoots<kReadBarrierOption>());
139 }
140 
141 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
GetClassRoot(ClassRoot class_root)142 inline ObjPtr<mirror::Class> GetClassRoot(ClassRoot class_root)
143     REQUIRES_SHARED(Locks::mutator_lock_) {
144   return GetClassRoot<kReadBarrierOption>(class_root, Runtime::Current()->GetClassLinker());
145 }
146 
147 namespace detail {
148 
149 class ClassNotFoundExceptionTag;
150 template <class Tag> struct NoMirrorType;
151 
152 template <class MirrorType>
153 struct ClassRootSelector;  // No definition for unspecialized ClassRoot selector.
154 
155 #define SPECIALIZE_CLASS_ROOT_SELECTOR(name, descriptor, mirror_type) \
156   template <>                                                         \
157   struct ClassRootSelector<mirror_type> {                             \
158     static constexpr ClassRoot value = ClassRoot::name;               \
159   };
160 
161 CLASS_ROOT_LIST(SPECIALIZE_CLASS_ROOT_SELECTOR)
162 
163 #undef SPECIALIZE_CLASS_ROOT_SELECTOR
164 
165 }  // namespace detail
166 
167 template <class MirrorType, ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
GetClassRoot(ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots)168 inline ObjPtr<mirror::Class> GetClassRoot(ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots)
169     REQUIRES_SHARED(Locks::mutator_lock_) {
170   return GetClassRoot<kReadBarrierOption>(detail::ClassRootSelector<MirrorType>::value,
171                                           class_roots);
172 }
173 
174 template <class MirrorType, ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
GetClassRoot(ClassLinker * linker)175 inline ObjPtr<mirror::Class> GetClassRoot(ClassLinker* linker)
176     REQUIRES_SHARED(Locks::mutator_lock_) {
177   return GetClassRoot<kReadBarrierOption>(detail::ClassRootSelector<MirrorType>::value, linker);
178 }
179 
180 template <class MirrorType, ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
GetClassRoot()181 inline ObjPtr<mirror::Class> GetClassRoot() REQUIRES_SHARED(Locks::mutator_lock_) {
182   return GetClassRoot<kReadBarrierOption>(detail::ClassRootSelector<MirrorType>::value);
183 }
184 
185 }  // namespace art
186 
187 #endif  // ART_RUNTIME_CLASS_ROOT_H_
188