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