blob: 6a65e1271fce3e00de346c686cbe0b165461d1c7 [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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_MIRROR_CLASS_INL_H_
18#define ART_RUNTIME_MIRROR_CLASS_INL_H_
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080019
20#include "class.h"
21
Mingyao Yang98d1cc82014-05-15 17:02:16 -070022#include "art_field-inl.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070023#include "art_method.h"
Mingyao Yang98d1cc82014-05-15 17:02:16 -070024#include "art_method-inl.h"
Alex Lighte64300b2015-12-15 15:02:47 -080025#include "base/array_slice.h"
26#include "base/length_prefixed_array.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070027#include "class_loader.h"
Vladimir Marko23a28212014-01-09 19:24:37 +000028#include "common_throws.h"
Mathieu Chartierf8322842014-05-16 10:59:25 -070029#include "dex_file.h"
Hiroshi Yamauchi3b4c1892013-09-12 21:33:12 -070030#include "gc/heap-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080031#include "iftable.h"
Ian Rogers62d6c772013-02-27 08:32:07 -080032#include "object_array-inl.h"
Mingyao Yang98d1cc82014-05-15 17:02:16 -070033#include "read_barrier-inl.h"
Fred Shih4ee7a662014-07-11 09:59:27 -070034#include "reference-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080035#include "runtime.h"
36#include "string.h"
Vladimir Marko80afd022015-05-19 18:08:00 +010037#include "utils.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080038
39namespace art {
40namespace mirror {
41
Hiroshi Yamauchi25023c72014-05-09 11:45:53 -070042template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -080043inline uint32_t Class::GetObjectSize() {
Vladimir Marko3481ba22015-04-13 12:22:36 +010044 // Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator.
David Sehr709b0702016-10-13 09:12:37 -070045 DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << "class=" << PrettyTypeOf();
Hiroshi Yamauchie01a5202015-03-19 12:35:04 -070046 return GetField32(ObjectSizeOffset());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080047}
48
Mathieu Chartierfbc31082016-01-24 11:59:56 -080049template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Mathieu Chartier161db1d2016-09-01 14:06:54 -070050inline uint32_t Class::GetObjectSizeAllocFastPath() {
51 // Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator.
David Sehr709b0702016-10-13 09:12:37 -070052 DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << "class=" << PrettyTypeOf();
Mathieu Chartier161db1d2016-09-01 14:06:54 -070053 return GetField32(ObjectSizeAllocFastPathOffset());
54}
55
56
57template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -080058inline Class* Class::GetSuperClass() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080059 // Can only get super class for loaded classes (hack for when runtime is
60 // initializing)
Mathieu Chartierfbc31082016-01-24 11:59:56 -080061 DCHECK(IsLoaded<kVerifyFlags>() ||
62 IsErroneous<kVerifyFlags>() ||
63 !Runtime::Current()->IsStarted()) << IsLoaded();
64 return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(
65 OFFSET_OF_OBJECT_MEMBER(Class, super_class_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080066}
67
Nicolas Geoffraye51ca8b2016-11-22 14:49:31 +000068template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -080069inline ClassLoader* Class::GetClassLoader() {
Nicolas Geoffraye51ca8b2016-11-22 14:49:31 +000070 return GetFieldObject<ClassLoader, kVerifyFlags, kReadBarrierOption>(
71 OFFSET_OF_OBJECT_MEMBER(Class, class_loader_));
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070072}
73
Mathieu Chartier137cdfa2017-01-26 14:03:11 -080074template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -080075inline DexCache* Class::GetDexCache() {
Mathieu Chartier137cdfa2017-01-26 14:03:11 -080076 return GetFieldObject<DexCache, kVerifyFlags, kReadBarrierOption>(
77 OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_));
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070078}
79
Alex Lighte64300b2015-12-15 15:02:47 -080080inline uint32_t Class::GetCopiedMethodsStartOffset() {
81 return GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, copied_methods_offset_));
82}
83
84inline uint32_t Class::GetDirectMethodsStartOffset() {
85 return 0;
86}
87
88inline uint32_t Class::GetVirtualMethodsStartOffset() {
89 return GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_offset_));
90}
91
92template<VerifyObjectFlags kVerifyFlags>
Andreas Gampe542451c2016-07-26 09:02:02 -070093inline ArraySlice<ArtMethod> Class::GetDirectMethodsSlice(PointerSize pointer_size) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080094 DCHECK(IsLoaded() || IsErroneous());
Alex Lighte64300b2015-12-15 15:02:47 -080095 return GetDirectMethodsSliceUnchecked(pointer_size);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080096}
97
Andreas Gampe542451c2016-07-26 09:02:02 -070098inline ArraySlice<ArtMethod> Class::GetDirectMethodsSliceUnchecked(PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -080099 return ArraySlice<ArtMethod>(GetMethodsPtr(),
100 GetDirectMethodsStartOffset(),
101 GetVirtualMethodsStartOffset(),
102 ArtMethod::Size(pointer_size),
103 ArtMethod::Alignment(pointer_size));
104}
105
106template<VerifyObjectFlags kVerifyFlags>
Andreas Gampe542451c2016-07-26 09:02:02 -0700107inline ArraySlice<ArtMethod> Class::GetDeclaredMethodsSlice(PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800108 DCHECK(IsLoaded() || IsErroneous());
Alex Lighte64300b2015-12-15 15:02:47 -0800109 return GetDeclaredMethodsSliceUnchecked(pointer_size);
110}
111
Andreas Gampe542451c2016-07-26 09:02:02 -0700112inline ArraySlice<ArtMethod> Class::GetDeclaredMethodsSliceUnchecked(PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800113 return ArraySlice<ArtMethod>(GetMethodsPtr(),
114 GetDirectMethodsStartOffset(),
115 GetCopiedMethodsStartOffset(),
116 ArtMethod::Size(pointer_size),
117 ArtMethod::Alignment(pointer_size));
118}
119template<VerifyObjectFlags kVerifyFlags>
Andreas Gampe542451c2016-07-26 09:02:02 -0700120inline ArraySlice<ArtMethod> Class::GetDeclaredVirtualMethodsSlice(PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800121 DCHECK(IsLoaded() || IsErroneous());
Alex Lighte64300b2015-12-15 15:02:47 -0800122 return GetDeclaredVirtualMethodsSliceUnchecked(pointer_size);
123}
124
Andreas Gampe542451c2016-07-26 09:02:02 -0700125inline ArraySlice<ArtMethod> Class::GetDeclaredVirtualMethodsSliceUnchecked(
126 PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800127 return ArraySlice<ArtMethod>(GetMethodsPtr(),
128 GetVirtualMethodsStartOffset(),
129 GetCopiedMethodsStartOffset(),
130 ArtMethod::Size(pointer_size),
131 ArtMethod::Alignment(pointer_size));
132}
133
134template<VerifyObjectFlags kVerifyFlags>
Andreas Gampe542451c2016-07-26 09:02:02 -0700135inline ArraySlice<ArtMethod> Class::GetVirtualMethodsSlice(PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800136 DCHECK(IsLoaded() || IsErroneous());
Alex Lighte64300b2015-12-15 15:02:47 -0800137 return GetVirtualMethodsSliceUnchecked(pointer_size);
138}
139
Andreas Gampe542451c2016-07-26 09:02:02 -0700140inline ArraySlice<ArtMethod> Class::GetVirtualMethodsSliceUnchecked(PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800141 LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
142 return ArraySlice<ArtMethod>(methods,
143 GetVirtualMethodsStartOffset(),
144 NumMethods(),
145 ArtMethod::Size(pointer_size),
146 ArtMethod::Alignment(pointer_size));
147}
148
149template<VerifyObjectFlags kVerifyFlags>
Andreas Gampe542451c2016-07-26 09:02:02 -0700150inline ArraySlice<ArtMethod> Class::GetCopiedMethodsSlice(PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800151 DCHECK(IsLoaded() || IsErroneous());
Alex Lighte64300b2015-12-15 15:02:47 -0800152 return GetCopiedMethodsSliceUnchecked(pointer_size);
153}
154
Andreas Gampe542451c2016-07-26 09:02:02 -0700155inline ArraySlice<ArtMethod> Class::GetCopiedMethodsSliceUnchecked(PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800156 LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
157 return ArraySlice<ArtMethod>(methods,
158 GetCopiedMethodsStartOffset(),
159 NumMethods(),
160 ArtMethod::Size(pointer_size),
161 ArtMethod::Alignment(pointer_size));
162}
163
164inline LengthPrefixedArray<ArtMethod>* Class::GetMethodsPtr() {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700165 return reinterpret_cast<LengthPrefixedArray<ArtMethod>*>(
Mathieu Chartierf4b3dba2016-01-26 20:11:06 -0800166 static_cast<uintptr_t>(GetField64(OFFSET_OF_OBJECT_MEMBER(Class, methods_))));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800167}
168
Alex Lighte64300b2015-12-15 15:02:47 -0800169template<VerifyObjectFlags kVerifyFlags>
Andreas Gampe542451c2016-07-26 09:02:02 -0700170inline ArraySlice<ArtMethod> Class::GetMethodsSlice(PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800171 DCHECK(IsLoaded() || IsErroneous());
172 LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
173 return ArraySlice<ArtMethod>(methods,
174 0,
175 NumMethods(),
176 ArtMethod::Size(pointer_size),
177 ArtMethod::Alignment(pointer_size));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800178}
179
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800180
Alex Lighte64300b2015-12-15 15:02:47 -0800181inline uint32_t Class::NumMethods() {
182 LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
183 return (methods == nullptr) ? 0 : methods->size();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700184}
185
Andreas Gampe542451c2016-07-26 09:02:02 -0700186inline ArtMethod* Class::GetDirectMethodUnchecked(size_t i, PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700187 CheckPointerSize(pointer_size);
Alex Lighte64300b2015-12-15 15:02:47 -0800188 return &GetDirectMethodsSliceUnchecked(pointer_size).At(i);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700189}
190
Andreas Gampe542451c2016-07-26 09:02:02 -0700191inline ArtMethod* Class::GetDirectMethod(size_t i, PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700192 CheckPointerSize(pointer_size);
Alex Lighte64300b2015-12-15 15:02:47 -0800193 return &GetDirectMethodsSlice(pointer_size).At(i);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800194}
195
Alex Lighte64300b2015-12-15 15:02:47 -0800196inline void Class::SetMethodsPtr(LengthPrefixedArray<ArtMethod>* new_methods,
197 uint32_t num_direct,
198 uint32_t num_virtual) {
199 DCHECK(GetMethodsPtr() == nullptr);
200 SetMethodsPtrUnchecked(new_methods, num_direct, num_virtual);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800201}
202
Alex Lighte64300b2015-12-15 15:02:47 -0800203
204inline void Class::SetMethodsPtrUnchecked(LengthPrefixedArray<ArtMethod>* new_methods,
205 uint32_t num_direct,
206 uint32_t num_virtual) {
207 DCHECK_LE(num_direct + num_virtual, (new_methods == nullptr) ? 0 : new_methods->size());
208 SetMethodsPtrInternal(new_methods);
209 SetFieldShort<false>(OFFSET_OF_OBJECT_MEMBER(Class, copied_methods_offset_),
210 dchecked_integral_cast<uint16_t>(num_direct + num_virtual));
211 SetFieldShort<false>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_offset_),
212 dchecked_integral_cast<uint16_t>(num_direct));
213}
214
215inline void Class::SetMethodsPtrInternal(LengthPrefixedArray<ArtMethod>* new_methods) {
216 SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, methods_),
Mathieu Chartierf4b3dba2016-01-26 20:11:06 -0800217 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(new_methods)));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800218}
219
Mathieu Chartier4e305412014-02-19 10:54:44 -0800220template<VerifyObjectFlags kVerifyFlags>
Andreas Gampe542451c2016-07-26 09:02:02 -0700221inline ArtMethod* Class::GetVirtualMethod(size_t i, PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700222 CheckPointerSize(pointer_size);
Hiroshi Yamauchif4c15a12014-10-20 16:56:58 -0700223 DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>())
David Sehr709b0702016-10-13 09:12:37 -0700224 << Class::PrettyClass() << " status=" << GetStatus();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700225 return GetVirtualMethodUnchecked(i, pointer_size);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800226}
227
Andreas Gampe542451c2016-07-26 09:02:02 -0700228inline ArtMethod* Class::GetVirtualMethodDuringLinking(size_t i, PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700229 CheckPointerSize(pointer_size);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800230 DCHECK(IsLoaded() || IsErroneous());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700231 return GetVirtualMethodUnchecked(i, pointer_size);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800232}
233
Andreas Gampe542451c2016-07-26 09:02:02 -0700234inline ArtMethod* Class::GetVirtualMethodUnchecked(size_t i, PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700235 CheckPointerSize(pointer_size);
Alex Lighte64300b2015-12-15 15:02:47 -0800236 return &GetVirtualMethodsSliceUnchecked(pointer_size).At(i);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800237}
238
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800239template<VerifyObjectFlags kVerifyFlags,
240 ReadBarrierOption kReadBarrierOption>
Mathieu Chartiere401d142015-04-22 13:56:20 -0700241inline PointerArray* Class::GetVTable() {
Mingyao Yang063fc772016-08-02 11:02:54 -0700242 DCHECK(IsLoaded<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800243 return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(
244 OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800245}
246
Mathieu Chartiere401d142015-04-22 13:56:20 -0700247inline PointerArray* Class::GetVTableDuringLinking() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800248 DCHECK(IsLoaded() || IsErroneous());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700249 return GetFieldObject<PointerArray>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800250}
251
Mathieu Chartiere401d142015-04-22 13:56:20 -0700252inline void Class::SetVTable(PointerArray* new_vtable) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700253 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800254}
255
Mingyao Yang2cdbad72014-07-16 10:44:41 -0700256inline bool Class::HasVTable() {
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +0000257 return GetVTable() != nullptr || ShouldHaveEmbeddedVTable();
Mingyao Yang2cdbad72014-07-16 10:44:41 -0700258}
259
260inline int32_t Class::GetVTableLength() {
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +0000261 if (ShouldHaveEmbeddedVTable()) {
Mingyao Yang2cdbad72014-07-16 10:44:41 -0700262 return GetEmbeddedVTableLength();
263 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700264 return GetVTable() != nullptr ? GetVTable()->GetLength() : 0;
Mingyao Yang2cdbad72014-07-16 10:44:41 -0700265}
266
Andreas Gampe542451c2016-07-26 09:02:02 -0700267inline ArtMethod* Class::GetVTableEntry(uint32_t i, PointerSize pointer_size) {
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +0000268 if (ShouldHaveEmbeddedVTable()) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700269 return GetEmbeddedVTableEntry(i, pointer_size);
Mingyao Yang2cdbad72014-07-16 10:44:41 -0700270 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700271 auto* vtable = GetVTable();
272 DCHECK(vtable != nullptr);
273 return vtable->GetElementPtrSize<ArtMethod*>(i, pointer_size);
Mingyao Yang2cdbad72014-07-16 10:44:41 -0700274}
275
276inline int32_t Class::GetEmbeddedVTableLength() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700277 return GetField32(MemberOffset(EmbeddedVTableLengthOffset()));
Mingyao Yang2cdbad72014-07-16 10:44:41 -0700278}
279
280inline void Class::SetEmbeddedVTableLength(int32_t len) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700281 SetField32<false>(MemberOffset(EmbeddedVTableLengthOffset()), len);
Mingyao Yang2cdbad72014-07-16 10:44:41 -0700282}
283
Andreas Gampe542451c2016-07-26 09:02:02 -0700284inline ImTable* Class::GetImt(PointerSize pointer_size) {
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +0000285 return GetFieldPtrWithSize<ImTable*>(MemberOffset(ImtPtrOffset(pointer_size)), pointer_size);
286}
287
Andreas Gampe542451c2016-07-26 09:02:02 -0700288inline void Class::SetImt(ImTable* imt, PointerSize pointer_size) {
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +0000289 return SetFieldPtrWithSize<false>(MemberOffset(ImtPtrOffset(pointer_size)), imt, pointer_size);
290}
291
Andreas Gampe542451c2016-07-26 09:02:02 -0700292inline MemberOffset Class::EmbeddedVTableEntryOffset(uint32_t i, PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700293 return MemberOffset(
294 EmbeddedVTableOffset(pointer_size).Uint32Value() + i * VTableEntrySize(pointer_size));
Mingyao Yang2cdbad72014-07-16 10:44:41 -0700295}
296
Andreas Gampe542451c2016-07-26 09:02:02 -0700297inline ArtMethod* Class::GetEmbeddedVTableEntry(uint32_t i, PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700298 return GetFieldPtrWithSize<ArtMethod*>(EmbeddedVTableEntryOffset(i, pointer_size), pointer_size);
299}
300
301inline void Class::SetEmbeddedVTableEntryUnchecked(
Andreas Gampe542451c2016-07-26 09:02:02 -0700302 uint32_t i, ArtMethod* method, PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700303 SetFieldPtrWithSize<false>(EmbeddedVTableEntryOffset(i, pointer_size), method, pointer_size);
304}
305
Andreas Gampe542451c2016-07-26 09:02:02 -0700306inline void Class::SetEmbeddedVTableEntry(uint32_t i, ArtMethod* method, PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700307 auto* vtable = GetVTableDuringLinking();
308 CHECK_EQ(method, vtable->GetElementPtrSize<ArtMethod*>(i, pointer_size));
309 SetEmbeddedVTableEntryUnchecked(i, method, pointer_size);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700310}
311
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700312inline bool Class::Implements(ObjPtr<Class> klass) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700313 DCHECK(klass != nullptr);
David Sehr709b0702016-10-13 09:12:37 -0700314 DCHECK(klass->IsInterface()) << PrettyClass();
Ian Rogers693ff612013-02-01 10:56:12 -0800315 // All interfaces implemented directly and by our superclass, and
316 // recursively all super-interfaces of those interfaces, are listed
317 // in iftable_, so we can just do a linear scan through that.
318 int32_t iftable_count = GetIfTableCount();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700319 ObjPtr<IfTable> iftable = GetIfTable();
Ian Rogers693ff612013-02-01 10:56:12 -0800320 for (int32_t i = 0; i < iftable_count; i++) {
321 if (iftable->GetInterface(i) == klass) {
322 return true;
323 }
324 }
325 return false;
326}
327
328// Determine whether "this" is assignable from "src", where both of these
329// are array classes.
330//
331// Consider an array class, e.g. Y[][], where Y is a subclass of X.
332// Y[][] = Y[][] --> true (identity)
333// X[][] = Y[][] --> true (element superclass)
334// Y = Y[][] --> false
335// Y[] = Y[][] --> false
336// Object = Y[][] --> true (everything is an object)
337// Object[] = Y[][] --> true
338// Object[][] = Y[][] --> true
339// Object[][][] = Y[][] --> false (too many []s)
340// Serializable = Y[][] --> true (all arrays are Serializable)
341// Serializable[] = Y[][] --> true
342// Serializable[][] = Y[][] --> false (unless Y is Serializable)
343//
344// Don't forget about primitive types.
345// Object[] = int[] --> false
346//
Mathieu Chartier3398c782016-09-30 10:27:43 -0700347inline bool Class::IsArrayAssignableFromArray(ObjPtr<Class> src) {
David Sehr709b0702016-10-13 09:12:37 -0700348 DCHECK(IsArrayClass()) << PrettyClass();
349 DCHECK(src->IsArrayClass()) << src->PrettyClass();
Ian Rogers693ff612013-02-01 10:56:12 -0800350 return GetComponentType()->IsAssignableFrom(src->GetComponentType());
351}
352
Mathieu Chartier3398c782016-09-30 10:27:43 -0700353inline bool Class::IsAssignableFromArray(ObjPtr<Class> src) {
David Sehr709b0702016-10-13 09:12:37 -0700354 DCHECK(!IsInterface()) << PrettyClass(); // handled first in IsAssignableFrom
355 DCHECK(src->IsArrayClass()) << src->PrettyClass();
Ian Rogers693ff612013-02-01 10:56:12 -0800356 if (!IsArrayClass()) {
357 // If "this" is not also an array, it must be Object.
358 // src's super should be java_lang_Object, since it is an array.
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700359 ObjPtr<Class> java_lang_Object = src->GetSuperClass();
David Sehr709b0702016-10-13 09:12:37 -0700360 DCHECK(java_lang_Object != nullptr) << src->PrettyClass();
361 DCHECK(java_lang_Object->GetSuperClass() == nullptr) << src->PrettyClass();
Ian Rogers693ff612013-02-01 10:56:12 -0800362 return this == java_lang_Object;
363 }
364 return IsArrayAssignableFromArray(src);
365}
366
Vladimir Marko89786432014-01-31 15:03:55 +0000367template <bool throw_on_failure, bool use_referrers_cache>
Mathieu Chartierb8901302016-09-30 10:27:43 -0700368inline bool Class::ResolvedFieldAccessTest(ObjPtr<Class> access_to,
Mathieu Chartier3398c782016-09-30 10:27:43 -0700369 ArtField* field,
370 uint32_t field_idx,
Mathieu Chartierb8901302016-09-30 10:27:43 -0700371 ObjPtr<DexCache> dex_cache) {
Vladimir Marko89786432014-01-31 15:03:55 +0000372 DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
Vladimir Marko23a28212014-01-09 19:24:37 +0000373 if (UNLIKELY(!this->CanAccess(access_to))) {
374 // The referrer class can't access the field's declaring class but may still be able
375 // to access the field if the FieldId specifies an accessible subclass of the declaring
376 // class rather than the declaring class itself.
Mathieu Chartierb8901302016-09-30 10:27:43 -0700377 ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800378 dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_;
Mathieu Chartier279ac5c2016-09-08 17:34:25 -0700379 // The referenced class has already been resolved with the field, but may not be in the dex
Mathieu Chartierb8901302016-09-30 10:27:43 -0700380 // cache. Use LookupResolveType here to search the class table if it is not in the dex cache.
Mathieu Chartier279ac5c2016-09-08 17:34:25 -0700381 // should be no thread suspension due to the class being resolved.
Mathieu Chartierb8901302016-09-30 10:27:43 -0700382 ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType(
383 *referrer_dex_cache->GetDexFile(),
384 class_idx,
385 referrer_dex_cache,
386 access_to->GetClassLoader());
Vladimir Marko23a28212014-01-09 19:24:37 +0000387 DCHECK(dex_access_to != nullptr);
388 if (UNLIKELY(!this->CanAccess(dex_access_to))) {
389 if (throw_on_failure) {
Mathieu Chartier6b3d12b2016-10-13 13:59:58 -0700390 ThrowIllegalAccessErrorClass(this, dex_access_to);
Vladimir Marko23a28212014-01-09 19:24:37 +0000391 }
392 return false;
393 }
Vladimir Marko23a28212014-01-09 19:24:37 +0000394 }
395 if (LIKELY(this->CanAccessMember(access_to, field->GetAccessFlags()))) {
396 return true;
397 }
398 if (throw_on_failure) {
399 ThrowIllegalAccessErrorField(this, field);
400 }
401 return false;
402}
403
Vladimir Marko89786432014-01-31 15:03:55 +0000404template <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type>
Mathieu Chartierb8901302016-09-30 10:27:43 -0700405inline bool Class::ResolvedMethodAccessTest(ObjPtr<Class> access_to,
406 ArtMethod* method,
407 uint32_t method_idx,
408 ObjPtr<DexCache> dex_cache) {
Andreas Gampe575e78c2014-11-03 23:41:03 -0800409 static_assert(throw_on_failure || throw_invoke_type == kStatic, "Non-default throw invoke type");
Vladimir Marko89786432014-01-31 15:03:55 +0000410 DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
Vladimir Marko23a28212014-01-09 19:24:37 +0000411 if (UNLIKELY(!this->CanAccess(access_to))) {
412 // The referrer class can't access the method's declaring class but may still be able
413 // to access the method if the MethodId specifies an accessible subclass of the declaring
414 // class rather than the declaring class itself.
Mathieu Chartierb8901302016-09-30 10:27:43 -0700415 ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800416 dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
Mathieu Chartier279ac5c2016-09-08 17:34:25 -0700417 // The referenced class has already been resolved with the method, but may not be in the dex
Mathieu Chartierb8901302016-09-30 10:27:43 -0700418 // cache.
419 ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType(
420 *referrer_dex_cache->GetDexFile(),
421 class_idx,
422 referrer_dex_cache,
423 access_to->GetClassLoader());
Vladimir Marko23a28212014-01-09 19:24:37 +0000424 DCHECK(dex_access_to != nullptr);
425 if (UNLIKELY(!this->CanAccess(dex_access_to))) {
426 if (throw_on_failure) {
Mathieu Chartierb8901302016-09-30 10:27:43 -0700427 ThrowIllegalAccessErrorClassForMethodDispatch(this,
Mathieu Chartier1cc62e42016-10-03 18:01:28 -0700428 dex_access_to.Ptr(),
Mathieu Chartierb8901302016-09-30 10:27:43 -0700429 method,
430 throw_invoke_type);
Vladimir Marko23a28212014-01-09 19:24:37 +0000431 }
432 return false;
433 }
Vladimir Marko23a28212014-01-09 19:24:37 +0000434 }
435 if (LIKELY(this->CanAccessMember(access_to, method->GetAccessFlags()))) {
436 return true;
437 }
438 if (throw_on_failure) {
439 ThrowIllegalAccessErrorMethod(this, method);
440 }
441 return false;
442}
443
Mathieu Chartier3398c782016-09-30 10:27:43 -0700444inline bool Class::CanAccessResolvedField(ObjPtr<Class> access_to,
445 ArtField* field,
446 ObjPtr<DexCache> dex_cache,
447 uint32_t field_idx) {
Mathieu Chartierb8901302016-09-30 10:27:43 -0700448 return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, dex_cache);
Vladimir Marko89786432014-01-31 15:03:55 +0000449}
450
Mathieu Chartier3398c782016-09-30 10:27:43 -0700451inline bool Class::CheckResolvedFieldAccess(ObjPtr<Class> access_to,
452 ArtField* field,
Vladimir Marko89786432014-01-31 15:03:55 +0000453 uint32_t field_idx) {
Mathieu Chartierf8ac97f2016-10-05 15:56:52 -0700454 return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr);
Vladimir Marko89786432014-01-31 15:03:55 +0000455}
456
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700457inline bool Class::CanAccessResolvedMethod(ObjPtr<Class> access_to,
458 ArtMethod* method,
459 ObjPtr<DexCache> dex_cache,
460 uint32_t method_idx) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800461 return ResolvedMethodAccessTest<false, false, kStatic>(access_to, method, method_idx, dex_cache);
Vladimir Marko89786432014-01-31 15:03:55 +0000462}
463
464template <InvokeType throw_invoke_type>
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700465inline bool Class::CheckResolvedMethodAccess(ObjPtr<Class> access_to,
466 ArtMethod* method,
Vladimir Marko89786432014-01-31 15:03:55 +0000467 uint32_t method_idx) {
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700468 return ResolvedMethodAccessTest<true, true, throw_invoke_type>(access_to,
469 method,
470 method_idx,
Vladimir Marko89786432014-01-31 15:03:55 +0000471 nullptr);
472}
473
Mathieu Chartier3398c782016-09-30 10:27:43 -0700474inline bool Class::IsSubClass(ObjPtr<Class> klass) {
David Sehr709b0702016-10-13 09:12:37 -0700475 DCHECK(!IsInterface()) << PrettyClass();
476 DCHECK(!IsArrayClass()) << PrettyClass();
Mathieu Chartier3398c782016-09-30 10:27:43 -0700477 ObjPtr<Class> current = this;
Ian Rogers693ff612013-02-01 10:56:12 -0800478 do {
479 if (current == klass) {
480 return true;
481 }
482 current = current->GetSuperClass();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700483 } while (current != nullptr);
Ian Rogers693ff612013-02-01 10:56:12 -0800484 return false;
485}
486
Andreas Gampe542451c2016-07-26 09:02:02 -0700487inline ArtMethod* Class::FindVirtualMethodForInterface(ArtMethod* method,
488 PointerSize pointer_size) {
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700489 ObjPtr<Class> declaring_class = method->GetDeclaringClass();
David Sehr709b0702016-10-13 09:12:37 -0700490 DCHECK(declaring_class != nullptr) << PrettyClass();
491 DCHECK(declaring_class->IsInterface()) << method->PrettyMethod();
Alex Light0f7e8f52016-07-19 11:21:32 -0700492 DCHECK(!method->IsCopied());
Ian Rogers693ff612013-02-01 10:56:12 -0800493 // TODO cache to improve lookup speed
Mathieu Chartiere401d142015-04-22 13:56:20 -0700494 const int32_t iftable_count = GetIfTableCount();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700495 ObjPtr<IfTable> iftable = GetIfTable();
Ian Rogers693ff612013-02-01 10:56:12 -0800496 for (int32_t i = 0; i < iftable_count; i++) {
497 if (iftable->GetInterface(i) == declaring_class) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700498 return iftable->GetMethodArray(i)->GetElementPtrSize<ArtMethod*>(
499 method->GetMethodIndex(), pointer_size);
Ian Rogers693ff612013-02-01 10:56:12 -0800500 }
501 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700502 return nullptr;
Ian Rogers693ff612013-02-01 10:56:12 -0800503}
504
Andreas Gampe542451c2016-07-26 09:02:02 -0700505inline ArtMethod* Class::FindVirtualMethodForVirtual(ArtMethod* method, PointerSize pointer_size) {
Alex Lighteb7c1442015-08-31 13:17:42 -0700506 // Only miranda or default methods may come from interfaces and be used as a virtual.
507 DCHECK(!method->GetDeclaringClass()->IsInterface() || method->IsDefault() || method->IsMiranda());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800508 // The argument method may from a super class.
509 // Use the index to a potentially overridden one for this instance's class.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700510 return GetVTableEntry(method->GetMethodIndex(), pointer_size);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800511}
512
Andreas Gampe542451c2016-07-26 09:02:02 -0700513inline ArtMethod* Class::FindVirtualMethodForSuper(ArtMethod* method, PointerSize pointer_size) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800514 DCHECK(!method->GetDeclaringClass()->IsInterface());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700515 return GetSuperClass()->GetVTableEntry(method->GetMethodIndex(), pointer_size);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800516}
517
Mathieu Chartiere401d142015-04-22 13:56:20 -0700518inline ArtMethod* Class::FindVirtualMethodForVirtualOrInterface(ArtMethod* method,
Andreas Gampe542451c2016-07-26 09:02:02 -0700519 PointerSize pointer_size) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800520 if (method->IsDirect()) {
521 return method;
522 }
Alex Light36121492016-02-22 13:43:29 -0800523 if (method->GetDeclaringClass()->IsInterface() && !method->IsCopied()) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700524 return FindVirtualMethodForInterface(method, pointer_size);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800525 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700526 return FindVirtualMethodForVirtual(method, pointer_size);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800527}
528
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800529template<VerifyObjectFlags kVerifyFlags,
530 ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800531inline IfTable* Class::GetIfTable() {
Mathieu Chartier6beced42016-11-15 15:51:31 -0800532 ObjPtr<IfTable> ret = GetFieldObject<IfTable, kVerifyFlags, kReadBarrierOption>(IfTableOffset());
533 DCHECK(ret != nullptr) << PrettyClass(this);
534 return ret.Ptr();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800535}
536
Ian Rogersef7d42f2014-01-06 12:55:46 -0800537inline int32_t Class::GetIfTableCount() {
Mathieu Chartier6beced42016-11-15 15:51:31 -0800538 return GetIfTable()->Count();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800539}
540
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700541inline void Class::SetIfTable(ObjPtr<IfTable> new_iftable) {
Mathieu Chartier6beced42016-11-15 15:51:31 -0800542 DCHECK(new_iftable != nullptr) << PrettyClass(this);
Mathieu Chartier2ecfd272016-11-01 10:10:05 -0700543 SetFieldObject<false>(IfTableOffset(), new_iftable);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800544}
545
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700546inline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtr() {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800547 DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700548 return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800549}
550
Hiroshi Yamauchi5496f692016-02-17 13:29:59 -0800551template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Vladimir Marko76649e82014-11-10 18:32:59 +0000552inline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() {
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700553 ObjPtr<Class> super_class = GetSuperClass<kVerifyFlags, kReadBarrierOption>();
Vladimir Marko76649e82014-11-10 18:32:59 +0000554 return (super_class != nullptr)
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -0700555 ? MemberOffset(RoundUp(super_class->GetObjectSize<kVerifyFlags, kReadBarrierOption>(),
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700556 kHeapReferenceSize))
Vladimir Marko76649e82014-11-10 18:32:59 +0000557 : ClassOffset();
558}
559
Mathieu Chartierdfe02f62016-02-01 20:15:11 -0800560template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Andreas Gampe542451c2016-07-26 09:02:02 -0700561inline MemberOffset Class::GetFirstReferenceStaticFieldOffset(PointerSize pointer_size) {
Vladimir Marko76649e82014-11-10 18:32:59 +0000562 DCHECK(IsResolved());
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700563 uint32_t base = sizeof(Class); // Static fields come after the class.
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +0000564 if (ShouldHaveEmbeddedVTable<kVerifyFlags, kReadBarrierOption>()) {
Vladimir Marko76649e82014-11-10 18:32:59 +0000565 // Static fields come after the embedded tables.
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700566 base = Class::ComputeClassSize(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700567 true, GetEmbeddedVTableLength(), 0, 0, 0, 0, 0, pointer_size);
Vladimir Marko76649e82014-11-10 18:32:59 +0000568 }
569 return MemberOffset(base);
570}
571
Andreas Gampe542451c2016-07-26 09:02:02 -0700572inline MemberOffset Class::GetFirstReferenceStaticFieldOffsetDuringLinking(
573 PointerSize pointer_size) {
Vladimir Marko76649e82014-11-10 18:32:59 +0000574 DCHECK(IsLoaded());
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700575 uint32_t base = sizeof(Class); // Static fields come after the class.
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +0000576 if (ShouldHaveEmbeddedVTable()) {
Vladimir Marko76649e82014-11-10 18:32:59 +0000577 // Static fields come after the embedded tables.
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700578 base = Class::ComputeClassSize(true, GetVTableDuringLinking()->GetLength(),
Mathieu Chartiere401d142015-04-22 13:56:20 -0700579 0, 0, 0, 0, 0, pointer_size);
Vladimir Marko76649e82014-11-10 18:32:59 +0000580 }
581 return MemberOffset(base);
582}
583
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700584inline void Class::SetIFieldsPtr(LengthPrefixedArray<ArtField>* new_ifields) {
585 DCHECK(GetIFieldsPtrUnchecked() == nullptr);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700586 return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800587}
588
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700589inline void Class::SetIFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_ifields) {
Mathieu Chartierc7853442015-03-27 14:35:38 -0700590 SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
591}
592
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700593inline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtrUnchecked() {
594 return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
Mathieu Chartierc7853442015-03-27 14:35:38 -0700595}
596
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700597inline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtrUnchecked() {
598 return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
Mathieu Chartierc7853442015-03-27 14:35:38 -0700599}
600
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700601inline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtr() {
Mathieu Chartier987ca8b2015-03-15 14:19:14 -0700602 DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700603 return GetSFieldsPtrUnchecked();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800604}
605
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700606inline void Class::SetSFieldsPtr(LengthPrefixedArray<ArtField>* new_sfields) {
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700607 DCHECK((IsRetired() && new_sfields == nullptr) ||
Mathieu Chartierc7853442015-03-27 14:35:38 -0700608 GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)) == nullptr);
609 SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800610}
611
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700612inline void Class::SetSFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_sfields) {
Mathieu Chartierc7853442015-03-27 14:35:38 -0700613 SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800614}
615
Mathieu Chartierc7853442015-03-27 14:35:38 -0700616inline ArtField* Class::GetStaticField(uint32_t i) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700617 return &GetSFieldsPtr()->At(i);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800618}
619
Mathieu Chartierc7853442015-03-27 14:35:38 -0700620inline ArtField* Class::GetInstanceField(uint32_t i) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700621 return &GetIFieldsPtr()->At(i);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800622}
623
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700624template<VerifyObjectFlags kVerifyFlags>
625inline uint32_t Class::GetReferenceInstanceOffsets() {
626 DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
627 return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_));
628}
629
630inline void Class::SetClinitThreadId(pid_t new_clinit_thread_id) {
631 if (Runtime::Current()->IsActiveTransaction()) {
632 SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
633 } else {
634 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
635 }
636}
637
Mathieu Chartier4e305412014-02-19 10:54:44 -0800638template<VerifyObjectFlags kVerifyFlags>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800639inline uint32_t Class::GetAccessFlags() {
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700640 // Check class is loaded/retired or this is java.lang.String that has a
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800641 // circularity issue during loading the names of its members
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700642 DCHECK(IsIdxLoaded<kVerifyFlags>() || IsRetired<kVerifyFlags>() ||
Mathieu Chartier4e305412014-02-19 10:54:44 -0800643 IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ||
Mathieu Chartiere401d142015-04-22 13:56:20 -0700644 this == String::GetJavaLangString())
Andreas Gampea6928662014-12-12 11:06:00 -0800645 << "IsIdxLoaded=" << IsIdxLoaded<kVerifyFlags>()
646 << " IsRetired=" << IsRetired<kVerifyFlags>()
647 << " IsErroneous=" <<
648 IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>()
649 << " IsString=" << (this == String::GetJavaLangString())
Alex Light705ad492015-09-21 11:36:30 -0700650 << " status= " << GetStatus<kVerifyFlags>()
David Sehr709b0702016-10-13 09:12:37 -0700651 << " descriptor=" << PrettyDescriptor();
Hiroshi Yamauchie01a5202015-03-19 12:35:04 -0700652 return GetField32<kVerifyFlags>(AccessFlagsOffset());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800653}
654
Ian Rogersef7d42f2014-01-06 12:55:46 -0800655inline String* Class::GetName() {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700656 return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(Class, name_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800657}
Mathieu Chartier52a7f5c2015-08-18 18:35:52 -0700658
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700659inline void Class::SetName(ObjPtr<String> name) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100660 if (Runtime::Current()->IsActiveTransaction()) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700661 SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100662 } else {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700663 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100664 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800665}
666
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700667template<VerifyObjectFlags kVerifyFlags>
668inline Primitive::Type Class::GetPrimitiveType() {
Roland Levillain33d69032015-06-18 18:20:59 +0100669 static_assert(sizeof(Primitive::Type) == sizeof(int32_t),
670 "art::Primitive::Type and int32_t have different sizes.");
Hiroshi Yamauchif0edfc32014-09-25 11:46:46 -0700671 int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_));
Mathieu Chartier8261d022016-08-08 09:41:04 -0700672 Primitive::Type type = static_cast<Primitive::Type>(v32 & kPrimitiveTypeMask);
673 DCHECK_EQ(static_cast<size_t>(v32 >> kPrimitiveTypeSizeShiftShift),
674 Primitive::ComponentSizeShift(type));
Hiroshi Yamauchif0edfc32014-09-25 11:46:46 -0700675 return type;
676}
677
678template<VerifyObjectFlags kVerifyFlags>
679inline size_t Class::GetPrimitiveTypeSizeShift() {
Roland Levillain33d69032015-06-18 18:20:59 +0100680 static_assert(sizeof(Primitive::Type) == sizeof(int32_t),
681 "art::Primitive::Type and int32_t have different sizes.");
Hiroshi Yamauchif0edfc32014-09-25 11:46:46 -0700682 int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_));
Mathieu Chartier8261d022016-08-08 09:41:04 -0700683 size_t size_shift = static_cast<Primitive::Type>(v32 >> kPrimitiveTypeSizeShiftShift);
684 DCHECK_EQ(size_shift,
685 Primitive::ComponentSizeShift(static_cast<Primitive::Type>(v32 & kPrimitiveTypeMask)));
Hiroshi Yamauchif0edfc32014-09-25 11:46:46 -0700686 return size_shift;
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700687}
688
Hiroshi Yamauchi3b4c1892013-09-12 21:33:12 -0700689inline void Class::CheckObjectAlloc() {
Hiroshi Yamauchi4cd662e2014-04-03 16:28:10 -0700690 DCHECK(!IsArrayClass())
David Sehr709b0702016-10-13 09:12:37 -0700691 << PrettyClass()
Hiroshi Yamauchi4cd662e2014-04-03 16:28:10 -0700692 << "A array shouldn't be allocated through this "
693 << "as it requires a pre-fence visitor that sets the class size.";
694 DCHECK(!IsClassClass())
David Sehr709b0702016-10-13 09:12:37 -0700695 << PrettyClass()
Hiroshi Yamauchi4cd662e2014-04-03 16:28:10 -0700696 << "A class object shouldn't be allocated through this "
697 << "as it requires a pre-fence visitor that sets the class size.";
Jeff Hao848f70a2014-01-15 13:49:50 -0800698 DCHECK(!IsStringClass())
David Sehr709b0702016-10-13 09:12:37 -0700699 << PrettyClass()
Jeff Hao848f70a2014-01-15 13:49:50 -0800700 << "A string shouldn't be allocated through this "
701 << "as it requires a pre-fence visitor that sets the class size.";
David Sehr709b0702016-10-13 09:12:37 -0700702 DCHECK(IsInstantiable()) << PrettyClass();
Hiroshi Yamauchi967a0ad2013-09-10 16:24:21 -0700703 // TODO: decide whether we want this check. It currently fails during bootstrap.
David Sehr709b0702016-10-13 09:12:37 -0700704 // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass();
Hiroshi Yamauchi967a0ad2013-09-10 16:24:21 -0700705 DCHECK_GE(this->object_size_, sizeof(Object));
Hiroshi Yamauchi3b4c1892013-09-12 21:33:12 -0700706}
707
Mathieu Chartier8668c3c2014-04-24 16:48:11 -0700708template<bool kIsInstrumented, bool kCheckAddFinalizer>
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700709inline ObjPtr<Object> Class::Alloc(Thread* self, gc::AllocatorType allocator_type) {
Hiroshi Yamauchi3b4c1892013-09-12 21:33:12 -0700710 CheckObjectAlloc();
Mathieu Chartier590fee92013-09-13 13:46:47 -0700711 gc::Heap* heap = Runtime::Current()->GetHeap();
Mathieu Chartier8668c3c2014-04-24 16:48:11 -0700712 const bool add_finalizer = kCheckAddFinalizer && IsFinalizable();
713 if (!kCheckAddFinalizer) {
714 DCHECK(!IsFinalizable());
715 }
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700716 // Note that the this pointer may be invalidated after the allocation.
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700717 ObjPtr<Object> obj =
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700718 heap->AllocObjectWithAllocator<kIsInstrumented, false>(self,
719 this,
720 this->object_size_,
721 allocator_type,
722 VoidFunctor());
Mathieu Chartier8668c3c2014-04-24 16:48:11 -0700723 if (add_finalizer && LIKELY(obj != nullptr)) {
724 heap->AddFinalizerReference(self, &obj);
Pavel Vyssotski3ac90da2014-12-02 19:54:50 +0600725 if (UNLIKELY(self->IsExceptionPending())) {
726 // Failed to allocate finalizer reference, it means that the whole allocation failed.
727 obj = nullptr;
728 }
Mathieu Chartier8668c3c2014-04-24 16:48:11 -0700729 }
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700730 return obj.Ptr();
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800731}
732
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700733inline ObjPtr<Object> Class::AllocObject(Thread* self) {
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800734 return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentAllocator());
735}
736
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700737inline ObjPtr<Object> Class::AllocNonMovableObject(Thread* self) {
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800738 return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator());
Hiroshi Yamauchi967a0ad2013-09-10 16:24:21 -0700739}
740
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +0000741inline uint32_t Class::ComputeClassSize(bool has_embedded_vtable,
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700742 uint32_t num_vtable_entries,
Fred Shih37f05ef2014-07-16 18:38:08 -0700743 uint32_t num_8bit_static_fields,
744 uint32_t num_16bit_static_fields,
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700745 uint32_t num_32bit_static_fields,
746 uint32_t num_64bit_static_fields,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700747 uint32_t num_ref_static_fields,
Andreas Gampe542451c2016-07-26 09:02:02 -0700748 PointerSize pointer_size) {
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700749 // Space used by java.lang.Class and its instance fields.
750 uint32_t size = sizeof(Class);
751 // Space used by embedded tables.
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +0000752 if (has_embedded_vtable) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700753 size = RoundUp(size + sizeof(uint32_t), static_cast<size_t>(pointer_size));
754 size += static_cast<size_t>(pointer_size); // size of pointer to IMT
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +0000755 size += num_vtable_entries * VTableEntrySize(pointer_size);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700756 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700757
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700758 // Space used by reference statics.
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700759 size += num_ref_static_fields * kHeapReferenceSize;
Fred Shih37f05ef2014-07-16 18:38:08 -0700760 if (!IsAligned<8>(size) && num_64bit_static_fields > 0) {
761 uint32_t gap = 8 - (size & 0x7);
762 size += gap; // will be padded
763 // Shuffle 4-byte fields forward.
764 while (gap >= sizeof(uint32_t) && num_32bit_static_fields != 0) {
765 --num_32bit_static_fields;
766 gap -= sizeof(uint32_t);
767 }
768 // Shuffle 2-byte fields forward.
769 while (gap >= sizeof(uint16_t) && num_16bit_static_fields != 0) {
770 --num_16bit_static_fields;
771 gap -= sizeof(uint16_t);
772 }
773 // Shuffle byte fields forward.
774 while (gap >= sizeof(uint8_t) && num_8bit_static_fields != 0) {
775 --num_8bit_static_fields;
776 gap -= sizeof(uint8_t);
Mingyao Yang2cdbad72014-07-16 10:44:41 -0700777 }
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700778 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700779 // Guaranteed to be at least 4 byte aligned. No need for further alignments.
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700780 // Space used for primitive static fields.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700781 size += num_8bit_static_fields * sizeof(uint8_t) + num_16bit_static_fields * sizeof(uint16_t) +
782 num_32bit_static_fields * sizeof(uint32_t) + num_64bit_static_fields * sizeof(uint64_t);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700783 return size;
784}
785
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800786template <bool kVisitNativeRoots,
787 VerifyObjectFlags kVerifyFlags,
788 ReadBarrierOption kReadBarrierOption,
789 typename Visitor>
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700790inline void Class::VisitReferences(ObjPtr<Class> klass, const Visitor& visitor) {
791 VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass.Ptr(), visitor);
Hiroshi Yamauchi2cd334a2015-01-09 14:03:35 -0800792 // Right after a class is allocated, but not yet loaded
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700793 // (kStatusNotReady, see ClassLinker::LoadClass()), GC may find it
Hiroshi Yamauchi2cd334a2015-01-09 14:03:35 -0800794 // and scan it. IsTemp() may call Class::GetAccessFlags() but may
795 // fail in the DCHECK in Class::GetAccessFlags() because the class
796 // status is kStatusNotReady. To avoid it, rely on IsResolved()
797 // only. This is fine because a temp class never goes into the
798 // kStatusResolved state.
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800799 if (IsResolved<kVerifyFlags>()) {
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700800 // Temp classes don't ever populate imt/vtable or static fields and they are not even
Hiroshi Yamauchif4c15a12014-10-20 16:56:58 -0700801 // allocated with the right size for those. Also, unresolved classes don't have fields
802 // linked yet.
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800803 VisitStaticFieldsReferences<kVerifyFlags, kReadBarrierOption>(this, visitor);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700804 }
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800805 if (kVisitNativeRoots) {
806 // Since this class is reachable, we must also visit the associated roots when we scan it.
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -0700807 VisitNativeRoots<kReadBarrierOption>(
808 visitor, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800809 }
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700810}
811
Fred Shih4ee7a662014-07-11 09:59:27 -0700812template<ReadBarrierOption kReadBarrierOption>
813inline bool Class::IsReferenceClass() const {
814 return this == Reference::GetJavaLangRefReference<kReadBarrierOption>();
815}
816
Hiroshi Yamauchi25023c72014-05-09 11:45:53 -0700817template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
818inline bool Class::IsClassClass() {
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700819 ObjPtr<Class> java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
Hiroshi Yamauchi25023c72014-05-09 11:45:53 -0700820 template GetClass<kVerifyFlags, kReadBarrierOption>();
821 return this == java_lang_Class;
822}
823
Mathieu Chartierf8322842014-05-16 10:59:25 -0700824inline const DexFile& Class::GetDexFile() {
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000825 return *GetDexCache()->GetDexFile();
Mathieu Chartierf8322842014-05-16 10:59:25 -0700826}
827
828inline bool Class::DescriptorEquals(const char* match) {
Ian Rogers1ff3c982014-08-12 02:30:58 -0700829 if (IsArrayClass()) {
Mathieu Chartierf8322842014-05-16 10:59:25 -0700830 return match[0] == '[' && GetComponentType()->DescriptorEquals(match + 1);
Ian Rogers1ff3c982014-08-12 02:30:58 -0700831 } else if (IsPrimitive()) {
Mathieu Chartierf8322842014-05-16 10:59:25 -0700832 return strcmp(Primitive::Descriptor(GetPrimitiveType()), match) == 0;
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000833 } else if (IsProxyClass()) {
834 return ProxyDescriptorEquals(match);
Mathieu Chartierf8322842014-05-16 10:59:25 -0700835 } else {
836 const DexFile& dex_file = GetDexFile();
837 const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
838 return strcmp(dex_file.GetTypeDescriptor(type_id), match) == 0;
839 }
840}
841
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200842inline void Class::AssertInitializedOrInitializingInThread(Thread* self) {
843 if (kIsDebugBuild && !IsInitialized()) {
David Sehr709b0702016-10-13 09:12:37 -0700844 CHECK(IsInitializing()) << PrettyClass() << " is not initializing: " << GetStatus();
845 CHECK_EQ(GetClinitThreadId(), self->GetTid()) << PrettyClass()
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200846 << " is initializing in a different thread";
847 }
848}
849
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000850inline ObjectArray<Class>* Class::GetInterfaces() {
851 CHECK(IsProxyClass());
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700852 // First static field.
Mathieu Chartierc7853442015-03-27 14:35:38 -0700853 auto* field = GetStaticField(0);
854 DCHECK_STREQ(field->GetName(), "interfaces");
855 MemberOffset field_offset = field->GetOffset();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000856 return GetFieldObject<ObjectArray<Class>>(field_offset);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700857}
858
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000859inline ObjectArray<ObjectArray<Class>>* Class::GetThrows() {
860 CHECK(IsProxyClass());
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700861 // Second static field.
Mathieu Chartierc7853442015-03-27 14:35:38 -0700862 auto* field = GetStaticField(1);
863 DCHECK_STREQ(field->GetName(), "throws");
864 MemberOffset field_offset = field->GetOffset();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000865 return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700866}
867
Fred Shih4ee7a662014-07-11 09:59:27 -0700868inline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
869 CHECK(IsReferenceClass());
870 // First static field
Mathieu Chartierc7853442015-03-27 14:35:38 -0700871 auto* field = GetStaticField(0);
872 DCHECK_STREQ(field->GetName(), "disableIntrinsic");
873 return field->GetOffset();
Fred Shih4ee7a662014-07-11 09:59:27 -0700874}
875
876inline MemberOffset Class::GetSlowPathFlagOffset() {
877 CHECK(IsReferenceClass());
878 // Second static field
Mathieu Chartierc7853442015-03-27 14:35:38 -0700879 auto* field = GetStaticField(1);
880 DCHECK_STREQ(field->GetName(), "slowPathEnabled");
881 return field->GetOffset();
Fred Shih4ee7a662014-07-11 09:59:27 -0700882}
883
884inline bool Class::GetSlowPathEnabled() {
Fred Shih37f05ef2014-07-16 18:38:08 -0700885 return GetFieldBoolean(GetSlowPathFlagOffset());
Fred Shih4ee7a662014-07-11 09:59:27 -0700886}
887
888inline void Class::SetSlowPath(bool enabled) {
Mathieu Chartier31000802015-06-14 14:14:37 -0700889 SetFieldBoolean<false, false>(GetSlowPathFlagOffset(), enabled);
Fred Shih4ee7a662014-07-11 09:59:27 -0700890}
891
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700892inline void Class::InitializeClassVisitor::operator()(ObjPtr<Object> obj,
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700893 size_t usable_size) const {
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700894 DCHECK_LE(class_size_, usable_size);
895 // Avoid AsClass as object is not yet in live bitmap or allocation stack.
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700896 ObjPtr<Class> klass = ObjPtr<Class>::DownCast(obj);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700897 klass->SetClassSize(class_size_);
898 klass->SetPrimitiveType(Primitive::kPrimNot); // Default to not being primitive.
899 klass->SetDexClassDefIndex(DexFile::kDexNoIndex16); // Default to no valid class def index.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800900 klass->SetDexTypeIndex(dex::TypeIndex(DexFile::kDexNoIndex16)); // Default to no valid type
901 // index.
Mathieu Chartier93bbee02016-08-31 09:38:40 -0700902 // Default to force slow path until initialized.
Mathieu Chartier161db1d2016-09-01 14:06:54 -0700903 klass->SetObjectSizeAllocFastPath(std::numeric_limits<uint32_t>::max());
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700904}
905
Andreas Gampe48498592014-09-10 19:48:05 -0700906inline void Class::SetAccessFlags(uint32_t new_access_flags) {
907 // Called inside a transaction when setting pre-verified flag during boot image compilation.
908 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier52a7f5c2015-08-18 18:35:52 -0700909 SetField32<true>(AccessFlagsOffset(), new_access_flags);
Andreas Gampe48498592014-09-10 19:48:05 -0700910 } else {
Mathieu Chartier52a7f5c2015-08-18 18:35:52 -0700911 SetField32<false>(AccessFlagsOffset(), new_access_flags);
912 }
913}
914
915inline void Class::SetClassFlags(uint32_t new_flags) {
916 if (Runtime::Current()->IsActiveTransaction()) {
917 SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_flags_), new_flags);
918 } else {
919 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_flags_), new_flags);
Andreas Gampe48498592014-09-10 19:48:05 -0700920 }
921}
922
Mathieu Chartier2d2621a2014-10-23 16:48:06 -0700923inline uint32_t Class::NumDirectInterfaces() {
924 if (IsPrimitive()) {
925 return 0;
926 } else if (IsArrayClass()) {
927 return 2;
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000928 } else if (IsProxyClass()) {
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700929 ObjectArray<Class>* interfaces = GetInterfaces();
Mathieu Chartier2d2621a2014-10-23 16:48:06 -0700930 return interfaces != nullptr ? interfaces->GetLength() : 0;
931 } else {
932 const DexFile::TypeList* interfaces = GetInterfaceTypeList();
933 if (interfaces == nullptr) {
934 return 0;
935 } else {
936 return interfaces->Size();
937 }
938 }
939}
940
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -0700941template<ReadBarrierOption kReadBarrierOption, class Visitor>
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700942void Class::VisitNativeRoots(Visitor& visitor, PointerSize pointer_size) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700943 for (ArtField& field : GetSFieldsUnchecked()) {
944 // Visit roots first in case the declaring class gets moved.
945 field.VisitRoots(visitor);
946 if (kIsDebugBuild && IsResolved()) {
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -0700947 CHECK_EQ(field.GetDeclaringClass<kReadBarrierOption>(), this) << GetStatus();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700948 }
Mathieu Chartierc7853442015-03-27 14:35:38 -0700949 }
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700950 for (ArtField& field : GetIFieldsUnchecked()) {
951 // Visit roots first in case the declaring class gets moved.
952 field.VisitRoots(visitor);
953 if (kIsDebugBuild && IsResolved()) {
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -0700954 CHECK_EQ(field.GetDeclaringClass<kReadBarrierOption>(), this) << GetStatus();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700955 }
Mathieu Chartierc7853442015-03-27 14:35:38 -0700956 }
Alex Lighte64300b2015-12-15 15:02:47 -0800957 for (ArtMethod& method : GetMethods(pointer_size)) {
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -0700958 method.VisitRoots<kReadBarrierOption>(visitor, pointer_size);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700959 }
960}
961
Andreas Gampe542451c2016-07-26 09:02:02 -0700962inline IterationRange<StrideIterator<ArtMethod>> Class::GetDirectMethods(PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700963 CheckPointerSize(pointer_size);
Alex Lighte64300b2015-12-15 15:02:47 -0800964 return GetDirectMethodsSliceUnchecked(pointer_size).AsRange();
965}
966
967inline IterationRange<StrideIterator<ArtMethod>> Class::GetDeclaredMethods(
Andreas Gampe542451c2016-07-26 09:02:02 -0700968 PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800969 return GetDeclaredMethodsSliceUnchecked(pointer_size).AsRange();
970}
971
972inline IterationRange<StrideIterator<ArtMethod>> Class::GetDeclaredVirtualMethods(
Andreas Gampe542451c2016-07-26 09:02:02 -0700973 PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800974 return GetDeclaredVirtualMethodsSliceUnchecked(pointer_size).AsRange();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700975}
976
Andreas Gampe542451c2016-07-26 09:02:02 -0700977inline IterationRange<StrideIterator<ArtMethod>> Class::GetVirtualMethods(
978 PointerSize pointer_size) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700979 CheckPointerSize(pointer_size);
Alex Lighte64300b2015-12-15 15:02:47 -0800980 return GetVirtualMethodsSliceUnchecked(pointer_size).AsRange();
981}
982
Andreas Gampe542451c2016-07-26 09:02:02 -0700983inline IterationRange<StrideIterator<ArtMethod>> Class::GetCopiedMethods(PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800984 CheckPointerSize(pointer_size);
985 return GetCopiedMethodsSliceUnchecked(pointer_size).AsRange();
986}
987
988
Andreas Gampe542451c2016-07-26 09:02:02 -0700989inline IterationRange<StrideIterator<ArtMethod>> Class::GetMethods(PointerSize pointer_size) {
Alex Lighte64300b2015-12-15 15:02:47 -0800990 CheckPointerSize(pointer_size);
991 return MakeIterationRangeFromLengthPrefixedArray(GetMethodsPtr(),
Vladimir Marko14632852015-08-17 12:07:23 +0100992 ArtMethod::Size(pointer_size),
993 ArtMethod::Alignment(pointer_size));
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700994}
995
996inline IterationRange<StrideIterator<ArtField>> Class::GetIFields() {
Vladimir Markocf36d492015-08-12 19:27:26 +0100997 return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtr());
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700998}
999
1000inline IterationRange<StrideIterator<ArtField>> Class::GetSFields() {
Vladimir Markocf36d492015-08-12 19:27:26 +01001001 return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtr());
Mathieu Chartier54d220e2015-07-30 16:20:06 -07001002}
1003
1004inline IterationRange<StrideIterator<ArtField>> Class::GetIFieldsUnchecked() {
Vladimir Markocf36d492015-08-12 19:27:26 +01001005 return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtrUnchecked());
Mathieu Chartier54d220e2015-07-30 16:20:06 -07001006}
1007
1008inline IterationRange<StrideIterator<ArtField>> Class::GetSFieldsUnchecked() {
Vladimir Markocf36d492015-08-12 19:27:26 +01001009 return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtrUnchecked());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001010}
1011
Andreas Gampe542451c2016-07-26 09:02:02 -07001012inline MemberOffset Class::EmbeddedVTableOffset(PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07001013 CheckPointerSize(pointer_size);
Andreas Gampe542451c2016-07-26 09:02:02 -07001014 return MemberOffset(ImtPtrOffset(pointer_size).Uint32Value() + static_cast<size_t>(pointer_size));
Mathieu Chartiere401d142015-04-22 13:56:20 -07001015}
1016
Andreas Gampe542451c2016-07-26 09:02:02 -07001017inline void Class::CheckPointerSize(PointerSize pointer_size) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07001018 DCHECK_EQ(pointer_size, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
Mathieu Chartierc7853442015-03-27 14:35:38 -07001019}
1020
Calin Juravle2e768302015-07-28 14:41:11 +00001021template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
1022inline Class* Class::GetComponentType() {
1023 return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(ComponentTypeOffset());
1024}
1025
1026template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
1027inline bool Class::IsArrayClass() {
1028 return GetComponentType<kVerifyFlags, kReadBarrierOption>() != nullptr;
1029}
1030
Mathieu Chartier3398c782016-09-30 10:27:43 -07001031inline bool Class::IsAssignableFrom(ObjPtr<Class> src) {
Calin Juravle2e768302015-07-28 14:41:11 +00001032 DCHECK(src != nullptr);
1033 if (this == src) {
1034 // Can always assign to things of the same type.
1035 return true;
1036 } else if (IsObjectClass()) {
1037 // Can assign any reference to java.lang.Object.
1038 return !src->IsPrimitive();
1039 } else if (IsInterface()) {
1040 return src->Implements(this);
1041 } else if (src->IsArrayClass()) {
1042 return IsAssignableFromArray(src);
1043 } else {
1044 return !src->IsInterface() && src->IsSubClass(this);
1045 }
1046}
1047
Mathieu Chartier54d220e2015-07-30 16:20:06 -07001048inline uint32_t Class::NumDirectMethods() {
Alex Lighte64300b2015-12-15 15:02:47 -08001049 return GetVirtualMethodsStartOffset();
1050}
1051
1052inline uint32_t Class::NumDeclaredVirtualMethods() {
1053 return GetCopiedMethodsStartOffset() - GetVirtualMethodsStartOffset();
Mathieu Chartier54d220e2015-07-30 16:20:06 -07001054}
1055
1056inline uint32_t Class::NumVirtualMethods() {
Alex Lighte64300b2015-12-15 15:02:47 -08001057 return NumMethods() - GetVirtualMethodsStartOffset();
Mathieu Chartier54d220e2015-07-30 16:20:06 -07001058}
1059
1060inline uint32_t Class::NumInstanceFields() {
1061 LengthPrefixedArray<ArtField>* arr = GetIFieldsPtrUnchecked();
Vladimir Marko35831e82015-09-11 11:59:18 +01001062 return arr != nullptr ? arr->size() : 0u;
Mathieu Chartier54d220e2015-07-30 16:20:06 -07001063}
1064
1065inline uint32_t Class::NumStaticFields() {
1066 LengthPrefixedArray<ArtField>* arr = GetSFieldsPtrUnchecked();
Vladimir Marko35831e82015-09-11 11:59:18 +01001067 return arr != nullptr ? arr->size() : 0u;
Mathieu Chartier54d220e2015-07-30 16:20:06 -07001068}
1069
Mathieu Chartierdfe02f62016-02-01 20:15:11 -08001070template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
Mathieu Chartier28bd2e42016-10-04 13:54:57 -07001071inline void Class::FixupNativePointers(Class* dest,
Andreas Gampe542451c2016-07-26 09:02:02 -07001072 PointerSize pointer_size,
Mathieu Chartier4b00d342015-11-13 10:42:08 -08001073 const Visitor& visitor) {
1074 // Update the field arrays.
1075 LengthPrefixedArray<ArtField>* const sfields = GetSFieldsPtr();
1076 LengthPrefixedArray<ArtField>* const new_sfields = visitor(sfields);
1077 if (sfields != new_sfields) {
1078 dest->SetSFieldsPtrUnchecked(new_sfields);
1079 }
1080 LengthPrefixedArray<ArtField>* const ifields = GetIFieldsPtr();
1081 LengthPrefixedArray<ArtField>* const new_ifields = visitor(ifields);
1082 if (ifields != new_ifields) {
1083 dest->SetIFieldsPtrUnchecked(new_ifields);
1084 }
Alex Lighte64300b2015-12-15 15:02:47 -08001085 // Update method array.
1086 LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
1087 LengthPrefixedArray<ArtMethod>* new_methods = visitor(methods);
1088 if (methods != new_methods) {
1089 dest->SetMethodsPtrInternal(new_methods);
Mathieu Chartier4b00d342015-11-13 10:42:08 -08001090 }
Mathieu Chartier4b00d342015-11-13 10:42:08 -08001091 // Fix up embedded tables.
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +00001092 if (!IsTemp() && ShouldHaveEmbeddedVTable<kVerifyNone, kReadBarrierOption>()) {
Mathieu Chartier4b00d342015-11-13 10:42:08 -08001093 for (int32_t i = 0, count = GetEmbeddedVTableLength(); i < count; ++i) {
1094 ArtMethod* method = GetEmbeddedVTableEntry(i, pointer_size);
1095 ArtMethod* new_method = visitor(method);
1096 if (method != new_method) {
1097 dest->SetEmbeddedVTableEntryUnchecked(i, new_method, pointer_size);
1098 }
1099 }
Artem Udovichenkoa62cb9b2016-06-30 09:18:25 +00001100 }
1101 if (!IsTemp() && ShouldHaveImt<kVerifyNone, kReadBarrierOption>()) {
1102 dest->SetImt(visitor(GetImt(pointer_size)), pointer_size);
Mathieu Chartier4b00d342015-11-13 10:42:08 -08001103 }
1104}
1105
Mathieu Chartier3398c782016-09-30 10:27:43 -07001106inline bool Class::CanAccess(ObjPtr<Class> that) {
1107 return that->IsPublic() || this->IsInSamePackage(that);
1108}
1109
1110
1111inline bool Class::CanAccessMember(ObjPtr<Class> access_to, uint32_t member_flags) {
1112 // Classes can access all of their own members
1113 if (this == access_to) {
1114 return true;
1115 }
1116 // Public members are trivially accessible
1117 if (member_flags & kAccPublic) {
1118 return true;
1119 }
1120 // Private members are trivially not accessible
1121 if (member_flags & kAccPrivate) {
1122 return false;
1123 }
1124 // Check for protected access from a sub-class, which may or may not be in the same package.
1125 if (member_flags & kAccProtected) {
1126 if (!this->IsInterface() && this->IsSubClass(access_to)) {
1127 return true;
1128 }
1129 }
1130 // Allow protected access from other classes in the same package.
1131 return this->IsInSamePackage(access_to);
1132}
1133
Mathieu Chartier28bd2e42016-10-04 13:54:57 -07001134inline bool Class::CannotBeAssignedFromOtherTypes() {
1135 if (!IsArrayClass()) {
1136 return IsFinal();
1137 }
1138 ObjPtr<Class> component = GetComponentType();
1139 return component->IsPrimitive() || component->CannotBeAssignedFromOtherTypes();
1140}
1141
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001142} // namespace mirror
1143} // namespace art
1144
Brian Carlstromfc0e3212013-07-17 14:40:12 -07001145#endif // ART_RUNTIME_MIRROR_CLASS_INL_H_