blob: 7eb8601cd6b6c941528db376175e93fc3a931605 [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
133inline AbstractMethod* Class::FindVirtualMethodForVirtual(AbstractMethod* method) const
134 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
135 DCHECK(!method->GetDeclaringClass()->IsInterface());
136 // The argument method may from a super class.
137 // Use the index to a potentially overridden one for this instance's class.
138 return GetVTable()->Get(method->GetMethodIndex());
139}
140
141inline AbstractMethod* Class::FindVirtualMethodForSuper(AbstractMethod* method) const
142 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
143 DCHECK(!method->GetDeclaringClass()->IsInterface());
144 return GetSuperClass()->GetVTable()->Get(method->GetMethodIndex());
145}
146
147inline AbstractMethod* Class::FindVirtualMethodForVirtualOrInterface(AbstractMethod* method) const {
148 if (method->IsDirect()) {
149 return method;
150 }
151 if (method->GetDeclaringClass()->IsInterface()) {
152 return FindVirtualMethodForInterface(method);
153 }
154 return FindVirtualMethodForVirtual(method);
155}
156
157inline IfTable* Class::GetIfTable() const {
158 return GetFieldObject<IfTable*>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), false);
159}
160
161inline int32_t Class::GetIfTableCount() const {
162 IfTable* iftable = GetIfTable();
163 if (iftable == NULL) {
164 return 0;
165 }
166 return iftable->Count();
167}
168
169inline void Class::SetIfTable(IfTable* new_iftable) {
170 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable, false);
171}
172
173inline ObjectArray<Field>* Class::GetIFields() const {
174 DCHECK(IsLoaded() || IsErroneous());
175 return GetFieldObject<ObjectArray<Field>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false);
176}
177
178inline void Class::SetIFields(ObjectArray<Field>* new_ifields)
179 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
180 DCHECK(NULL == GetFieldObject<ObjectArray<Field>*>(
181 OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false));
182 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields, false);
183}
184
185inline ObjectArray<Field>* Class::GetSFields() const {
186 DCHECK(IsLoaded() || IsErroneous());
187 return GetFieldObject<ObjectArray<Field>*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false);
188}
189
190inline void Class::SetSFields(ObjectArray<Field>* new_sfields)
191 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
192 DCHECK(NULL == GetFieldObject<ObjectArray<Field>*>(
193 OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false));
194 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields, false);
195}
196
197inline size_t Class::NumStaticFields() const {
198 return (GetSFields() != NULL) ? GetSFields()->GetLength() : 0;
199}
200
201inline Field* Class::GetStaticField(uint32_t i) const // TODO: uint16_t
202 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
203 return GetSFields()->Get(i);
204}
205
206inline void Class::SetStaticField(uint32_t i, Field* f) // TODO: uint16_t
207 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
208 ObjectArray<Field>* sfields= GetFieldObject<ObjectArray<Field>*>(
209 OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false);
210 sfields->Set(i, f);
211}
212
213inline size_t Class::NumInstanceFields() const {
214 return (GetIFields() != NULL) ? GetIFields()->GetLength() : 0;
215}
216
217inline Field* Class::GetInstanceField(uint32_t i) const // TODO: uint16_t
218 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
219 DCHECK_NE(NumInstanceFields(), 0U);
220 return GetIFields()->Get(i);
221}
222
223inline void Class::SetInstanceField(uint32_t i, Field* f) // TODO: uint16_t
224 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
225 ObjectArray<Field>* ifields= GetFieldObject<ObjectArray<Field>*>(
226 OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false);
227 ifields->Set(i, f);
228}
229
230inline void Class::SetVerifyErrorClass(Class* klass) {
231 CHECK(klass != NULL) << PrettyClass(this);
232 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass, false);
233}
234
235inline uint32_t Class::GetAccessFlags() const {
236 // Check class is loaded or this is java.lang.String that has a
237 // circularity issue during loading the names of its members
238 DCHECK(IsLoaded() || IsErroneous() ||
239 this == String::GetJavaLangString() ||
240 this == Field::GetJavaLangReflectField() ||
241 this == AbstractMethod::GetConstructorClass() ||
242 this == AbstractMethod::GetMethodClass());
243 return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), false);
244}
245
246inline String* Class::GetName() const {
247 return GetFieldObject<String*>(OFFSET_OF_OBJECT_MEMBER(Class, name_), false);
248}
249inline void Class::SetName(String* name) {
250 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, name_), name, false);
251}
252
253} // namespace mirror
254} // namespace art
255
256#endif // ART_SRC_MIRROR_CLASS_INL_H_