12dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers/*
22dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Copyright (C) 2011 The Android Open Source Project
32dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *
42dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Licensed under the Apache License, Version 2.0 (the "License");
52dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * you may not use this file except in compliance with the License.
62dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * You may obtain a copy of the License at
72dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *
82dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *      http://www.apache.org/licenses/LICENSE-2.0
92dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *
102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Unless required by applicable law or agreed to in writing, software
112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * distributed under the License is distributed on an "AS IS" BASIS,
122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * See the License for the specific language governing permissions and
142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * limitations under the License.
152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers */
162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_MIRROR_CLASS_INL_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_MIRROR_CLASS_INL_H_
192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class.h"
212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
22a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "art_field.h"
23e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method.h"
24e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light#include "base/array_slice.h"
25e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light#include "base/length_prefixed_array.h"
26a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "class_linker-inl.h"
274f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "class_loader.h"
2823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko#include "common_throws.h"
29a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "dex_file-inl.h"
303b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi#include "gc/heap-inl.h"
312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "iftable.h"
3262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "object_array-inl.h"
33c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "object-inl.h"
3498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang#include "read_barrier-inl.h"
354ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih#include "reference-inl.h"
362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "runtime.h"
372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "string.h"
3880afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "utils.h"
392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art {
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4325023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
44ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline uint32_t Class::GetObjectSize() {
453481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko  // Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator.
46709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << "class=" << PrettyTypeOf();
47e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi  return GetField32(ObjectSizeOffset());
482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
50fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
51161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartierinline uint32_t Class::GetObjectSizeAllocFastPath() {
52161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier  // Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator.
53709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << "class=" << PrettyTypeOf();
54161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier  return GetField32(ObjectSizeAllocFastPathOffset());
55161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier}
56161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier
57161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier
58161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
59ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline Class* Class::GetSuperClass() {
602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  // Can only get super class for loaded classes (hack for when runtime is
612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  // initializing)
62fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  DCHECK(IsLoaded<kVerifyFlags>() ||
63fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier         IsErroneous<kVerifyFlags>() ||
64fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier         !Runtime::Current()->IsStarted()) << IsLoaded();
65fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(
66fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier      OFFSET_OF_OBJECT_MEMBER(Class, super_class_));
672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
698ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillaininline void Class::SetSuperClass(ObjPtr<Class> new_super_class) {
708ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain  // Super class is assigned once, except during class linker initialization.
718ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain  if (kIsDebugBuild) {
728ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain    ObjPtr<Class> old_super_class =
738ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain        GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_));
748ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain    DCHECK(old_super_class == nullptr || old_super_class == new_super_class);
758ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain  }
768ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain  DCHECK(new_super_class != nullptr);
778ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), new_super_class);
788ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain}
798ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain
80e51ca8bfa8a193b64901ad214842f213adca92ebNicolas Geoffraytemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
81ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ClassLoader* Class::GetClassLoader() {
82e51ca8bfa8a193b64901ad214842f213adca92ebNicolas Geoffray  return GetFieldObject<ClassLoader, kVerifyFlags, kReadBarrierOption>(
83e51ca8bfa8a193b64901ad214842f213adca92ebNicolas Geoffray      OFFSET_OF_OBJECT_MEMBER(Class, class_loader_));
844f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers}
854f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers
86137cdfa1e8a3810fb86d3298ec10036c0491d13fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
874f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Lightinline ClassExt* Class::GetExtData() {
884f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Light  return GetFieldObject<ClassExt, kVerifyFlags, kReadBarrierOption>(
894f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Light      OFFSET_OF_OBJECT_MEMBER(Class, ext_data_));
904f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Light}
914f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Light
924f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Lighttemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
93ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline DexCache* Class::GetDexCache() {
94137cdfa1e8a3810fb86d3298ec10036c0491d13fMathieu Chartier  return GetFieldObject<DexCache, kVerifyFlags, kReadBarrierOption>(
95137cdfa1e8a3810fb86d3298ec10036c0491d13fMathieu Chartier      OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_));
964f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers}
974f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers
98e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline uint32_t Class::GetCopiedMethodsStartOffset() {
99c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  // Object::GetFieldShort returns an int16_t value, but
100c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  // Class::copied_methods_offset_ is an uint16_t value; cast the
101c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  // latter to int16_t before returning it as an uint32_t value, so
102c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  // that uint16_t values between 2^15 and 2^16-1 are correctly
103c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  // handled.
104c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  return static_cast<uint16_t>(
105c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain      GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, copied_methods_offset_)));
106e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
107e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
108e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline uint32_t Class::GetDirectMethodsStartOffset() {
109e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return 0;
110e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
111e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
112e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline uint32_t Class::GetVirtualMethodsStartOffset() {
113c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  // Object::GetFieldShort returns an int16_t value, but
114c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  // Class::virtual_method_offset_ is an uint16_t value; cast the
115c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  // latter to int16_t before returning it as an uint32_t value, so
116c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  // that uint16_t values between 2^15 and 2^16-1 are correctly
117c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  // handled.
118c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain  return static_cast<uint16_t>(
119c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain      GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_offset_)));
120e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
121e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
122e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags>
123542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDirectMethodsSlice(PointerSize pointer_size) {
1242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  DCHECK(IsLoaded() || IsErroneous());
125e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetDirectMethodsSliceUnchecked(pointer_size);
1262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
128542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDirectMethodsSliceUnchecked(PointerSize pointer_size) {
129e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return ArraySlice<ArtMethod>(GetMethodsPtr(),
130e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               GetDirectMethodsStartOffset(),
131e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               GetVirtualMethodsStartOffset(),
132e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Size(pointer_size),
133e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Alignment(pointer_size));
1346286a97bea0f584342803a215550038852b24776Alex Light}
1356286a97bea0f584342803a215550038852b24776Alex Light
136e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags>
137542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDeclaredMethodsSlice(PointerSize pointer_size) {
138e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  DCHECK(IsLoaded() || IsErroneous());
139e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetDeclaredMethodsSliceUnchecked(pointer_size);
140e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
141e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
142542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDeclaredMethodsSliceUnchecked(PointerSize pointer_size) {
143e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return ArraySlice<ArtMethod>(GetMethodsPtr(),
144e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               GetDirectMethodsStartOffset(),
145e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               GetCopiedMethodsStartOffset(),
146e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Size(pointer_size),
147e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Alignment(pointer_size));
148e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
149e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags>
150542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDeclaredVirtualMethodsSlice(PointerSize pointer_size) {
151e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  DCHECK(IsLoaded() || IsErroneous());
152e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetDeclaredVirtualMethodsSliceUnchecked(pointer_size);
153e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
154e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
155542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDeclaredVirtualMethodsSliceUnchecked(
156542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe    PointerSize pointer_size) {
157e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return ArraySlice<ArtMethod>(GetMethodsPtr(),
158e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               GetVirtualMethodsStartOffset(),
159e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               GetCopiedMethodsStartOffset(),
160e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Size(pointer_size),
161e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Alignment(pointer_size));
162e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
163e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
164e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags>
165542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetVirtualMethodsSlice(PointerSize pointer_size) {
166e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  DCHECK(IsLoaded() || IsErroneous());
167e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetVirtualMethodsSliceUnchecked(pointer_size);
168e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
169e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
170542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetVirtualMethodsSliceUnchecked(PointerSize pointer_size) {
171e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
172e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return ArraySlice<ArtMethod>(methods,
173e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               GetVirtualMethodsStartOffset(),
174e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               NumMethods(),
175e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Size(pointer_size),
176e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Alignment(pointer_size));
177e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
178e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
179e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags>
180542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetCopiedMethodsSlice(PointerSize pointer_size) {
181e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  DCHECK(IsLoaded() || IsErroneous());
182e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetCopiedMethodsSliceUnchecked(pointer_size);
183e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
184e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
185542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetCopiedMethodsSliceUnchecked(PointerSize pointer_size) {
186e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
187e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return ArraySlice<ArtMethod>(methods,
188e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               GetCopiedMethodsStartOffset(),
189e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               NumMethods(),
190e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Size(pointer_size),
191e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Alignment(pointer_size));
192e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
193e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
194e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline LengthPrefixedArray<ArtMethod>* Class::GetMethodsPtr() {
19554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier  return reinterpret_cast<LengthPrefixedArray<ArtMethod>*>(
196f4b3dbad413023795b92a842aad1c3f2fe4a57e9Mathieu Chartier      static_cast<uintptr_t>(GetField64(OFFSET_OF_OBJECT_MEMBER(Class, methods_))));
1972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
199e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags>
200542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetMethodsSlice(PointerSize pointer_size) {
201e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  DCHECK(IsLoaded() || IsErroneous());
202e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
203e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return ArraySlice<ArtMethod>(methods,
204e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               0,
205e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               NumMethods(),
206e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Size(pointer_size),
207e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                               ArtMethod::Alignment(pointer_size));
2082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
210e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
211e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline uint32_t Class::NumMethods() {
212e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
213e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return (methods == nullptr) ? 0 : methods->size();
214e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
215e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
216542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetDirectMethodUnchecked(size_t i, PointerSize pointer_size) {
217e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  CheckPointerSize(pointer_size);
218e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return &GetDirectMethodsSliceUnchecked(pointer_size).At(i);
219e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
220e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
221542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetDirectMethod(size_t i, PointerSize pointer_size) {
222e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  CheckPointerSize(pointer_size);
223e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return &GetDirectMethodsSlice(pointer_size).At(i);
2246286a97bea0f584342803a215550038852b24776Alex Light}
2256286a97bea0f584342803a215550038852b24776Alex Light
226e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline void Class::SetMethodsPtr(LengthPrefixedArray<ArtMethod>* new_methods,
227e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                                 uint32_t num_direct,
228e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                                 uint32_t num_virtual) {
229e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  DCHECK(GetMethodsPtr() == nullptr);
230e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  SetMethodsPtrUnchecked(new_methods, num_direct, num_virtual);
231e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
232e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
233e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
234e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline void Class::SetMethodsPtrUnchecked(LengthPrefixedArray<ArtMethod>* new_methods,
235e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                                          uint32_t num_direct,
236e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                                          uint32_t num_virtual) {
237e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  DCHECK_LE(num_direct + num_virtual, (new_methods == nullptr) ? 0 : new_methods->size());
238e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  SetMethodsPtrInternal(new_methods);
239e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  SetFieldShort<false>(OFFSET_OF_OBJECT_MEMBER(Class, copied_methods_offset_),
240e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                    dchecked_integral_cast<uint16_t>(num_direct + num_virtual));
241e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  SetFieldShort<false>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_offset_),
242e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light                       dchecked_integral_cast<uint16_t>(num_direct));
2432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
245e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline void Class::SetMethodsPtrInternal(LengthPrefixedArray<ArtMethod>* new_methods) {
246e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, methods_),
247f4b3dbad413023795b92a842aad1c3f2fe4a57e9Mathieu Chartier                    static_cast<uint64_t>(reinterpret_cast<uintptr_t>(new_methods)));
2482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
251542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetVirtualMethod(size_t i, PointerSize pointer_size) {
252e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  CheckPointerSize(pointer_size);
253f4c15a18eb055735857a280856be5b142e0c1113Hiroshi Yamauchi  DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>())
254709b070044354d9f47641f273edacaeeb0240ab7David Sehr      << Class::PrettyClass() << " status=" << GetStatus();
255e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return GetVirtualMethodUnchecked(i, pointer_size);
2562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
258542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetVirtualMethodDuringLinking(size_t i, PointerSize pointer_size) {
259e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  CheckPointerSize(pointer_size);
2602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  DCHECK(IsLoaded() || IsErroneous());
261e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return GetVirtualMethodUnchecked(i, pointer_size);
2622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
264542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetVirtualMethodUnchecked(size_t i, PointerSize pointer_size) {
265e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  CheckPointerSize(pointer_size);
266e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return &GetVirtualMethodsSliceUnchecked(pointer_size).At(i);
2672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
269fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags,
270fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier         ReadBarrierOption kReadBarrierOption>
271e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline PointerArray* Class::GetVTable() {
272063fc772b5b8aed7d769cd7cccb6ddc7619326eeMingyao Yang  DCHECK(IsLoaded<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
273fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(
274fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier      OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
2752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
277e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline PointerArray* Class::GetVTableDuringLinking() {
2782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  DCHECK(IsLoaded() || IsErroneous());
279e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return GetFieldObject<PointerArray>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
2802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
282e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline void Class::SetVTable(PointerArray* new_vtable) {
283b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable);
2842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2862cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline bool Class::HasVTable() {
287a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko  return GetVTable() != nullptr || ShouldHaveEmbeddedVTable();
2882cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang}
2892cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang
2902cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline int32_t Class::GetVTableLength() {
291a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko  if (ShouldHaveEmbeddedVTable()) {
2922cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang    return GetEmbeddedVTableLength();
2932cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang  }
294e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return GetVTable() != nullptr ? GetVTable()->GetLength() : 0;
2952cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang}
2962cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang
297542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetVTableEntry(uint32_t i, PointerSize pointer_size) {
298a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko  if (ShouldHaveEmbeddedVTable()) {
299e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    return GetEmbeddedVTableEntry(i, pointer_size);
3002cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang  }
301e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  auto* vtable = GetVTable();
302e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  DCHECK(vtable != nullptr);
303e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return vtable->GetElementPtrSize<ArtMethod*>(i, pointer_size);
3042cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang}
3052cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang
3062cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline int32_t Class::GetEmbeddedVTableLength() {
307e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return GetField32(MemberOffset(EmbeddedVTableLengthOffset()));
3082cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang}
3092cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang
3102cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline void Class::SetEmbeddedVTableLength(int32_t len) {
311e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  SetField32<false>(MemberOffset(EmbeddedVTableLengthOffset()), len);
3122cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang}
3132cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang
314542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ImTable* Class::GetImt(PointerSize pointer_size) {
315a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko  return GetFieldPtrWithSize<ImTable*>(MemberOffset(ImtPtrOffset(pointer_size)), pointer_size);
316a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko}
317a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko
318542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline void Class::SetImt(ImTable* imt, PointerSize pointer_size) {
319a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko  return SetFieldPtrWithSize<false>(MemberOffset(ImtPtrOffset(pointer_size)), imt, pointer_size);
320a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko}
321a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko
322542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline MemberOffset Class::EmbeddedVTableEntryOffset(uint32_t i, PointerSize pointer_size) {
323e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return MemberOffset(
324e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier      EmbeddedVTableOffset(pointer_size).Uint32Value() + i * VTableEntrySize(pointer_size));
3252cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang}
3262cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang
327542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetEmbeddedVTableEntry(uint32_t i, PointerSize pointer_size) {
328e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return GetFieldPtrWithSize<ArtMethod*>(EmbeddedVTableEntryOffset(i, pointer_size), pointer_size);
329e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
330e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
331e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline void Class::SetEmbeddedVTableEntryUnchecked(
332542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe    uint32_t i, ArtMethod* method, PointerSize pointer_size) {
333e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  SetFieldPtrWithSize<false>(EmbeddedVTableEntryOffset(i, pointer_size), method, pointer_size);
334e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
335e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
336542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline void Class::SetEmbeddedVTableEntry(uint32_t i, ArtMethod* method, PointerSize pointer_size) {
337e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  auto* vtable = GetVTableDuringLinking();
338e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  CHECK_EQ(method, vtable->GetElementPtrSize<ArtMethod*>(i, pointer_size));
339e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  SetEmbeddedVTableEntryUnchecked(i, method, pointer_size);
34098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang}
34198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang
34228bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline bool Class::Implements(ObjPtr<Class> klass) {
3432cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(klass != nullptr);
344709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK(klass->IsInterface()) << PrettyClass();
345693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  // All interfaces implemented directly and by our superclass, and
346693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  // recursively all super-interfaces of those interfaces, are listed
347693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  // in iftable_, so we can just do a linear scan through that.
348693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  int32_t iftable_count = GetIfTableCount();
34928bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  ObjPtr<IfTable> iftable = GetIfTable();
350693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  for (int32_t i = 0; i < iftable_count; i++) {
351693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    if (iftable->GetInterface(i) == klass) {
352693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers      return true;
353693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    }
354693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  }
355693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  return false;
356693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers}
357693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
358c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampetemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
359c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampeinline bool Class::IsVariableSize() {
360c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe  // Classes, arrays, and strings vary in size, and so the object_size_ field cannot
361c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe  // be used to Get their instance size
362c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe  return IsClassClass<kVerifyFlags, kReadBarrierOption>() ||
363c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe         IsArrayClass<kVerifyFlags, kReadBarrierOption>() ||
364c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe         IsStringClass();
365c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe}
366c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe
367c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampeinline void Class::SetObjectSize(uint32_t new_object_size) {
368c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe  DCHECK(!IsVariableSize());
369c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe  // Not called within a transaction.
370c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe  return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, object_size_), new_object_size);
371c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe}
372c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe
373693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Determine whether "this" is assignable from "src", where both of these
374693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// are array classes.
375693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//
376693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Consider an array class, e.g. Y[][], where Y is a subclass of X.
377693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   Y[][]            = Y[][] --> true (identity)
378693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   X[][]            = Y[][] --> true (element superclass)
379693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   Y                = Y[][] --> false
380693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   Y[]              = Y[][] --> false
381693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   Object           = Y[][] --> true (everything is an object)
382693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   Object[]         = Y[][] --> true
383693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   Object[][]       = Y[][] --> true
384693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   Object[][][]     = Y[][] --> false (too many []s)
385693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   Serializable     = Y[][] --> true (all arrays are Serializable)
386693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   Serializable[]   = Y[][] --> true
387693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   Serializable[][] = Y[][] --> false (unless Y is Serializable)
388693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//
389693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Don't forget about primitive types.
390693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//   Object[]         = int[] --> false
391693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers//
3923398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::IsArrayAssignableFromArray(ObjPtr<Class> src) {
393709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK(IsArrayClass())  << PrettyClass();
394709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK(src->IsArrayClass()) << src->PrettyClass();
395693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  return GetComponentType()->IsAssignableFrom(src->GetComponentType());
396693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers}
397693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
3983398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::IsAssignableFromArray(ObjPtr<Class> src) {
399709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK(!IsInterface()) << PrettyClass();  // handled first in IsAssignableFrom
400709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK(src->IsArrayClass()) << src->PrettyClass();
401693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  if (!IsArrayClass()) {
402693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    // If "this" is not also an array, it must be Object.
403693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    // src's super should be java_lang_Object, since it is an array.
40428bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier    ObjPtr<Class> java_lang_Object = src->GetSuperClass();
405709b070044354d9f47641f273edacaeeb0240ab7David Sehr    DCHECK(java_lang_Object != nullptr) << src->PrettyClass();
406709b070044354d9f47641f273edacaeeb0240ab7David Sehr    DCHECK(java_lang_Object->GetSuperClass() == nullptr) << src->PrettyClass();
407693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    return this == java_lang_Object;
408693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  }
409693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  return IsArrayAssignableFromArray(src);
410693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers}
411693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
41289786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markotemplate <bool throw_on_failure, bool use_referrers_cache>
413b890130a66e167404a9a60cf0893a015538778caMathieu Chartierinline bool Class::ResolvedFieldAccessTest(ObjPtr<Class> access_to,
4143398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier                                           ArtField* field,
4153398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier                                           uint32_t field_idx,
416b890130a66e167404a9a60cf0893a015538778caMathieu Chartier                                           ObjPtr<DexCache> dex_cache) {
41789786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko  DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
41823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  if (UNLIKELY(!this->CanAccess(access_to))) {
41923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    // The referrer class can't access the field's declaring class but may still be able
42023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    // to access the field if the FieldId specifies an accessible subclass of the declaring
42123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    // class rather than the declaring class itself.
422b890130a66e167404a9a60cf0893a015538778caMathieu Chartier    ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
423a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe    dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_;
424279ac5c060a1a642c786730e3f2b05d556c00839Mathieu Chartier    // The referenced class has already been resolved with the field, but may not be in the dex
425b890130a66e167404a9a60cf0893a015538778caMathieu Chartier    // cache. Use LookupResolveType here to search the class table if it is not in the dex cache.
426279ac5c060a1a642c786730e3f2b05d556c00839Mathieu Chartier    // should be no thread suspension due to the class being resolved.
427b890130a66e167404a9a60cf0893a015538778caMathieu Chartier    ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType(
428b890130a66e167404a9a60cf0893a015538778caMathieu Chartier        *referrer_dex_cache->GetDexFile(),
429b890130a66e167404a9a60cf0893a015538778caMathieu Chartier        class_idx,
430b890130a66e167404a9a60cf0893a015538778caMathieu Chartier        referrer_dex_cache,
431b890130a66e167404a9a60cf0893a015538778caMathieu Chartier        access_to->GetClassLoader());
43223a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    DCHECK(dex_access_to != nullptr);
43323a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    if (UNLIKELY(!this->CanAccess(dex_access_to))) {
43423a282146042a0d171aec2a415176f5d0621a90cVladimir Marko      if (throw_on_failure) {
4356b3d12b3d233734bb6669faccddcba7abeb5ea99Mathieu Chartier        ThrowIllegalAccessErrorClass(this, dex_access_to);
43623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko      }
43723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko      return false;
43823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    }
43923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  }
44023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  if (LIKELY(this->CanAccessMember(access_to, field->GetAccessFlags()))) {
44123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    return true;
44223a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  }
44323a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  if (throw_on_failure) {
44423a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    ThrowIllegalAccessErrorField(this, field);
44523a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  }
44623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  return false;
44723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko}
44823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko
44989786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markotemplate <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type>
450b890130a66e167404a9a60cf0893a015538778caMathieu Chartierinline bool Class::ResolvedMethodAccessTest(ObjPtr<Class> access_to,
451b890130a66e167404a9a60cf0893a015538778caMathieu Chartier                                            ArtMethod* method,
452b890130a66e167404a9a60cf0893a015538778caMathieu Chartier                                            uint32_t method_idx,
453b890130a66e167404a9a60cf0893a015538778caMathieu Chartier                                            ObjPtr<DexCache> dex_cache) {
454575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe  static_assert(throw_on_failure || throw_invoke_type == kStatic, "Non-default throw invoke type");
45589786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko  DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
45623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  if (UNLIKELY(!this->CanAccess(access_to))) {
45723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    // The referrer class can't access the method's declaring class but may still be able
45823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    // to access the method if the MethodId specifies an accessible subclass of the declaring
45923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    // class rather than the declaring class itself.
460b890130a66e167404a9a60cf0893a015538778caMathieu Chartier    ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
461a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe    dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
462279ac5c060a1a642c786730e3f2b05d556c00839Mathieu Chartier    // The referenced class has already been resolved with the method, but may not be in the dex
463b890130a66e167404a9a60cf0893a015538778caMathieu Chartier    // cache.
464b890130a66e167404a9a60cf0893a015538778caMathieu Chartier    ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType(
465b890130a66e167404a9a60cf0893a015538778caMathieu Chartier        *referrer_dex_cache->GetDexFile(),
466b890130a66e167404a9a60cf0893a015538778caMathieu Chartier        class_idx,
467b890130a66e167404a9a60cf0893a015538778caMathieu Chartier        referrer_dex_cache,
468b890130a66e167404a9a60cf0893a015538778caMathieu Chartier        access_to->GetClassLoader());
46923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    DCHECK(dex_access_to != nullptr);
47023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    if (UNLIKELY(!this->CanAccess(dex_access_to))) {
47123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko      if (throw_on_failure) {
472b890130a66e167404a9a60cf0893a015538778caMathieu Chartier        ThrowIllegalAccessErrorClassForMethodDispatch(this,
4731cc62e4ea24828fdb3f3da0b8603f0b107d09a04Mathieu Chartier                                                      dex_access_to.Ptr(),
474b890130a66e167404a9a60cf0893a015538778caMathieu Chartier                                                      method,
475b890130a66e167404a9a60cf0893a015538778caMathieu Chartier                                                      throw_invoke_type);
47623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko      }
47723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko      return false;
47823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    }
47923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  }
48023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  if (LIKELY(this->CanAccessMember(access_to, method->GetAccessFlags()))) {
48123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    return true;
48223a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  }
48323a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  if (throw_on_failure) {
48423a282146042a0d171aec2a415176f5d0621a90cVladimir Marko    ThrowIllegalAccessErrorMethod(this, method);
48523a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  }
48623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko  return false;
48723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko}
48823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko
4893398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::CanAccessResolvedField(ObjPtr<Class> access_to,
4903398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier                                          ArtField* field,
4913398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier                                          ObjPtr<DexCache> dex_cache,
4923398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier                                          uint32_t field_idx) {
493b890130a66e167404a9a60cf0893a015538778caMathieu Chartier  return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, dex_cache);
49489786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko}
49589786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko
4963398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::CheckResolvedFieldAccess(ObjPtr<Class> access_to,
4973398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier                                            ArtField* field,
49889786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko                                            uint32_t field_idx) {
499f8ac97f94aad9ce2d324c2c7c21dde3abf13315bMathieu Chartier  return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr);
50089786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko}
50189786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko
50228bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline bool Class::CanAccessResolvedMethod(ObjPtr<Class> access_to,
50328bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier                                           ArtMethod* method,
50428bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier                                           ObjPtr<DexCache> dex_cache,
50528bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier                                           uint32_t method_idx) {
506ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return ResolvedMethodAccessTest<false, false, kStatic>(access_to, method, method_idx, dex_cache);
50789786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko}
50889786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko
50989786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markotemplate <InvokeType throw_invoke_type>
51028bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline bool Class::CheckResolvedMethodAccess(ObjPtr<Class> access_to,
51128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier                                             ArtMethod* method,
51289786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko                                             uint32_t method_idx) {
51328bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  return ResolvedMethodAccessTest<true, true, throw_invoke_type>(access_to,
51428bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier                                                                 method,
51528bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier                                                                 method_idx,
51689786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko                                                                 nullptr);
51789786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko}
51889786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko
5193398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::IsSubClass(ObjPtr<Class> klass) {
520709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK(!IsInterface()) << PrettyClass();
521709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK(!IsArrayClass()) << PrettyClass();
5223398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  ObjPtr<Class> current = this;
523693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  do {
524693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    if (current == klass) {
525693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers      return true;
526693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    }
527693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    current = current->GetSuperClass();
5282cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  } while (current != nullptr);
529693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  return false;
530693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers}
531693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
532542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::FindVirtualMethodForInterface(ArtMethod* method,
533542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe                                                       PointerSize pointer_size) {
53428bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  ObjPtr<Class> declaring_class = method->GetDeclaringClass();
535709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK(declaring_class != nullptr) << PrettyClass();
536709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK(declaring_class->IsInterface()) << method->PrettyMethod();
5370f7e8f59698265d416d40844233bb09d02e7fc33Alex Light  DCHECK(!method->IsCopied());
538693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  // TODO cache to improve lookup speed
539e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  const int32_t iftable_count = GetIfTableCount();
54028bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  ObjPtr<IfTable> iftable = GetIfTable();
541693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  for (int32_t i = 0; i < iftable_count; i++) {
542693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    if (iftable->GetInterface(i) == declaring_class) {
543e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier      return iftable->GetMethodArray(i)->GetElementPtrSize<ArtMethod*>(
544e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier          method->GetMethodIndex(), pointer_size);
545693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers    }
546693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers  }
5472cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  return nullptr;
548693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers}
549693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers
550542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::FindVirtualMethodForVirtual(ArtMethod* method, PointerSize pointer_size) {
551eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light  // Only miranda or default methods may come from interfaces and be used as a virtual.
552eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light  DCHECK(!method->GetDeclaringClass()->IsInterface() || method->IsDefault() || method->IsMiranda());
5532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  // The argument method may from a super class.
5542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  // Use the index to a potentially overridden one for this instance's class.
555e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return GetVTableEntry(method->GetMethodIndex(), pointer_size);
5562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
5572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
558542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::FindVirtualMethodForSuper(ArtMethod* method, PointerSize pointer_size) {
5592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  DCHECK(!method->GetDeclaringClass()->IsInterface());
560e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return GetSuperClass()->GetVTableEntry(method->GetMethodIndex(), pointer_size);
5612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
5622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
563e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::FindVirtualMethodForVirtualOrInterface(ArtMethod* method,
564542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe                                                                PointerSize pointer_size) {
5652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  if (method->IsDirect()) {
5662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return method;
5672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
5683612149aee482ab7a17da68b0ef5fef3879729a2Alex Light  if (method->GetDeclaringClass()->IsInterface() && !method->IsCopied()) {
569e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    return FindVirtualMethodForInterface(method, pointer_size);
5702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
571e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return FindVirtualMethodForVirtual(method, pointer_size);
5722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
5732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
574fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags,
575fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier         ReadBarrierOption kReadBarrierOption>
576ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline IfTable* Class::GetIfTable() {
5776beced4c017826f7c449f12fac7fa42403657f2bMathieu Chartier  ObjPtr<IfTable> ret = GetFieldObject<IfTable, kVerifyFlags, kReadBarrierOption>(IfTableOffset());
5786beced4c017826f7c449f12fac7fa42403657f2bMathieu Chartier  DCHECK(ret != nullptr) << PrettyClass(this);
5796beced4c017826f7c449f12fac7fa42403657f2bMathieu Chartier  return ret.Ptr();
5802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
5812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
582ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline int32_t Class::GetIfTableCount() {
5836beced4c017826f7c449f12fac7fa42403657f2bMathieu Chartier  return GetIfTable()->Count();
5842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
5852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
58628bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline void Class::SetIfTable(ObjPtr<IfTable> new_iftable) {
5876beced4c017826f7c449f12fac7fa42403657f2bMathieu Chartier  DCHECK(new_iftable != nullptr) << PrettyClass(this);
5882ecfd270adb29861b493de51cfb8670e276e0c5eMathieu Chartier  SetFieldObject<false>(IfTableOffset(), new_iftable);
5892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
5902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
59154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtr() {
592fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
59354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier  return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
5942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
5952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
5965496f69c0a4c2cc357a065f57b7f4ff5d9ad2fa9Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
59776649e8d775519fe19f2b14d18ac488c13296054Vladimir Markoinline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() {
59828bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  ObjPtr<Class> super_class = GetSuperClass<kVerifyFlags, kReadBarrierOption>();
59976649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko  return (super_class != nullptr)
6007a62e6728463237684d3d9834d81bd7bba7ab197Hiroshi Yamauchi      ? MemberOffset(RoundUp(super_class->GetObjectSize<kVerifyFlags, kReadBarrierOption>(),
60128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier                             kHeapReferenceSize))
60276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko      : ClassOffset();
60376649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko}
60476649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko
605dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
606542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline MemberOffset Class::GetFirstReferenceStaticFieldOffset(PointerSize pointer_size) {
60776649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko  DCHECK(IsResolved());
60828bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  uint32_t base = sizeof(Class);  // Static fields come after the class.
609a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko  if (ShouldHaveEmbeddedVTable<kVerifyFlags, kReadBarrierOption>()) {
61076649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko    // Static fields come after the embedded tables.
61128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier    base = Class::ComputeClassSize(
612e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier        true, GetEmbeddedVTableLength(), 0, 0, 0, 0, 0, pointer_size);
61376649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko  }
61476649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko  return MemberOffset(base);
61576649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko}
61676649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko
617542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline MemberOffset Class::GetFirstReferenceStaticFieldOffsetDuringLinking(
618542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe    PointerSize pointer_size) {
61976649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko  DCHECK(IsLoaded());
62028bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  uint32_t base = sizeof(Class);  // Static fields come after the class.
621a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko  if (ShouldHaveEmbeddedVTable()) {
62276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko    // Static fields come after the embedded tables.
62328bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier    base = Class::ComputeClassSize(true, GetVTableDuringLinking()->GetLength(),
624e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                                           0, 0, 0, 0, 0, pointer_size);
62576649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko  }
62676649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko  return MemberOffset(base);
62776649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko}
62876649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko
62954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetIFieldsPtr(LengthPrefixedArray<ArtField>* new_ifields) {
63054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier  DCHECK(GetIFieldsPtrUnchecked() == nullptr);
631c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
6322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
63454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetIFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_ifields) {
635c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
6362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
63854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtrUnchecked() {
63954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier  return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
6402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
64254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtrUnchecked() {
64354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier  return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
6442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
64654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtr() {
647c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
64854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier  return GetSFieldsPtrUnchecked();
6492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
65154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetSFieldsPtr(LengthPrefixedArray<ArtField>* new_sfields) {
652c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  DCHECK((IsRetired() && new_sfields == nullptr) ||
653c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier         GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)) == nullptr);
654c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
6552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
65754d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetSFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_sfields) {
658c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
6592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
661c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierinline ArtField* Class::GetStaticField(uint32_t i) {
66254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier  return &GetSFieldsPtr()->At(i);
6632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
665c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierinline ArtField* Class::GetInstanceField(uint32_t i) {
66654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier  return &GetIFieldsPtr()->At(i);
6672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
669b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags>
670b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline uint32_t Class::GetReferenceInstanceOffsets() {
671b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
672b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_));
673b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
674b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
675b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Class::SetClinitThreadId(pid_t new_clinit_thread_id) {
676b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (Runtime::Current()->IsActiveTransaction()) {
677b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
678b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  } else {
679b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
680b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
681b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
682b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
683ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline String* Class::GetName() {
684b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(Class, name_));
6852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
68652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier
6871a5337fff2cc6cb9d563c8b32aca75f485d23373Mathieu Chartierinline void Class::SetName(ObjPtr<String> name) {
688d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (Runtime::Current()->IsActiveTransaction()) {
689b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
690d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  } else {
691b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
692d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
6932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
695b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags>
696b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline Primitive::Type Class::GetPrimitiveType() {
69733d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain  static_assert(sizeof(Primitive::Type) == sizeof(int32_t),
69833d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain                "art::Primitive::Type and int32_t have different sizes.");
699f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi  int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_));
7008261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier  Primitive::Type type = static_cast<Primitive::Type>(v32 & kPrimitiveTypeMask);
7018261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier  DCHECK_EQ(static_cast<size_t>(v32 >> kPrimitiveTypeSizeShiftShift),
7028261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier            Primitive::ComponentSizeShift(type));
703f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi  return type;
704f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi}
705f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi
706f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags>
707f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchiinline size_t Class::GetPrimitiveTypeSizeShift() {
70833d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain  static_assert(sizeof(Primitive::Type) == sizeof(int32_t),
70933d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain                "art::Primitive::Type and int32_t have different sizes.");
710f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi  int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_));
7118261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier  size_t size_shift = static_cast<Primitive::Type>(v32 >> kPrimitiveTypeSizeShiftShift);
7128261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier  DCHECK_EQ(size_shift,
7138261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier            Primitive::ComponentSizeShift(static_cast<Primitive::Type>(v32 & kPrimitiveTypeMask)));
714f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi  return size_shift;
715b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
716b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
7173b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchiinline void Class::CheckObjectAlloc() {
7184cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi  DCHECK(!IsArrayClass())
719709b070044354d9f47641f273edacaeeb0240ab7David Sehr      << PrettyClass()
7204cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi      << "A array shouldn't be allocated through this "
7214cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi      << "as it requires a pre-fence visitor that sets the class size.";
7224cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi  DCHECK(!IsClassClass())
723709b070044354d9f47641f273edacaeeb0240ab7David Sehr      << PrettyClass()
7244cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi      << "A class object shouldn't be allocated through this "
7254cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi      << "as it requires a pre-fence visitor that sets the class size.";
726848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  DCHECK(!IsStringClass())
727709b070044354d9f47641f273edacaeeb0240ab7David Sehr      << PrettyClass()
728848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      << "A string shouldn't be allocated through this "
729848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      << "as it requires a pre-fence visitor that sets the class size.";
730709b070044354d9f47641f273edacaeeb0240ab7David Sehr  DCHECK(IsInstantiable()) << PrettyClass();
731967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  // TODO: decide whether we want this check. It currently fails during bootstrap.
732709b070044354d9f47641f273edacaeeb0240ab7David Sehr  // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass();
733967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  DCHECK_GE(this->object_size_, sizeof(Object));
7343b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi}
7353b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi
7368668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartiertemplate<bool kIsInstrumented, bool kCheckAddFinalizer>
73728bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline ObjPtr<Object> Class::Alloc(Thread* self, gc::AllocatorType allocator_type) {
7383b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  CheckObjectAlloc();
739590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  gc::Heap* heap = Runtime::Current()->GetHeap();
7408668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier  const bool add_finalizer = kCheckAddFinalizer && IsFinalizable();
7418668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier  if (!kCheckAddFinalizer) {
7428668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier    DCHECK(!IsFinalizable());
7438668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier  }
7449d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier  // Note that the this pointer may be invalidated after the allocation.
74528bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  ObjPtr<Object> obj =
7469d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier      heap->AllocObjectWithAllocator<kIsInstrumented, false>(self,
7479d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier                                                             this,
7489d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier                                                             this->object_size_,
7499d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier                                                             allocator_type,
7509d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier                                                             VoidFunctor());
7518668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier  if (add_finalizer && LIKELY(obj != nullptr)) {
7528668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier    heap->AddFinalizerReference(self, &obj);
7533ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski    if (UNLIKELY(self->IsExceptionPending())) {
7543ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski      // Failed to allocate finalizer reference, it means that the whole allocation failed.
7553ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski      obj = nullptr;
7563ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski    }
7578668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier  }
7589d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier  return obj.Ptr();
759cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier}
760cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier
76128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline ObjPtr<Object> Class::AllocObject(Thread* self) {
762cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier  return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentAllocator());
763cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier}
764cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier
76528bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline ObjPtr<Object> Class::AllocNonMovableObject(Thread* self) {
766cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier  return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator());
767967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi}
768967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi
769a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenkoinline uint32_t Class::ComputeClassSize(bool has_embedded_vtable,
77098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang                                        uint32_t num_vtable_entries,
77137f05ef45e0393de812d51261dc293240c17294dFred Shih                                        uint32_t num_8bit_static_fields,
77237f05ef45e0393de812d51261dc293240c17294dFred Shih                                        uint32_t num_16bit_static_fields,
77398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang                                        uint32_t num_32bit_static_fields,
77498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang                                        uint32_t num_64bit_static_fields,
775e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                                        uint32_t num_ref_static_fields,
776542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe                                        PointerSize pointer_size) {
77798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  // Space used by java.lang.Class and its instance fields.
77898d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  uint32_t size = sizeof(Class);
77998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  // Space used by embedded tables.
780a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko  if (has_embedded_vtable) {
781542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe    size = RoundUp(size + sizeof(uint32_t), static_cast<size_t>(pointer_size));
782542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe    size += static_cast<size_t>(pointer_size);  // size of pointer to IMT
783a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko    size += num_vtable_entries * VTableEntrySize(pointer_size);
78498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  }
78537f05ef45e0393de812d51261dc293240c17294dFred Shih
78698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  // Space used by reference statics.
78728bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  size += num_ref_static_fields * kHeapReferenceSize;
78837f05ef45e0393de812d51261dc293240c17294dFred Shih  if (!IsAligned<8>(size) && num_64bit_static_fields > 0) {
78937f05ef45e0393de812d51261dc293240c17294dFred Shih    uint32_t gap = 8 - (size & 0x7);
79037f05ef45e0393de812d51261dc293240c17294dFred Shih    size += gap;  // will be padded
79137f05ef45e0393de812d51261dc293240c17294dFred Shih    // Shuffle 4-byte fields forward.
79237f05ef45e0393de812d51261dc293240c17294dFred Shih    while (gap >= sizeof(uint32_t) && num_32bit_static_fields != 0) {
79337f05ef45e0393de812d51261dc293240c17294dFred Shih      --num_32bit_static_fields;
79437f05ef45e0393de812d51261dc293240c17294dFred Shih      gap -= sizeof(uint32_t);
79537f05ef45e0393de812d51261dc293240c17294dFred Shih    }
79637f05ef45e0393de812d51261dc293240c17294dFred Shih    // Shuffle 2-byte fields forward.
79737f05ef45e0393de812d51261dc293240c17294dFred Shih    while (gap >= sizeof(uint16_t) && num_16bit_static_fields != 0) {
79837f05ef45e0393de812d51261dc293240c17294dFred Shih      --num_16bit_static_fields;
79937f05ef45e0393de812d51261dc293240c17294dFred Shih      gap -= sizeof(uint16_t);
80037f05ef45e0393de812d51261dc293240c17294dFred Shih    }
80137f05ef45e0393de812d51261dc293240c17294dFred Shih    // Shuffle byte fields forward.
80237f05ef45e0393de812d51261dc293240c17294dFred Shih    while (gap >= sizeof(uint8_t) && num_8bit_static_fields != 0) {
80337f05ef45e0393de812d51261dc293240c17294dFred Shih      --num_8bit_static_fields;
80437f05ef45e0393de812d51261dc293240c17294dFred Shih      gap -= sizeof(uint8_t);
8052cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang    }
80698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  }
80737f05ef45e0393de812d51261dc293240c17294dFred Shih  // Guaranteed to be at least 4 byte aligned. No need for further alignments.
80898d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  // Space used for primitive static fields.
809e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  size += num_8bit_static_fields * sizeof(uint8_t) + num_16bit_static_fields * sizeof(uint16_t) +
810e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier      num_32bit_static_fields * sizeof(uint32_t) + num_64bit_static_fields * sizeof(uint64_t);
81198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  return size;
81298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang}
81398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang
8144f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5Hiroshi Yamauchitemplate<ReadBarrierOption kReadBarrierOption>
8154ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline bool Class::IsReferenceClass() const {
8164ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  return this == Reference::GetJavaLangRefReference<kReadBarrierOption>();
8174ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih}
8184ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih
81925023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
82025023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchiinline bool Class::IsClassClass() {
82128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  ObjPtr<Class> java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
82225023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi      template GetClass<kVerifyFlags, kReadBarrierOption>();
82325023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi  return this == java_lang_Class;
82425023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi}
82525023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi
826f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartierinline const DexFile& Class::GetDexFile() {
827bc632f05acd06f9000e67517fdeb8296f739e079Mathieu Chartier  // From-space version is the same as the to-space version since the dex file never changes.
828bc632f05acd06f9000e67517fdeb8296f739e079Mathieu Chartier  // Avoiding the read barrier here is important to prevent recursive AssertToSpaceInvariant issues
829bc632f05acd06f9000e67517fdeb8296f739e079Mathieu Chartier  // from PrettyTypeOf.
830bc632f05acd06f9000e67517fdeb8296f739e079Mathieu Chartier  return *GetDexCache<kDefaultVerifyFlags, kWithoutReadBarrier>()->GetDexFile();
831f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier}
832f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier
833f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartierinline bool Class::DescriptorEquals(const char* match) {
8341ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers  if (IsArrayClass()) {
835f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier    return match[0] == '[' && GetComponentType()->DescriptorEquals(match + 1);
8361ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers  } else if (IsPrimitive()) {
837f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier    return strcmp(Primitive::Descriptor(GetPrimitiveType()), match) == 0;
8383a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray  } else if (IsProxyClass()) {
8393a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray    return ProxyDescriptorEquals(match);
840f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier  } else {
841f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier    const DexFile& dex_file = GetDexFile();
842f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier    const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
843f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier    return strcmp(dex_file.GetTypeDescriptor(type_id), match) == 0;
844f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier  }
845f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier}
846f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier
8474e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertzinline void Class::AssertInitializedOrInitializingInThread(Thread* self) {
8484e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz  if (kIsDebugBuild && !IsInitialized()) {
849709b070044354d9f47641f273edacaeeb0240ab7David Sehr    CHECK(IsInitializing()) << PrettyClass() << " is not initializing: " << GetStatus();
850709b070044354d9f47641f273edacaeeb0240ab7David Sehr    CHECK_EQ(GetClinitThreadId(), self->GetTid()) << PrettyClass()
8514e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz                                                  << " is initializing in a different thread";
8524e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz  }
8534e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz}
8544e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz
8556b2dc3156a2140a5bfd9cbbf5d7dad332ab5f5bdNarayan Kamathinline ObjectArray<Class>* Class::GetProxyInterfaces() {
8563a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray  CHECK(IsProxyClass());
85798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  // First static field.
858c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  auto* field = GetStaticField(0);
859c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  DCHECK_STREQ(field->GetName(), "interfaces");
860c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  MemberOffset field_offset = field->GetOffset();
8613a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray  return GetFieldObject<ObjectArray<Class>>(field_offset);
86298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang}
86398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang
8646b2dc3156a2140a5bfd9cbbf5d7dad332ab5f5bdNarayan Kamathinline ObjectArray<ObjectArray<Class>>* Class::GetProxyThrows() {
8653a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray  CHECK(IsProxyClass());
86698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  // Second static field.
867c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  auto* field = GetStaticField(1);
868c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  DCHECK_STREQ(field->GetName(), "throws");
869c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  MemberOffset field_offset = field->GetOffset();
8703a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray  return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
87198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang}
87298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang
8734ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
8744ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  CHECK(IsReferenceClass());
8754ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  // First static field
876c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  auto* field = GetStaticField(0);
877c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  DCHECK_STREQ(field->GetName(), "disableIntrinsic");
878c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  return field->GetOffset();
8794ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih}
8804ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih
8814ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline MemberOffset Class::GetSlowPathFlagOffset() {
8824ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  CHECK(IsReferenceClass());
8834ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  // Second static field
884c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  auto* field = GetStaticField(1);
885c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  DCHECK_STREQ(field->GetName(), "slowPathEnabled");
886c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  return field->GetOffset();
8874ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih}
8884ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih
8894ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline bool Class::GetSlowPathEnabled() {
89037f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldBoolean(GetSlowPathFlagOffset());
8914ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih}
8924ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih
8934ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline void Class::SetSlowPath(bool enabled) {
894310008008c90fea246efd00cb99ee7ded97c5209Mathieu Chartier  SetFieldBoolean<false, false>(GetSlowPathFlagOffset(), enabled);
8954ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih}
8964ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih
89728bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline void Class::InitializeClassVisitor::operator()(ObjPtr<Object> obj,
8989d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier                                                      size_t usable_size) const {
89998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  DCHECK_LE(class_size_, usable_size);
90098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  // Avoid AsClass as object is not yet in live bitmap or allocation stack.
90128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  ObjPtr<Class> klass = ObjPtr<Class>::DownCast(obj);
90298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  klass->SetClassSize(class_size_);
90398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  klass->SetPrimitiveType(Primitive::kPrimNot);  // Default to not being primitive.
90498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  klass->SetDexClassDefIndex(DexFile::kDexNoIndex16);  // Default to no valid class def index.
905a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  klass->SetDexTypeIndex(dex::TypeIndex(DexFile::kDexNoIndex16));  // Default to no valid type
906a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe                                                                   // index.
90793bbee0c1c97bd9a5336ed0c9e41cd17613df585Mathieu Chartier  // Default to force slow path until initialized.
908161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier  klass->SetObjectSizeAllocFastPath(std::numeric_limits<uint32_t>::max());
90998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang}
91098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang
91148498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampeinline void Class::SetAccessFlags(uint32_t new_access_flags) {
91248498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe  // Called inside a transaction when setting pre-verified flag during boot image compilation.
91348498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe  if (Runtime::Current()->IsActiveTransaction()) {
91452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier    SetField32<true>(AccessFlagsOffset(), new_access_flags);
91552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier  } else {
91652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier    SetField32<false>(AccessFlagsOffset(), new_access_flags);
91752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier  }
91852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier}
91952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier
92052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartierinline void Class::SetClassFlags(uint32_t new_flags) {
92152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier  if (Runtime::Current()->IsActiveTransaction()) {
92252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier    SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_flags_), new_flags);
92348498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe  } else {
92452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier    SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_flags_), new_flags);
92548498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe  }
92648498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe}
92748498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe
9282d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartierinline uint32_t Class::NumDirectInterfaces() {
9292d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier  if (IsPrimitive()) {
9302d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier    return 0;
9312d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier  } else if (IsArrayClass()) {
9322d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier    return 2;
9333a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray  } else if (IsProxyClass()) {
9346b2dc3156a2140a5bfd9cbbf5d7dad332ab5f5bdNarayan Kamath    ObjectArray<Class>* interfaces = GetProxyInterfaces();
9352d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier    return interfaces != nullptr ? interfaces->GetLength() : 0;
9362d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier  } else {
9372d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier    const DexFile::TypeList* interfaces = GetInterfaceTypeList();
9382d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier    if (interfaces == nullptr) {
9392d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier      return 0;
9402d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier    } else {
9412d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier      return interfaces->Size();
9422d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier    }
9432d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier  }
9442d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier}
9452d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier
946542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline IterationRange<StrideIterator<ArtMethod>> Class::GetDirectMethods(PointerSize pointer_size) {
947e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  CheckPointerSize(pointer_size);
948e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetDirectMethodsSliceUnchecked(pointer_size).AsRange();
949e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
950e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
951e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline IterationRange<StrideIterator<ArtMethod>> Class::GetDeclaredMethods(
952542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe      PointerSize pointer_size) {
953e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetDeclaredMethodsSliceUnchecked(pointer_size).AsRange();
954e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
955e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
956e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline IterationRange<StrideIterator<ArtMethod>> Class::GetDeclaredVirtualMethods(
957542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe      PointerSize pointer_size) {
958e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetDeclaredVirtualMethodsSliceUnchecked(pointer_size).AsRange();
959e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
960e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
961542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline IterationRange<StrideIterator<ArtMethod>> Class::GetVirtualMethods(
962542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe    PointerSize pointer_size) {
963e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  CheckPointerSize(pointer_size);
964e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetVirtualMethodsSliceUnchecked(pointer_size).AsRange();
965e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
966e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
967542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline IterationRange<StrideIterator<ArtMethod>> Class::GetCopiedMethods(PointerSize pointer_size) {
968e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  CheckPointerSize(pointer_size);
969e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetCopiedMethodsSliceUnchecked(pointer_size).AsRange();
970e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
971e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
972e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
973542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline IterationRange<StrideIterator<ArtMethod>> Class::GetMethods(PointerSize pointer_size) {
974e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  CheckPointerSize(pointer_size);
975e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return MakeIterationRangeFromLengthPrefixedArray(GetMethodsPtr(),
97614632857428b7e37761e6e811c19021715a400f8Vladimir Marko                                                   ArtMethod::Size(pointer_size),
97714632857428b7e37761e6e811c19021715a400f8Vladimir Marko                                                   ArtMethod::Alignment(pointer_size));
978e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
979e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
98054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetIFields() {
981cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko  return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtr());
982e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
983e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
98454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetSFields() {
985cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko  return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtr());
986e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
987e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
98854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetIFieldsUnchecked() {
989cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko  return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtrUnchecked());
990e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
991e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
99254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetSFieldsUnchecked() {
993cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko  return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtrUnchecked());
994e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
995e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
996542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline MemberOffset Class::EmbeddedVTableOffset(PointerSize pointer_size) {
997e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  CheckPointerSize(pointer_size);
998542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe  return MemberOffset(ImtPtrOffset(pointer_size).Uint32Value() + static_cast<size_t>(pointer_size));
999e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
1000e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
1001542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline void Class::CheckPointerSize(PointerSize pointer_size) {
1002e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  DCHECK_EQ(pointer_size, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
1003c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier}
1004c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier
10052e76830f0b3f23825677436c0633714402715099Calin Juravletemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
10062e76830f0b3f23825677436c0633714402715099Calin Juravleinline Class* Class::GetComponentType() {
10072e76830f0b3f23825677436c0633714402715099Calin Juravle  return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(ComponentTypeOffset());
10082e76830f0b3f23825677436c0633714402715099Calin Juravle}
10092e76830f0b3f23825677436c0633714402715099Calin Juravle
10102e76830f0b3f23825677436c0633714402715099Calin Juravletemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
10112e76830f0b3f23825677436c0633714402715099Calin Juravleinline bool Class::IsArrayClass() {
10122e76830f0b3f23825677436c0633714402715099Calin Juravle  return GetComponentType<kVerifyFlags, kReadBarrierOption>() != nullptr;
10132e76830f0b3f23825677436c0633714402715099Calin Juravle}
10142e76830f0b3f23825677436c0633714402715099Calin Juravle
1015c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampetemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
1016c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampeinline bool Class::IsObjectArrayClass() {
1017c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe  ObjPtr<Class> const component_type = GetComponentType<kVerifyFlags, kReadBarrierOption>();
1018c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe  return component_type != nullptr && !component_type->IsPrimitive();
1019c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe}
1020c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe
10213398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::IsAssignableFrom(ObjPtr<Class> src) {
10222e76830f0b3f23825677436c0633714402715099Calin Juravle  DCHECK(src != nullptr);
10232e76830f0b3f23825677436c0633714402715099Calin Juravle  if (this == src) {
10242e76830f0b3f23825677436c0633714402715099Calin Juravle    // Can always assign to things of the same type.
10252e76830f0b3f23825677436c0633714402715099Calin Juravle    return true;
10262e76830f0b3f23825677436c0633714402715099Calin Juravle  } else if (IsObjectClass()) {
10272e76830f0b3f23825677436c0633714402715099Calin Juravle    // Can assign any reference to java.lang.Object.
10282e76830f0b3f23825677436c0633714402715099Calin Juravle    return !src->IsPrimitive();
10292e76830f0b3f23825677436c0633714402715099Calin Juravle  } else if (IsInterface()) {
10302e76830f0b3f23825677436c0633714402715099Calin Juravle    return src->Implements(this);
10312e76830f0b3f23825677436c0633714402715099Calin Juravle  } else if (src->IsArrayClass()) {
10322e76830f0b3f23825677436c0633714402715099Calin Juravle    return IsAssignableFromArray(src);
10332e76830f0b3f23825677436c0633714402715099Calin Juravle  } else {
10342e76830f0b3f23825677436c0633714402715099Calin Juravle    return !src->IsInterface() && src->IsSubClass(this);
10352e76830f0b3f23825677436c0633714402715099Calin Juravle  }
10362e76830f0b3f23825677436c0633714402715099Calin Juravle}
10372e76830f0b3f23825677436c0633714402715099Calin Juravle
103854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumDirectMethods() {
1039e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetVirtualMethodsStartOffset();
1040e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light}
1041e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light
1042e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline uint32_t Class::NumDeclaredVirtualMethods() {
1043e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return GetCopiedMethodsStartOffset() - GetVirtualMethodsStartOffset();
104454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier}
104554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier
104654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumVirtualMethods() {
1047e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  return NumMethods() - GetVirtualMethodsStartOffset();
104854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier}
104954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier
105054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumInstanceFields() {
105154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier  LengthPrefixedArray<ArtField>* arr = GetIFieldsPtrUnchecked();
105235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  return arr != nullptr ? arr->size() : 0u;
105354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier}
105454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier
105554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumStaticFields() {
105654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier  LengthPrefixedArray<ArtField>* arr = GetSFieldsPtrUnchecked();
105735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko  return arr != nullptr ? arr->size() : 0u;
105854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier}
105954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier
1060dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
106128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline void Class::FixupNativePointers(Class* dest,
1062542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe                                       PointerSize pointer_size,
10634b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier                                       const Visitor& visitor) {
10644b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  // Update the field arrays.
10654b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  LengthPrefixedArray<ArtField>* const sfields = GetSFieldsPtr();
10664b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  LengthPrefixedArray<ArtField>* const new_sfields = visitor(sfields);
10674b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  if (sfields != new_sfields) {
10684b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier    dest->SetSFieldsPtrUnchecked(new_sfields);
10694b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  }
10704b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  LengthPrefixedArray<ArtField>* const ifields = GetIFieldsPtr();
10714b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  LengthPrefixedArray<ArtField>* const new_ifields = visitor(ifields);
10724b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  if (ifields != new_ifields) {
10734b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier    dest->SetIFieldsPtrUnchecked(new_ifields);
10744b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  }
1075e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  // Update method array.
1076e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
1077e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  LengthPrefixedArray<ArtMethod>* new_methods = visitor(methods);
1078e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light  if (methods != new_methods) {
1079e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light    dest->SetMethodsPtrInternal(new_methods);
10804b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  }
10814b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  // Fix up embedded tables.
1082a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko  if (!IsTemp() && ShouldHaveEmbeddedVTable<kVerifyNone, kReadBarrierOption>()) {
10834b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier    for (int32_t i = 0, count = GetEmbeddedVTableLength(); i < count; ++i) {
10844b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier      ArtMethod* method = GetEmbeddedVTableEntry(i, pointer_size);
10858c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier      void** dest_addr = reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(dest) +
10868c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier          EmbeddedVTableEntryOffset(i, pointer_size).Uint32Value());
10878c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier      ArtMethod* new_method = visitor(method, dest_addr);
10884b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier      if (method != new_method) {
10894b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier        dest->SetEmbeddedVTableEntryUnchecked(i, new_method, pointer_size);
10904b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier      }
10914b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier    }
1092a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko  }
1093a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko  if (!IsTemp() && ShouldHaveImt<kVerifyNone, kReadBarrierOption>()) {
1094a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko    dest->SetImt(visitor(GetImt(pointer_size)), pointer_size);
10954b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  }
10964b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier}
10974b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier
10983398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::CanAccess(ObjPtr<Class> that) {
10993398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  return that->IsPublic() || this->IsInSamePackage(that);
11003398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier}
11013398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier
11023398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier
11033398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::CanAccessMember(ObjPtr<Class> access_to, uint32_t member_flags) {
11043398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  // Classes can access all of their own members
11053398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  if (this == access_to) {
11063398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier    return true;
11073398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  }
11083398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  // Public members are trivially accessible
11093398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  if (member_flags & kAccPublic) {
11103398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier    return true;
11113398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  }
11123398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  // Private members are trivially not accessible
11133398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  if (member_flags & kAccPrivate) {
11143398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier    return false;
11153398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  }
11163398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  // Check for protected access from a sub-class, which may or may not be in the same package.
11173398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  if (member_flags & kAccProtected) {
11183398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier    if (!this->IsInterface() && this->IsSubClass(access_to)) {
11193398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier      return true;
11203398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier    }
11213398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  }
11223398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  // Allow protected access from other classes in the same package.
11233398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  return this->IsInSamePackage(access_to);
11243398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier}
11253398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier
112628bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline bool Class::CannotBeAssignedFromOtherTypes() {
112728bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  if (!IsArrayClass()) {
112828bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier    return IsFinal();
112928bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  }
113028bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  ObjPtr<Class> component = GetComponentType();
113128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier  return component->IsPrimitive() || component->CannotBeAssignedFromOtherTypes();
113228bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier}
113328bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier
11342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
11352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace art
11362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1137fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_MIRROR_CLASS_INL_H_
1138