blob: 3ca4c3023caf79d69232d8ca68ab90df7e5c29f9 [file] [log] [blame]
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001/*
2 * Copyright (C) 2011 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_SRC_MIRROR_CLASS_INL_H_
18#define ART_SRC_MIRROR_CLASS_INL_H_
19
20#include "class.h"
21
22#include "abstract_method.h"
23#include "field.h"
24#include "iftable.h"
25#include "object_array.h"
26#include "runtime.h"
27#include "string.h"
28
29namespace art {
30namespace mirror {
31
32inline size_t Class::GetObjectSize() const {
33 CHECK(!IsVariableSize()) << " class=" << PrettyTypeOf(this);
34 DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
35 size_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, object_size_), false);
36 CHECK_GE(result, sizeof(Object)) << " class=" << PrettyTypeOf(this);
37 return result;
38}
39
40inline Class* Class::GetSuperClass() const {
41 // Can only get super class for loaded classes (hack for when runtime is
42 // initializing)
43 DCHECK(IsLoaded() || !Runtime::Current()->IsStarted()) << IsLoaded();
44 return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), false);
45}
46
47inline ObjectArray<AbstractMethod>* Class::GetDirectMethods() const {
48 DCHECK(IsLoaded() || IsErroneous());
49 return GetFieldObject<ObjectArray<AbstractMethod>*>(
50 OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false);
51}
52
53inline void Class::SetDirectMethods(ObjectArray<AbstractMethod>* new_direct_methods)
54 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
55 DCHECK(NULL == GetFieldObject<ObjectArray<AbstractMethod>*>(
56 OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false));
57 DCHECK_NE(0, new_direct_methods->GetLength());
58 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_),
59 new_direct_methods, false);
60}
61
62inline AbstractMethod* Class::GetDirectMethod(int32_t i) const
63 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
64 return GetDirectMethods()->Get(i);
65}
66
67inline void Class::SetDirectMethod(uint32_t i, AbstractMethod* f) // TODO: uint16_t
68 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
69 ObjectArray<AbstractMethod>* direct_methods =
70 GetFieldObject<ObjectArray<AbstractMethod>*>(
71 OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false);
72 direct_methods->Set(i, f);
73}
74
75// Returns the number of static, private, and constructor methods.
76inline size_t Class::NumDirectMethods() const {
77 return (GetDirectMethods() != NULL) ? GetDirectMethods()->GetLength() : 0;
78}
79
80inline ObjectArray<AbstractMethod>* Class::GetVirtualMethods() const {
81 DCHECK(IsLoaded() || IsErroneous());
82 return GetFieldObject<ObjectArray<AbstractMethod>*>(
83 OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), false);
84}
85
86inline void Class::SetVirtualMethods(ObjectArray<AbstractMethod>* new_virtual_methods) {
87 // TODO: we reassign virtual methods to grow the table for miranda
88 // methods.. they should really just be assigned once
89 DCHECK_NE(0, new_virtual_methods->GetLength());
90 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_),
91 new_virtual_methods, false);
92}
93
94inline size_t Class::NumVirtualMethods() const {
95 return (GetVirtualMethods() != NULL) ? GetVirtualMethods()->GetLength() : 0;
96}
97
98inline AbstractMethod* Class::GetVirtualMethod(uint32_t i) const
99 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
100 DCHECK(IsResolved() || IsErroneous());
101 return GetVirtualMethods()->Get(i);
102}
103
104inline AbstractMethod* Class::GetVirtualMethodDuringLinking(uint32_t i) const
105 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
106 DCHECK(IsLoaded() || IsErroneous());
107 return GetVirtualMethods()->Get(i);
108}
109
110inline void Class::SetVirtualMethod(uint32_t i, AbstractMethod* f) // TODO: uint16_t
111 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
112 ObjectArray<AbstractMethod>* virtual_methods =
113 GetFieldObject<ObjectArray<AbstractMethod>*>(
114 OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), false);
115 virtual_methods->Set(i, f);
116}
117
118inline ObjectArray<AbstractMethod>* Class::GetVTable() const {
119 DCHECK(IsResolved() || IsErroneous());
120 return GetFieldObject<ObjectArray<AbstractMethod>*>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), false);
121}
122
123inline ObjectArray<AbstractMethod>* Class::GetVTableDuringLinking() const {
124 DCHECK(IsLoaded() || IsErroneous());
125 return GetFieldObject<ObjectArray<AbstractMethod>*>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), false);
126}
127
128inline void Class::SetVTable(ObjectArray<AbstractMethod>* new_vtable)
129 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
130 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable, false);
131}
132
Ian Rogers693ff612013-02-01 10:56:12 -0800133inline bool Class::Implements(const Class* klass) const {
134 DCHECK(klass != NULL);
135 DCHECK(klass->IsInterface()) << PrettyClass(this);
136 // All interfaces implemented directly and by our superclass, and
137 // recursively all super-interfaces of those interfaces, are listed
138 // in iftable_, so we can just do a linear scan through that.
139 int32_t iftable_count = GetIfTableCount();
140 IfTable* iftable = GetIfTable();
141 for (int32_t i = 0; i < iftable_count; i++) {
142 if (iftable->GetInterface(i) == klass) {
143 return true;
144 }
145 }
146 return false;
147}
148
149// Determine whether "this" is assignable from "src", where both of these
150// are array classes.
151//
152// Consider an array class, e.g. Y[][], where Y is a subclass of X.
153// Y[][] = Y[][] --> true (identity)
154// X[][] = Y[][] --> true (element superclass)
155// Y = Y[][] --> false
156// Y[] = Y[][] --> false
157// Object = Y[][] --> true (everything is an object)
158// Object[] = Y[][] --> true
159// Object[][] = Y[][] --> true
160// Object[][][] = Y[][] --> false (too many []s)
161// Serializable = Y[][] --> true (all arrays are Serializable)
162// Serializable[] = Y[][] --> true
163// Serializable[][] = Y[][] --> false (unless Y is Serializable)
164//
165// Don't forget about primitive types.
166// Object[] = int[] --> false
167//
168inline bool Class::IsArrayAssignableFromArray(const Class* src) const {
169 DCHECK(IsArrayClass()) << PrettyClass(this);
170 DCHECK(src->IsArrayClass()) << PrettyClass(src);
171 return GetComponentType()->IsAssignableFrom(src->GetComponentType());
172}
173
174inline bool Class::IsAssignableFromArray(const Class* src) const {
175 DCHECK(!IsInterface()) << PrettyClass(this); // handled first in IsAssignableFrom
176 DCHECK(src->IsArrayClass()) << PrettyClass(src);
177 if (!IsArrayClass()) {
178 // If "this" is not also an array, it must be Object.
179 // src's super should be java_lang_Object, since it is an array.
180 Class* java_lang_Object = src->GetSuperClass();
181 DCHECK(java_lang_Object != NULL) << PrettyClass(src);
182 DCHECK(java_lang_Object->GetSuperClass() == NULL) << PrettyClass(src);
183 return this == java_lang_Object;
184 }
185 return IsArrayAssignableFromArray(src);
186}
187
188inline bool Class::IsSubClass(const Class* klass) const {
189 DCHECK(!IsInterface()) << PrettyClass(this);
190 DCHECK(!IsArrayClass()) << PrettyClass(this);
191 const Class* current = this;
192 do {
193 if (current == klass) {
194 return true;
195 }
196 current = current->GetSuperClass();
197 } while (current != NULL);
198 return false;
199}
200
201inline AbstractMethod* Class::FindVirtualMethodForInterface(AbstractMethod* method) const {
202 Class* declaring_class = method->GetDeclaringClass();
203 DCHECK(declaring_class != NULL) << PrettyClass(this);
204 DCHECK(declaring_class->IsInterface()) << PrettyMethod(method);
205 // TODO cache to improve lookup speed
206 int32_t iftable_count = GetIfTableCount();
207 IfTable* iftable = GetIfTable();
208 for (int32_t i = 0; i < iftable_count; i++) {
209 if (iftable->GetInterface(i) == declaring_class) {
210 return iftable->GetMethodArray(i)->Get(method->GetMethodIndex());
211 }
212 }
213 return NULL;
214}
215
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800216inline AbstractMethod* Class::FindVirtualMethodForVirtual(AbstractMethod* method) const
217 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
218 DCHECK(!method->GetDeclaringClass()->IsInterface());
219 // The argument method may from a super class.
220 // Use the index to a potentially overridden one for this instance's class.
221 return GetVTable()->Get(method->GetMethodIndex());
222}
223
224inline AbstractMethod* Class::FindVirtualMethodForSuper(AbstractMethod* method) const
225 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
226 DCHECK(!method->GetDeclaringClass()->IsInterface());
227 return GetSuperClass()->GetVTable()->Get(method->GetMethodIndex());
228}
229
230inline AbstractMethod* Class::FindVirtualMethodForVirtualOrInterface(AbstractMethod* method) const {
231 if (method->IsDirect()) {
232 return method;
233 }
234 if (method->GetDeclaringClass()->IsInterface()) {
235 return FindVirtualMethodForInterface(method);
236 }
237 return FindVirtualMethodForVirtual(method);
238}
239
240inline IfTable* Class::GetIfTable() const {
241 return GetFieldObject<IfTable*>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), false);
242}
243
244inline int32_t Class::GetIfTableCount() const {
245 IfTable* iftable = GetIfTable();
246 if (iftable == NULL) {
247 return 0;
248 }
249 return iftable->Count();
250}
251
252inline void Class::SetIfTable(IfTable* new_iftable) {
253 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable, false);
254}
255
256inline ObjectArray<Field>* Class::GetIFields() const {
257 DCHECK(IsLoaded() || IsErroneous());
258 return GetFieldObject<ObjectArray<Field>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false);
259}
260
261inline void Class::SetIFields(ObjectArray<Field>* new_ifields)
262 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
263 DCHECK(NULL == GetFieldObject<ObjectArray<Field>*>(
264 OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false));
265 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields, false);
266}
267
268inline ObjectArray<Field>* Class::GetSFields() const {
269 DCHECK(IsLoaded() || IsErroneous());
270 return GetFieldObject<ObjectArray<Field>*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false);
271}
272
273inline void Class::SetSFields(ObjectArray<Field>* new_sfields)
274 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
275 DCHECK(NULL == GetFieldObject<ObjectArray<Field>*>(
276 OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false));
277 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields, false);
278}
279
280inline size_t Class::NumStaticFields() const {
281 return (GetSFields() != NULL) ? GetSFields()->GetLength() : 0;
282}
283
284inline Field* Class::GetStaticField(uint32_t i) const // TODO: uint16_t
285 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
286 return GetSFields()->Get(i);
287}
288
289inline void Class::SetStaticField(uint32_t i, Field* f) // TODO: uint16_t
290 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
291 ObjectArray<Field>* sfields= GetFieldObject<ObjectArray<Field>*>(
292 OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false);
293 sfields->Set(i, f);
294}
295
296inline size_t Class::NumInstanceFields() const {
297 return (GetIFields() != NULL) ? GetIFields()->GetLength() : 0;
298}
299
300inline Field* Class::GetInstanceField(uint32_t i) const // TODO: uint16_t
301 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
302 DCHECK_NE(NumInstanceFields(), 0U);
303 return GetIFields()->Get(i);
304}
305
306inline void Class::SetInstanceField(uint32_t i, Field* f) // TODO: uint16_t
307 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
308 ObjectArray<Field>* ifields= GetFieldObject<ObjectArray<Field>*>(
309 OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false);
310 ifields->Set(i, f);
311}
312
313inline void Class::SetVerifyErrorClass(Class* klass) {
314 CHECK(klass != NULL) << PrettyClass(this);
315 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass, false);
316}
317
318inline uint32_t Class::GetAccessFlags() const {
319 // Check class is loaded or this is java.lang.String that has a
320 // circularity issue during loading the names of its members
321 DCHECK(IsLoaded() || IsErroneous() ||
322 this == String::GetJavaLangString() ||
323 this == Field::GetJavaLangReflectField() ||
324 this == AbstractMethod::GetConstructorClass() ||
325 this == AbstractMethod::GetMethodClass());
326 return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), false);
327}
328
329inline String* Class::GetName() const {
330 return GetFieldObject<String*>(OFFSET_OF_OBJECT_MEMBER(Class, name_), false);
331}
332inline void Class::SetName(String* name) {
333 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, name_), name, false);
334}
335
336} // namespace mirror
337} // namespace art
338
339#endif // ART_SRC_MIRROR_CLASS_INL_H_