blob: ef75f941b50d4897b12990bd657bcb7ef7909666 [file] [log] [blame]
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mathieu Chartierc7853442015-03-27 14:35:38 -070017#ifndef ART_RUNTIME_ART_FIELD_INL_H_
18#define ART_RUNTIME_ART_FIELD_INL_H_
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080019
Brian Carlstromea46f952013-07-30 01:26:50 -070020#include "art_field.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080021
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080022#include "base/logging.h"
Ian Rogers08f1f502014-12-02 15:04:37 -080023#include "class_linker.h"
Vladimir Marko3481ba22015-04-13 12:22:36 +010024#include "gc_root-inl.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070025#include "gc/accounting/card_table-inl.h"
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080026#include "jvalue.h"
Vladimir Marko05792b92015-08-03 11:56:49 +010027#include "mirror/dex_cache-inl.h"
Mathieu Chartierc7853442015-03-27 14:35:38 -070028#include "mirror/object-inl.h"
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080029#include "primitive.h"
Mathieu Chartier76433272014-09-26 14:32:37 -070030#include "thread-inl.h"
31#include "scoped_thread_state_change.h"
32#include "well_known_classes.h"
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080033
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080034namespace art {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080035
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -070036template<ReadBarrierOption kReadBarrierOption>
Mathieu Chartierc7853442015-03-27 14:35:38 -070037inline mirror::Class* ArtField::GetDeclaringClass() {
Hiroshi Yamauchi3f64f252015-06-12 18:35:06 -070038 GcRootSource gc_root_source(this);
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -070039 mirror::Class* result = declaring_class_.Read<kReadBarrierOption>(&gc_root_source);
Mathieu Chartierc7853442015-03-27 14:35:38 -070040 DCHECK(result != nullptr);
Mathieu Chartierfbc31082016-01-24 11:59:56 -080041 DCHECK(result->IsLoaded() || result->IsErroneous()) << result->GetStatus();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080042 return result;
43}
44
Mathieu Chartierc7853442015-03-27 14:35:38 -070045inline void ArtField::SetDeclaringClass(mirror::Class* new_declaring_class) {
46 declaring_class_ = GcRoot<mirror::Class>(new_declaring_class);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080047}
48
Ian Rogersef7d42f2014-01-06 12:55:46 -080049inline uint32_t ArtField::GetAccessFlags() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080050 DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
Mathieu Chartierc7853442015-03-27 14:35:38 -070051 return access_flags_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080052}
53
Ian Rogersef7d42f2014-01-06 12:55:46 -080054inline MemberOffset ArtField::GetOffset() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080055 DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
Mathieu Chartierc7853442015-03-27 14:35:38 -070056 return MemberOffset(offset_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080057}
58
Ian Rogersef7d42f2014-01-06 12:55:46 -080059inline MemberOffset ArtField::GetOffsetDuringLinking() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080060 DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
Mathieu Chartierc7853442015-03-27 14:35:38 -070061 return MemberOffset(offset_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080062}
63
Mathieu Chartierc7853442015-03-27 14:35:38 -070064inline uint32_t ArtField::Get32(mirror::Object* object) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070065 DCHECK(object != nullptr) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080066 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070067 if (UNLIKELY(IsVolatile())) {
68 return object->GetField32Volatile(GetOffset());
69 }
70 return object->GetField32(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080071}
72
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010073template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -070074inline void ArtField::Set32(mirror::Object* object, uint32_t new_value) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070075 DCHECK(object != nullptr) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080076 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070077 if (UNLIKELY(IsVolatile())) {
78 object->SetField32Volatile<kTransactionActive>(GetOffset(), new_value);
79 } else {
80 object->SetField32<kTransactionActive>(GetOffset(), new_value);
81 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080082}
83
Mathieu Chartierc7853442015-03-27 14:35:38 -070084inline uint64_t ArtField::Get64(mirror::Object* object) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -070085 DCHECK(object != nullptr) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080086 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070087 if (UNLIKELY(IsVolatile())) {
88 return object->GetField64Volatile(GetOffset());
89 }
90 return object->GetField64(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080091}
92
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010093template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -070094inline void ArtField::Set64(mirror::Object* object, uint64_t new_value) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -070095 DCHECK(object != nullptr) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080096 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070097 if (UNLIKELY(IsVolatile())) {
98 object->SetField64Volatile<kTransactionActive>(GetOffset(), new_value);
99 } else {
100 object->SetField64<kTransactionActive>(GetOffset(), new_value);
101 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800102}
103
Mathieu Chartierc7853442015-03-27 14:35:38 -0700104inline mirror::Object* ArtField::GetObj(mirror::Object* object) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700105 DCHECK(object != nullptr) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800106 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700107 if (UNLIKELY(IsVolatile())) {
Mathieu Chartierc7853442015-03-27 14:35:38 -0700108 return object->GetFieldObjectVolatile<mirror::Object>(GetOffset());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700109 }
Mathieu Chartierc7853442015-03-27 14:35:38 -0700110 return object->GetFieldObject<mirror::Object>(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800111}
112
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100113template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -0700114inline void ArtField::SetObj(mirror::Object* object, mirror::Object* new_value) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700115 DCHECK(object != nullptr) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800116 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700117 if (UNLIKELY(IsVolatile())) {
118 object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value);
119 } else {
120 object->SetFieldObject<kTransactionActive>(GetOffset(), new_value);
121 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800122}
123
Fred Shih37f05ef2014-07-16 18:38:08 -0700124#define FIELD_GET(object, type) \
125 DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(this); \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700126 DCHECK((object) != nullptr) << PrettyField(this); \
127 DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700128 if (UNLIKELY(IsVolatile())) { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700129 return (object)->GetField ## type ## Volatile(GetOffset()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700130 } \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700131 return (object)->GetField ## type(GetOffset());
Fred Shih37f05ef2014-07-16 18:38:08 -0700132
133#define FIELD_SET(object, type, value) \
134 DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(this); \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700135 DCHECK((object) != nullptr) << PrettyField(this); \
136 DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700137 if (UNLIKELY(IsVolatile())) { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700138 (object)->SetField ## type ## Volatile<kTransactionActive>(GetOffset(), value); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700139 } else { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700140 (object)->SetField ## type<kTransactionActive>(GetOffset(), value); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700141 }
142
Mathieu Chartierc7853442015-03-27 14:35:38 -0700143inline uint8_t ArtField::GetBoolean(mirror::Object* object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700144 FIELD_GET(object, Boolean);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800145}
146
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100147template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -0700148inline void ArtField::SetBoolean(mirror::Object* object, uint8_t z) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700149 FIELD_SET(object, Boolean, z);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800150}
151
Mathieu Chartierc7853442015-03-27 14:35:38 -0700152inline int8_t ArtField::GetByte(mirror::Object* object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700153 FIELD_GET(object, Byte);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800154}
155
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100156template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -0700157inline void ArtField::SetByte(mirror::Object* object, int8_t b) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700158 FIELD_SET(object, Byte, b);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800159}
160
Mathieu Chartierc7853442015-03-27 14:35:38 -0700161inline uint16_t ArtField::GetChar(mirror::Object* object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700162 FIELD_GET(object, Char);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800163}
164
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100165template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -0700166inline void ArtField::SetChar(mirror::Object* object, uint16_t c) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700167 FIELD_SET(object, Char, c);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800168}
169
Mathieu Chartierc7853442015-03-27 14:35:38 -0700170inline int16_t ArtField::GetShort(mirror::Object* object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700171 FIELD_GET(object, Short);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800172}
173
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100174template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -0700175inline void ArtField::SetShort(mirror::Object* object, int16_t s) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700176 FIELD_SET(object, Short, s);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800177}
178
Fred Shih37f05ef2014-07-16 18:38:08 -0700179#undef FIELD_GET
180#undef FIELD_SET
181
Mathieu Chartierc7853442015-03-27 14:35:38 -0700182inline int32_t ArtField::GetInt(mirror::Object* object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100183 if (kIsDebugBuild) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700184 Primitive::Type type = GetTypeAsPrimitiveType();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100185 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
186 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800187 return Get32(object);
188}
189
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100190template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -0700191inline void ArtField::SetInt(mirror::Object* object, int32_t i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100192 if (kIsDebugBuild) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700193 Primitive::Type type = GetTypeAsPrimitiveType();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100194 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
195 }
196 Set32<kTransactionActive>(object, i);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800197}
198
Mathieu Chartierc7853442015-03-27 14:35:38 -0700199inline int64_t ArtField::GetLong(mirror::Object* object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100200 if (kIsDebugBuild) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700201 Primitive::Type type = GetTypeAsPrimitiveType();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100202 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
203 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800204 return Get64(object);
205}
206
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100207template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -0700208inline void ArtField::SetLong(mirror::Object* object, int64_t j) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100209 if (kIsDebugBuild) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700210 Primitive::Type type = GetTypeAsPrimitiveType();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100211 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
212 }
213 Set64<kTransactionActive>(object, j);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800214}
215
Mathieu Chartierc7853442015-03-27 14:35:38 -0700216inline float ArtField::GetFloat(mirror::Object* object) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700217 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800218 JValue bits;
219 bits.SetI(Get32(object));
220 return bits.GetF();
221}
222
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100223template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -0700224inline void ArtField::SetFloat(mirror::Object* object, float f) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700225 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800226 JValue bits;
227 bits.SetF(f);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100228 Set32<kTransactionActive>(object, bits.GetI());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800229}
230
Mathieu Chartierc7853442015-03-27 14:35:38 -0700231inline double ArtField::GetDouble(mirror::Object* object) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700232 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800233 JValue bits;
234 bits.SetJ(Get64(object));
235 return bits.GetD();
236}
237
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100238template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -0700239inline void ArtField::SetDouble(mirror::Object* object, double d) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700240 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800241 JValue bits;
242 bits.SetD(d);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100243 Set64<kTransactionActive>(object, bits.GetJ());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800244}
245
Mathieu Chartierc7853442015-03-27 14:35:38 -0700246inline mirror::Object* ArtField::GetObject(mirror::Object* object) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700247 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800248 return GetObj(object);
249}
250
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100251template<bool kTransactionActive>
Mathieu Chartierc7853442015-03-27 14:35:38 -0700252inline void ArtField::SetObject(mirror::Object* object, mirror::Object* l) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700253 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100254 SetObj<kTransactionActive>(object, l);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800255}
256
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700257inline const char* ArtField::GetName() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700258 uint32_t field_index = GetDexFieldIndex();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000259 if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700260 DCHECK(IsStatic());
261 DCHECK_LT(field_index, 2U);
262 return field_index == 0 ? "interfaces" : "throws";
263 }
264 const DexFile* dex_file = GetDexFile();
265 return dex_file->GetFieldName(dex_file->GetFieldId(field_index));
266}
267
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700268inline const char* ArtField::GetTypeDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700269 uint32_t field_index = GetDexFieldIndex();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000270 if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700271 DCHECK(IsStatic());
272 DCHECK_LT(field_index, 2U);
273 // 0 == Class[] interfaces; 1 == Class[][] throws;
274 return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
275 }
276 const DexFile* dex_file = GetDexFile();
277 const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
278 return dex_file->GetFieldTypeDescriptor(field_id);
279}
280
281inline Primitive::Type ArtField::GetTypeAsPrimitiveType()
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700282 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700283 return Primitive::GetType(GetTypeDescriptor()[0]);
284}
285
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700286inline bool ArtField::IsPrimitiveType() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700287 return GetTypeAsPrimitiveType() != Primitive::kPrimNot;
288}
289
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700290template <bool kResolve>
Mathieu Chartierc7853442015-03-27 14:35:38 -0700291inline mirror::Class* ArtField::GetType() {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700292 const uint32_t field_index = GetDexFieldIndex();
293 auto* declaring_class = GetDeclaringClass();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000294 if (UNLIKELY(declaring_class->IsProxyClass())) {
295 return ProxyFindSystemClass(GetTypeDescriptor());
Ian Rogers08f1f502014-12-02 15:04:37 -0800296 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700297 auto* dex_cache = declaring_class->GetDexCache();
298 const DexFile* const dex_file = dex_cache->GetDexFile();
Ian Rogers08f1f502014-12-02 15:04:37 -0800299 const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700300 mirror::Class* type = dex_cache->GetResolvedType(field_id.type_idx_);
301 if (kResolve && UNLIKELY(type == nullptr)) {
Vladimir Marko3481ba22015-04-13 12:22:36 +0100302 type = ResolveGetType(field_id.type_idx_);
Ian Rogers08f1f502014-12-02 15:04:37 -0800303 CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
304 }
305 return type;
306}
307
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700308inline size_t ArtField::FieldSize() REQUIRES_SHARED(Locks::mutator_lock_) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700309 return Primitive::ComponentSize(GetTypeAsPrimitiveType());
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700310}
311
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700312inline mirror::DexCache* ArtField::GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700313 return GetDeclaringClass()->GetDexCache();
314}
315
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700316inline const DexFile* ArtField::GetDexFile() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700317 return GetDexCache()->GetDexFile();
318}
319
Mathieu Chartierc7853442015-03-27 14:35:38 -0700320inline mirror::String* ArtField::GetStringName(Thread* self, bool resolve) {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700321 auto dex_field_index = GetDexFieldIndex();
322 CHECK_NE(dex_field_index, DexFile::kDexNoIndex);
323 auto* dex_cache = GetDexCache();
324 const auto* dex_file = dex_cache->GetDexFile();
325 const auto& field_id = dex_file->GetFieldId(dex_field_index);
326 auto* name = dex_cache->GetResolvedString(field_id.name_idx_);
327 if (resolve && name == nullptr) {
Vladimir Marko3481ba22015-04-13 12:22:36 +0100328 name = ResolveGetStringName(self, *dex_file, field_id.name_idx_, dex_cache);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700329 }
330 return name;
Mathieu Chartier76433272014-09-26 14:32:37 -0700331}
332
Mathieu Chartiere401d142015-04-22 13:56:20 -0700333template<typename RootVisitorType>
334inline void ArtField::VisitRoots(RootVisitorType& visitor) {
335 visitor.VisitRoot(declaring_class_.AddressWithoutBarrier());
336}
337
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800338template <typename Visitor>
339inline void ArtField::UpdateObjects(const Visitor& visitor) {
340 mirror::Class* old_class = DeclaringClassRoot().Read<kWithoutReadBarrier>();
341 mirror::Class* new_class = visitor(old_class);
342 if (old_class != new_class) {
343 SetDeclaringClass(new_class);
344 }
345}
346
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700347// If kExactOffset is true then we only find the matching offset, not the field containing the
348// offset.
349template <bool kExactOffset>
350static inline ArtField* FindFieldWithOffset(
351 const IterationRange<StrideIterator<ArtField>>& fields,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700352 uint32_t field_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700353 for (ArtField& field : fields) {
354 if (kExactOffset) {
355 if (field.GetOffset().Uint32Value() == field_offset) {
356 return &field;
357 }
358 } else {
359 const uint32_t offset = field.GetOffset().Uint32Value();
360 Primitive::Type type = field.GetTypeAsPrimitiveType();
361 const size_t field_size = Primitive::ComponentSize(type);
362 DCHECK_GT(field_size, 0u);
363 if (offset <= field_offset && field_offset < offset + field_size) {
364 return &field;
365 }
366 }
367 }
368 return nullptr;
369}
370
371template <bool kExactOffset>
372inline ArtField* ArtField::FindInstanceFieldWithOffset(mirror::Class* klass,
373 uint32_t field_offset) {
374 DCHECK(klass != nullptr);
375 ArtField* field = FindFieldWithOffset<kExactOffset>(klass->GetIFields(), field_offset);
376 if (field != nullptr) {
377 return field;
378 }
379 // We did not find field in the class: look into superclass.
380 return (klass->GetSuperClass() != nullptr) ?
381 FindInstanceFieldWithOffset<kExactOffset>(klass->GetSuperClass(), field_offset) : nullptr;
382}
383
384template <bool kExactOffset>
385inline ArtField* ArtField::FindStaticFieldWithOffset(mirror::Class* klass, uint32_t field_offset) {
386 DCHECK(klass != nullptr);
387 return FindFieldWithOffset<kExactOffset>(klass->GetSFields(), field_offset);
388}
389
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800390} // namespace art
391
Mathieu Chartierc7853442015-03-27 14:35:38 -0700392#endif // ART_RUNTIME_ART_FIELD_INL_H_