blob: a8a58e135eed0f952d1d14bd3ce8e96263e0a3f2 [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"
Andreas Gampec6ea7d02017-02-01 16:46:28 -080024#include "dex_file-inl.h"
Vladimir Marko3481ba22015-04-13 12:22:36 +010025#include "gc_root-inl.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070026#include "gc/accounting/card_table-inl.h"
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080027#include "jvalue.h"
Vladimir Marko05792b92015-08-03 11:56:49 +010028#include "mirror/dex_cache-inl.h"
Mathieu Chartierc7853442015-03-27 14:35:38 -070029#include "mirror/object-inl.h"
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080030#include "primitive.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070031#include "thread-current-inl.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070032#include "scoped_thread_state_change-inl.h"
Mathieu Chartier76433272014-09-26 14:32:37 -070033#include "well_known_classes.h"
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080034
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080035namespace art {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080036
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -070037template<ReadBarrierOption kReadBarrierOption>
Mathieu Chartier3398c782016-09-30 10:27:43 -070038inline ObjPtr<mirror::Class> ArtField::GetDeclaringClass() {
Hiroshi Yamauchi3f64f252015-06-12 18:35:06 -070039 GcRootSource gc_root_source(this);
Mathieu Chartier3398c782016-09-30 10:27:43 -070040 ObjPtr<mirror::Class> result = declaring_class_.Read<kReadBarrierOption>(&gc_root_source);
Mathieu Chartierc7853442015-03-27 14:35:38 -070041 DCHECK(result != nullptr);
Mathieu Chartierfbc31082016-01-24 11:59:56 -080042 DCHECK(result->IsLoaded() || result->IsErroneous()) << result->GetStatus();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080043 return result;
44}
45
Mathieu Chartier3398c782016-09-30 10:27:43 -070046inline void ArtField::SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class) {
Mathieu Chartierc7853442015-03-27 14:35:38 -070047 declaring_class_ = GcRoot<mirror::Class>(new_declaring_class);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080048}
49
Ian Rogersef7d42f2014-01-06 12:55:46 -080050inline MemberOffset ArtField::GetOffsetDuringLinking() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080051 DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
Mathieu Chartierc7853442015-03-27 14:35:38 -070052 return MemberOffset(offset_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080053}
54
Mathieu Chartier3398c782016-09-30 10:27:43 -070055inline uint32_t ArtField::Get32(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -070056 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080057 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070058 if (UNLIKELY(IsVolatile())) {
59 return object->GetField32Volatile(GetOffset());
60 }
61 return object->GetField32(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080062}
63
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010064template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -070065inline void ArtField::Set32(ObjPtr<mirror::Object> object, uint32_t new_value) {
David Sehr709b0702016-10-13 09:12:37 -070066 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080067 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070068 if (UNLIKELY(IsVolatile())) {
69 object->SetField32Volatile<kTransactionActive>(GetOffset(), new_value);
70 } else {
71 object->SetField32<kTransactionActive>(GetOffset(), new_value);
72 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080073}
74
Mathieu Chartier3398c782016-09-30 10:27:43 -070075inline uint64_t ArtField::Get64(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -070076 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080077 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070078 if (UNLIKELY(IsVolatile())) {
79 return object->GetField64Volatile(GetOffset());
80 }
81 return object->GetField64(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080082}
83
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010084template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -070085inline void ArtField::Set64(ObjPtr<mirror::Object> object, uint64_t new_value) {
David Sehr709b0702016-10-13 09:12:37 -070086 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080087 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070088 if (UNLIKELY(IsVolatile())) {
89 object->SetField64Volatile<kTransactionActive>(GetOffset(), new_value);
90 } else {
91 object->SetField64<kTransactionActive>(GetOffset(), new_value);
92 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080093}
94
Mathieu Chartier3398c782016-09-30 10:27:43 -070095template<class MirrorType>
96inline ObjPtr<MirrorType> ArtField::GetObj(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -070097 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080098 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070099 if (UNLIKELY(IsVolatile())) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700100 return object->GetFieldObjectVolatile<MirrorType>(GetOffset());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700101 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700102 return object->GetFieldObject<MirrorType>(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800103}
104
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100105template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700106inline void ArtField::SetObj(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> new_value) {
David Sehr709b0702016-10-13 09:12:37 -0700107 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800108 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700109 if (UNLIKELY(IsVolatile())) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700110 object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700111 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700112 object->SetFieldObject<kTransactionActive>(GetOffset(), new_value);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700113 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800114}
115
Fred Shih37f05ef2014-07-16 18:38:08 -0700116#define FIELD_GET(object, type) \
David Sehr709b0702016-10-13 09:12:37 -0700117 DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(); \
118 DCHECK((object) != nullptr) << PrettyField(); \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700119 DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700120 if (UNLIKELY(IsVolatile())) { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700121 return (object)->GetField ## type ## Volatile(GetOffset()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700122 } \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700123 return (object)->GetField ## type(GetOffset());
Fred Shih37f05ef2014-07-16 18:38:08 -0700124
125#define FIELD_SET(object, type, value) \
David Sehr709b0702016-10-13 09:12:37 -0700126 DCHECK((object) != nullptr) << PrettyField(); \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700127 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 (object)->SetField ## type ## Volatile<kTransactionActive>(GetOffset(), value); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700130 } else { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700131 (object)->SetField ## type<kTransactionActive>(GetOffset(), value); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700132 }
133
Mathieu Chartier3398c782016-09-30 10:27:43 -0700134inline uint8_t ArtField::GetBoolean(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700135 FIELD_GET(object, Boolean);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800136}
137
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100138template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700139inline void ArtField::SetBoolean(ObjPtr<mirror::Object> object, uint8_t z) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000140 if (kIsDebugBuild) {
141 // For simplicity, this method is being called by the compiler entrypoint for
142 // both boolean and byte fields.
143 Primitive::Type type = GetTypeAsPrimitiveType();
144 DCHECK(type == Primitive::kPrimBoolean || type == Primitive::kPrimByte) << PrettyField();
145 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700146 FIELD_SET(object, Boolean, z);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800147}
148
Mathieu Chartier3398c782016-09-30 10:27:43 -0700149inline int8_t ArtField::GetByte(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700150 FIELD_GET(object, Byte);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800151}
152
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100153template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700154inline void ArtField::SetByte(ObjPtr<mirror::Object> object, int8_t b) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000155 DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField();
Fred Shih37f05ef2014-07-16 18:38:08 -0700156 FIELD_SET(object, Byte, b);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800157}
158
Mathieu Chartier3398c782016-09-30 10:27:43 -0700159inline uint16_t ArtField::GetChar(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700160 FIELD_GET(object, Char);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800161}
162
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100163template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700164inline void ArtField::SetChar(ObjPtr<mirror::Object> object, uint16_t c) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000165 if (kIsDebugBuild) {
166 // For simplicity, this method is being called by the compiler entrypoint for
167 // both char and short fields.
168 Primitive::Type type = GetTypeAsPrimitiveType();
169 DCHECK(type == Primitive::kPrimChar || type == Primitive::kPrimShort) << PrettyField();
170 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700171 FIELD_SET(object, Char, c);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800172}
173
Mathieu Chartier3398c782016-09-30 10:27:43 -0700174inline int16_t ArtField::GetShort(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700175 FIELD_GET(object, Short);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800176}
177
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100178template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700179inline void ArtField::SetShort(ObjPtr<mirror::Object> object, int16_t s) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000180 DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField();
Fred Shih37f05ef2014-07-16 18:38:08 -0700181 FIELD_SET(object, Short, s);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800182}
183
Fred Shih37f05ef2014-07-16 18:38:08 -0700184#undef FIELD_GET
185#undef FIELD_SET
186
Mathieu Chartier3398c782016-09-30 10:27:43 -0700187inline int32_t ArtField::GetInt(ObjPtr<mirror::Object> object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100188 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000189 // For simplicity, this method is being called by the compiler entrypoint for
190 // both int and float fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700191 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700192 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100193 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800194 return Get32(object);
195}
196
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100197template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700198inline void ArtField::SetInt(ObjPtr<mirror::Object> object, int32_t i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100199 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000200 // For simplicity, this method is being called by the compiler entrypoint for
201 // both int and float fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700202 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700203 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100204 }
205 Set32<kTransactionActive>(object, i);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800206}
207
Mathieu Chartier3398c782016-09-30 10:27:43 -0700208inline int64_t ArtField::GetLong(ObjPtr<mirror::Object> object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100209 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000210 // For simplicity, this method is being called by the compiler entrypoint for
211 // both long and double fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700212 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700213 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100214 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800215 return Get64(object);
216}
217
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100218template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700219inline void ArtField::SetLong(ObjPtr<mirror::Object> object, int64_t j) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100220 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000221 // For simplicity, this method is being called by the compiler entrypoint for
222 // both long and double fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700223 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700224 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100225 }
226 Set64<kTransactionActive>(object, j);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800227}
228
Mathieu Chartier3398c782016-09-30 10:27:43 -0700229inline float ArtField::GetFloat(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700230 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800231 JValue bits;
232 bits.SetI(Get32(object));
233 return bits.GetF();
234}
235
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100236template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700237inline void ArtField::SetFloat(ObjPtr<mirror::Object> object, float f) {
David Sehr709b0702016-10-13 09:12:37 -0700238 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800239 JValue bits;
240 bits.SetF(f);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100241 Set32<kTransactionActive>(object, bits.GetI());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800242}
243
Mathieu Chartier3398c782016-09-30 10:27:43 -0700244inline double ArtField::GetDouble(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700245 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800246 JValue bits;
247 bits.SetJ(Get64(object));
248 return bits.GetD();
249}
250
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100251template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700252inline void ArtField::SetDouble(ObjPtr<mirror::Object> object, double d) {
David Sehr709b0702016-10-13 09:12:37 -0700253 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800254 JValue bits;
255 bits.SetD(d);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100256 Set64<kTransactionActive>(object, bits.GetJ());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800257}
258
Mathieu Chartier3398c782016-09-30 10:27:43 -0700259inline ObjPtr<mirror::Object> ArtField::GetObject(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700260 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800261 return GetObj(object);
262}
263
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100264template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700265inline void ArtField::SetObject(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> l) {
David Sehr709b0702016-10-13 09:12:37 -0700266 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100267 SetObj<kTransactionActive>(object, l);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800268}
269
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700270inline const char* ArtField::GetName() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700271 uint32_t field_index = GetDexFieldIndex();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000272 if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700273 DCHECK(IsStatic());
274 DCHECK_LT(field_index, 2U);
275 return field_index == 0 ? "interfaces" : "throws";
276 }
277 const DexFile* dex_file = GetDexFile();
278 return dex_file->GetFieldName(dex_file->GetFieldId(field_index));
279}
280
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700281inline const char* ArtField::GetTypeDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700282 uint32_t field_index = GetDexFieldIndex();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000283 if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700284 DCHECK(IsStatic());
285 DCHECK_LT(field_index, 2U);
286 // 0 == Class[] interfaces; 1 == Class[][] throws;
287 return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
288 }
289 const DexFile* dex_file = GetDexFile();
290 const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
291 return dex_file->GetFieldTypeDescriptor(field_id);
292}
293
294inline Primitive::Type ArtField::GetTypeAsPrimitiveType()
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700295 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700296 return Primitive::GetType(GetTypeDescriptor()[0]);
297}
298
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700299inline bool ArtField::IsPrimitiveType() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700300 return GetTypeAsPrimitiveType() != Primitive::kPrimNot;
301}
302
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700303template <bool kResolve>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700304inline ObjPtr<mirror::Class> ArtField::GetType() {
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000305 // TODO: Refactor this function into two functions, ResolveType() and LookupType()
306 // so that we can properly annotate it with no-suspension possible / suspension possible.
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700307 const uint32_t field_index = GetDexFieldIndex();
Mathieu Chartier3398c782016-09-30 10:27:43 -0700308 ObjPtr<mirror::Class> declaring_class = GetDeclaringClass();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000309 if (UNLIKELY(declaring_class->IsProxyClass())) {
310 return ProxyFindSystemClass(GetTypeDescriptor());
Ian Rogers08f1f502014-12-02 15:04:37 -0800311 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700312 auto* dex_cache = declaring_class->GetDexCache();
313 const DexFile* const dex_file = dex_cache->GetDexFile();
Ian Rogers08f1f502014-12-02 15:04:37 -0800314 const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700315 ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(field_id.type_idx_);
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000316 if (UNLIKELY(type == nullptr)) {
317 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
318 if (kResolve) {
319 type = class_linker->ResolveType(*dex_file, field_id.type_idx_, declaring_class);
320 CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
321 } else {
322 type = class_linker->LookupResolvedType(
323 *dex_file, field_id.type_idx_, dex_cache, declaring_class->GetClassLoader());
324 DCHECK(!Thread::Current()->IsExceptionPending());
325 }
Ian Rogers08f1f502014-12-02 15:04:37 -0800326 }
327 return type;
328}
329
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700330inline size_t ArtField::FieldSize() REQUIRES_SHARED(Locks::mutator_lock_) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700331 return Primitive::ComponentSize(GetTypeAsPrimitiveType());
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700332}
333
Mathieu Chartier3398c782016-09-30 10:27:43 -0700334inline ObjPtr<mirror::DexCache> ArtField::GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700335 return GetDeclaringClass()->GetDexCache();
336}
337
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700338inline const DexFile* ArtField::GetDexFile() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700339 return GetDexCache()->GetDexFile();
340}
341
Mathieu Chartier3398c782016-09-30 10:27:43 -0700342inline ObjPtr<mirror::String> ArtField::GetStringName(Thread* self, bool resolve) {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700343 auto dex_field_index = GetDexFieldIndex();
344 CHECK_NE(dex_field_index, DexFile::kDexNoIndex);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700345 ObjPtr<mirror::DexCache> dex_cache = GetDexCache();
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700346 const auto* dex_file = dex_cache->GetDexFile();
347 const auto& field_id = dex_file->GetFieldId(dex_field_index);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700348 ObjPtr<mirror::String> name = dex_cache->GetResolvedString(field_id.name_idx_);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700349 if (resolve && name == nullptr) {
Vladimir Marko3481ba22015-04-13 12:22:36 +0100350 name = ResolveGetStringName(self, *dex_file, field_id.name_idx_, dex_cache);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700351 }
352 return name;
Mathieu Chartier76433272014-09-26 14:32:37 -0700353}
354
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800355template <typename Visitor>
356inline void ArtField::UpdateObjects(const Visitor& visitor) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700357 ObjPtr<mirror::Class> old_class = DeclaringClassRoot().Read<kWithoutReadBarrier>();
Mathieu Chartier1cc62e42016-10-03 18:01:28 -0700358 ObjPtr<mirror::Class> new_class = visitor(old_class.Ptr());
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800359 if (old_class != new_class) {
360 SetDeclaringClass(new_class);
361 }
362}
363
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700364// If kExactOffset is true then we only find the matching offset, not the field containing the
365// offset.
366template <bool kExactOffset>
367static inline ArtField* FindFieldWithOffset(
368 const IterationRange<StrideIterator<ArtField>>& fields,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700369 uint32_t field_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700370 for (ArtField& field : fields) {
371 if (kExactOffset) {
372 if (field.GetOffset().Uint32Value() == field_offset) {
373 return &field;
374 }
375 } else {
376 const uint32_t offset = field.GetOffset().Uint32Value();
377 Primitive::Type type = field.GetTypeAsPrimitiveType();
378 const size_t field_size = Primitive::ComponentSize(type);
379 DCHECK_GT(field_size, 0u);
380 if (offset <= field_offset && field_offset < offset + field_size) {
381 return &field;
382 }
383 }
384 }
385 return nullptr;
386}
387
388template <bool kExactOffset>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700389inline ArtField* ArtField::FindInstanceFieldWithOffset(ObjPtr<mirror::Class> klass,
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700390 uint32_t field_offset) {
391 DCHECK(klass != nullptr);
392 ArtField* field = FindFieldWithOffset<kExactOffset>(klass->GetIFields(), field_offset);
393 if (field != nullptr) {
394 return field;
395 }
396 // We did not find field in the class: look into superclass.
397 return (klass->GetSuperClass() != nullptr) ?
398 FindInstanceFieldWithOffset<kExactOffset>(klass->GetSuperClass(), field_offset) : nullptr;
399}
400
401template <bool kExactOffset>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700402inline ArtField* ArtField::FindStaticFieldWithOffset(ObjPtr<mirror::Class> klass,
403 uint32_t field_offset) {
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700404 DCHECK(klass != nullptr);
405 return FindFieldWithOffset<kExactOffset>(klass->GetSFields(), field_offset);
406}
407
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800408} // namespace art
409
Mathieu Chartierc7853442015-03-27 14:35:38 -0700410#endif // ART_RUNTIME_ART_FIELD_INL_H_