blob: fb4141886a631fe0b3e6aca055604bf40148a3fe [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
Andreas Gampe57943812017-12-06 21:39:13 -080022#include <android-base/logging.h>
23
Vladimir Marko18090d12018-06-01 16:53:12 +010024#include "class_linker-inl.h"
David Sehr9e734c72018-01-04 17:56:19 -080025#include "dex/dex_file-inl.h"
David Sehr67bf42e2018-02-26 16:43:04 -080026#include "dex/primitive.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070027#include "gc/accounting/card_table-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070028#include "gc_root-inl.h"
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080029#include "jvalue.h"
Vladimir Marko05792b92015-08-03 11:56:49 +010030#include "mirror/dex_cache-inl.h"
Mathieu Chartierc7853442015-03-27 14:35:38 -070031#include "mirror/object-inl.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070032#include "scoped_thread_state_change-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070033#include "thread-current-inl.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
Vladimir Marko09c5ca42018-05-31 15:15:31 +010037inline bool ArtField::IsProxyField() {
38 return GetDeclaringClass<kWithoutReadBarrier>()->IsProxyClass<kVerifyNone>();
39}
40
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -070041template<ReadBarrierOption kReadBarrierOption>
Mathieu Chartier3398c782016-09-30 10:27:43 -070042inline ObjPtr<mirror::Class> ArtField::GetDeclaringClass() {
Hiroshi Yamauchi3f64f252015-06-12 18:35:06 -070043 GcRootSource gc_root_source(this);
Mathieu Chartier3398c782016-09-30 10:27:43 -070044 ObjPtr<mirror::Class> result = declaring_class_.Read<kReadBarrierOption>(&gc_root_source);
Mathieu Chartierc7853442015-03-27 14:35:38 -070045 DCHECK(result != nullptr);
Vladimir Marko09c5ca42018-05-31 15:15:31 +010046 DCHECK(result->IsIdxLoaded() || result->IsErroneous()) << result->GetStatus();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080047 return result;
48}
49
Mathieu Chartier3398c782016-09-30 10:27:43 -070050inline void ArtField::SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class) {
Mathieu Chartierc7853442015-03-27 14:35:38 -070051 declaring_class_ = GcRoot<mirror::Class>(new_declaring_class);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080052}
53
Ian Rogersef7d42f2014-01-06 12:55:46 -080054inline MemberOffset ArtField::GetOffsetDuringLinking() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080055 DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
Mathieu Chartierc7853442015-03-27 14:35:38 -070056 return MemberOffset(offset_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080057}
58
Mathieu Chartier3398c782016-09-30 10:27:43 -070059inline uint32_t ArtField::Get32(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -070060 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080061 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070062 if (UNLIKELY(IsVolatile())) {
63 return object->GetField32Volatile(GetOffset());
64 }
65 return object->GetField32(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080066}
67
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010068template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -070069inline void ArtField::Set32(ObjPtr<mirror::Object> object, uint32_t new_value) {
David Sehr709b0702016-10-13 09:12:37 -070070 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080071 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070072 if (UNLIKELY(IsVolatile())) {
73 object->SetField32Volatile<kTransactionActive>(GetOffset(), new_value);
74 } else {
75 object->SetField32<kTransactionActive>(GetOffset(), new_value);
76 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080077}
78
Mathieu Chartier3398c782016-09-30 10:27:43 -070079inline uint64_t ArtField::Get64(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -070080 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080081 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070082 if (UNLIKELY(IsVolatile())) {
83 return object->GetField64Volatile(GetOffset());
84 }
85 return object->GetField64(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080086}
87
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010088template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -070089inline void ArtField::Set64(ObjPtr<mirror::Object> object, uint64_t new_value) {
David Sehr709b0702016-10-13 09:12:37 -070090 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080091 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070092 if (UNLIKELY(IsVolatile())) {
93 object->SetField64Volatile<kTransactionActive>(GetOffset(), new_value);
94 } else {
95 object->SetField64<kTransactionActive>(GetOffset(), new_value);
96 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080097}
98
Mathieu Chartier3398c782016-09-30 10:27:43 -070099template<class MirrorType>
100inline ObjPtr<MirrorType> ArtField::GetObj(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700101 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800102 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700103 if (UNLIKELY(IsVolatile())) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700104 return object->GetFieldObjectVolatile<MirrorType>(GetOffset());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700105 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700106 return object->GetFieldObject<MirrorType>(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800107}
108
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100109template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700110inline void ArtField::SetObj(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> new_value) {
David Sehr709b0702016-10-13 09:12:37 -0700111 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800112 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700113 if (UNLIKELY(IsVolatile())) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700114 object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700115 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700116 object->SetFieldObject<kTransactionActive>(GetOffset(), new_value);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700117 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800118}
119
Fred Shih37f05ef2014-07-16 18:38:08 -0700120#define FIELD_GET(object, type) \
David Sehr709b0702016-10-13 09:12:37 -0700121 DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(); \
122 DCHECK((object) != nullptr) << PrettyField(); \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700123 DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700124 if (UNLIKELY(IsVolatile())) { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700125 return (object)->GetField ## type ## Volatile(GetOffset()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700126 } \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700127 return (object)->GetField ## type(GetOffset());
Fred Shih37f05ef2014-07-16 18:38:08 -0700128
129#define FIELD_SET(object, type, value) \
David Sehr709b0702016-10-13 09:12:37 -0700130 DCHECK((object) != nullptr) << PrettyField(); \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700131 DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700132 if (UNLIKELY(IsVolatile())) { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700133 (object)->SetField ## type ## Volatile<kTransactionActive>(GetOffset(), value); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700134 } else { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700135 (object)->SetField ## type<kTransactionActive>(GetOffset(), value); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700136 }
137
Mathieu Chartier3398c782016-09-30 10:27:43 -0700138inline uint8_t ArtField::GetBoolean(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700139 FIELD_GET(object, Boolean);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800140}
141
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100142template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700143inline void ArtField::SetBoolean(ObjPtr<mirror::Object> object, uint8_t z) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000144 if (kIsDebugBuild) {
145 // For simplicity, this method is being called by the compiler entrypoint for
146 // both boolean and byte fields.
147 Primitive::Type type = GetTypeAsPrimitiveType();
148 DCHECK(type == Primitive::kPrimBoolean || type == Primitive::kPrimByte) << PrettyField();
149 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700150 FIELD_SET(object, Boolean, z);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800151}
152
Mathieu Chartier3398c782016-09-30 10:27:43 -0700153inline int8_t ArtField::GetByte(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700154 FIELD_GET(object, Byte);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800155}
156
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100157template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700158inline void ArtField::SetByte(ObjPtr<mirror::Object> object, int8_t b) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000159 DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField();
Fred Shih37f05ef2014-07-16 18:38:08 -0700160 FIELD_SET(object, Byte, b);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800161}
162
Mathieu Chartier3398c782016-09-30 10:27:43 -0700163inline uint16_t ArtField::GetChar(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700164 FIELD_GET(object, Char);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800165}
166
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100167template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700168inline void ArtField::SetChar(ObjPtr<mirror::Object> object, uint16_t c) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000169 if (kIsDebugBuild) {
170 // For simplicity, this method is being called by the compiler entrypoint for
171 // both char and short fields.
172 Primitive::Type type = GetTypeAsPrimitiveType();
173 DCHECK(type == Primitive::kPrimChar || type == Primitive::kPrimShort) << PrettyField();
174 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700175 FIELD_SET(object, Char, c);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800176}
177
Mathieu Chartier3398c782016-09-30 10:27:43 -0700178inline int16_t ArtField::GetShort(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700179 FIELD_GET(object, Short);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800180}
181
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100182template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700183inline void ArtField::SetShort(ObjPtr<mirror::Object> object, int16_t s) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000184 DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField();
Fred Shih37f05ef2014-07-16 18:38:08 -0700185 FIELD_SET(object, Short, s);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800186}
187
Fred Shih37f05ef2014-07-16 18:38:08 -0700188#undef FIELD_GET
189#undef FIELD_SET
190
Mathieu Chartier3398c782016-09-30 10:27:43 -0700191inline int32_t ArtField::GetInt(ObjPtr<mirror::Object> object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100192 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000193 // For simplicity, this method is being called by the compiler entrypoint for
194 // both int and float fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700195 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700196 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100197 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800198 return Get32(object);
199}
200
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100201template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700202inline void ArtField::SetInt(ObjPtr<mirror::Object> object, int32_t i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100203 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000204 // For simplicity, this method is being called by the compiler entrypoint for
205 // both int and float fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700206 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700207 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100208 }
209 Set32<kTransactionActive>(object, i);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800210}
211
Mathieu Chartier3398c782016-09-30 10:27:43 -0700212inline int64_t ArtField::GetLong(ObjPtr<mirror::Object> object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100213 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000214 // For simplicity, this method is being called by the compiler entrypoint for
215 // both long and double fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700216 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700217 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100218 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800219 return Get64(object);
220}
221
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100222template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700223inline void ArtField::SetLong(ObjPtr<mirror::Object> object, int64_t j) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100224 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000225 // For simplicity, this method is being called by the compiler entrypoint for
226 // both long and double fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700227 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700228 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100229 }
230 Set64<kTransactionActive>(object, j);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800231}
232
Mathieu Chartier3398c782016-09-30 10:27:43 -0700233inline float ArtField::GetFloat(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700234 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800235 JValue bits;
236 bits.SetI(Get32(object));
237 return bits.GetF();
238}
239
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100240template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700241inline void ArtField::SetFloat(ObjPtr<mirror::Object> object, float f) {
David Sehr709b0702016-10-13 09:12:37 -0700242 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800243 JValue bits;
244 bits.SetF(f);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100245 Set32<kTransactionActive>(object, bits.GetI());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800246}
247
Mathieu Chartier3398c782016-09-30 10:27:43 -0700248inline double ArtField::GetDouble(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700249 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800250 JValue bits;
251 bits.SetJ(Get64(object));
252 return bits.GetD();
253}
254
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100255template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700256inline void ArtField::SetDouble(ObjPtr<mirror::Object> object, double d) {
David Sehr709b0702016-10-13 09:12:37 -0700257 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800258 JValue bits;
259 bits.SetD(d);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100260 Set64<kTransactionActive>(object, bits.GetJ());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800261}
262
Mathieu Chartier3398c782016-09-30 10:27:43 -0700263inline ObjPtr<mirror::Object> ArtField::GetObject(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700264 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800265 return GetObj(object);
266}
267
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100268template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700269inline void ArtField::SetObject(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> l) {
David Sehr709b0702016-10-13 09:12:37 -0700270 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100271 SetObj<kTransactionActive>(object, l);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800272}
273
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700274inline const char* ArtField::GetName() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700275 uint32_t field_index = GetDexFieldIndex();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000276 if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700277 DCHECK(IsStatic());
278 DCHECK_LT(field_index, 2U);
279 return field_index == 0 ? "interfaces" : "throws";
280 }
281 const DexFile* dex_file = GetDexFile();
282 return dex_file->GetFieldName(dex_file->GetFieldId(field_index));
283}
284
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700285inline const char* ArtField::GetTypeDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700286 uint32_t field_index = GetDexFieldIndex();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000287 if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700288 DCHECK(IsStatic());
289 DCHECK_LT(field_index, 2U);
290 // 0 == Class[] interfaces; 1 == Class[][] throws;
291 return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
292 }
293 const DexFile* dex_file = GetDexFile();
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800294 const dex::FieldId& field_id = dex_file->GetFieldId(field_index);
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700295 return dex_file->GetFieldTypeDescriptor(field_id);
296}
297
298inline Primitive::Type ArtField::GetTypeAsPrimitiveType()
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700299 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700300 return Primitive::GetType(GetTypeDescriptor()[0]);
301}
302
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700303inline bool ArtField::IsPrimitiveType() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700304 return GetTypeAsPrimitiveType() != Primitive::kPrimNot;
305}
306
Vladimir Marko208f6702017-12-08 12:00:50 +0000307inline ObjPtr<mirror::Class> ArtField::LookupResolvedType() {
Vladimir Marko4098a7a2017-11-06 16:00:51 +0000308 ScopedAssertNoThreadSuspension ants(__FUNCTION__);
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100309 if (UNLIKELY(IsProxyField())) {
Vladimir Marko4098a7a2017-11-06 16:00:51 +0000310 return ProxyFindSystemClass(GetTypeDescriptor());
311 }
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000312 ObjPtr<mirror::Class> type = Runtime::Current()->GetClassLinker()->LookupResolvedType(
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100313 GetDexFile()->GetFieldId(GetDexFieldIndex()).type_idx_, this);
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000314 DCHECK(!Thread::Current()->IsExceptionPending());
315 return type;
Vladimir Marko4098a7a2017-11-06 16:00:51 +0000316}
317
318inline ObjPtr<mirror::Class> ArtField::ResolveType() {
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100319 if (UNLIKELY(IsProxyField())) {
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000320 return ProxyFindSystemClass(GetTypeDescriptor());
Ian Rogers08f1f502014-12-02 15:04:37 -0800321 }
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000322 ObjPtr<mirror::Class> type = Runtime::Current()->GetClassLinker()->ResolveType(
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100323 GetDexFile()->GetFieldId(GetDexFieldIndex()).type_idx_, this);
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000324 DCHECK_EQ(type == nullptr, Thread::Current()->IsExceptionPending());
Ian Rogers08f1f502014-12-02 15:04:37 -0800325 return type;
326}
327
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700328inline size_t ArtField::FieldSize() REQUIRES_SHARED(Locks::mutator_lock_) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700329 return Primitive::ComponentSize(GetTypeAsPrimitiveType());
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700330}
331
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100332template <ReadBarrierOption kReadBarrierOption>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700333inline ObjPtr<mirror::DexCache> ArtField::GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100334 ObjPtr<mirror::Class> klass = GetDeclaringClass<kReadBarrierOption>();
335 return klass->GetDexCache<kDefaultVerifyFlags, kReadBarrierOption>();
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700336}
337
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700338inline const DexFile* ArtField::GetDexFile() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100339 return GetDexCache<kWithoutReadBarrier>()->GetDexFile();
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700340}
341
Vladimir Marko18090d12018-06-01 16:53:12 +0100342inline ObjPtr<mirror::String> ArtField::ResolveNameString() {
343 uint32_t dex_field_index = GetDexFieldIndex();
Andreas Gampee2abbc62017-09-15 11:59:26 -0700344 CHECK_NE(dex_field_index, dex::kDexNoIndex);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800345 const dex::FieldId& field_id = GetDexFile()->GetFieldId(dex_field_index);
Vladimir Marko18090d12018-06-01 16:53:12 +0100346 return Runtime::Current()->GetClassLinker()->ResolveString(field_id.name_idx_, this);
Mathieu Chartier76433272014-09-26 14:32:37 -0700347}
348
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800349template <typename Visitor>
350inline void ArtField::UpdateObjects(const Visitor& visitor) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700351 ObjPtr<mirror::Class> old_class = DeclaringClassRoot().Read<kWithoutReadBarrier>();
Mathieu Chartier1cc62e42016-10-03 18:01:28 -0700352 ObjPtr<mirror::Class> new_class = visitor(old_class.Ptr());
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800353 if (old_class != new_class) {
354 SetDeclaringClass(new_class);
355 }
356}
357
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700358// If kExactOffset is true then we only find the matching offset, not the field containing the
359// offset.
360template <bool kExactOffset>
361static inline ArtField* FindFieldWithOffset(
362 const IterationRange<StrideIterator<ArtField>>& fields,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700363 uint32_t field_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700364 for (ArtField& field : fields) {
365 if (kExactOffset) {
366 if (field.GetOffset().Uint32Value() == field_offset) {
367 return &field;
368 }
369 } else {
370 const uint32_t offset = field.GetOffset().Uint32Value();
371 Primitive::Type type = field.GetTypeAsPrimitiveType();
372 const size_t field_size = Primitive::ComponentSize(type);
373 DCHECK_GT(field_size, 0u);
374 if (offset <= field_offset && field_offset < offset + field_size) {
375 return &field;
376 }
377 }
378 }
379 return nullptr;
380}
381
382template <bool kExactOffset>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700383inline ArtField* ArtField::FindInstanceFieldWithOffset(ObjPtr<mirror::Class> klass,
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700384 uint32_t field_offset) {
385 DCHECK(klass != nullptr);
386 ArtField* field = FindFieldWithOffset<kExactOffset>(klass->GetIFields(), field_offset);
387 if (field != nullptr) {
388 return field;
389 }
390 // We did not find field in the class: look into superclass.
391 return (klass->GetSuperClass() != nullptr) ?
392 FindInstanceFieldWithOffset<kExactOffset>(klass->GetSuperClass(), field_offset) : nullptr;
393}
394
395template <bool kExactOffset>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700396inline ArtField* ArtField::FindStaticFieldWithOffset(ObjPtr<mirror::Class> klass,
397 uint32_t field_offset) {
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700398 DCHECK(klass != nullptr);
399 return FindFieldWithOffset<kExactOffset>(klass->GetSFields(), field_offset);
400}
401
Andreas Gampe4835d212018-11-21 14:55:10 -0800402inline mirror::ClassLoader* ArtField::GetClassLoader() {
403 return GetDeclaringClass()->GetClassLoader();
404}
405
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800406} // namespace art
407
Mathieu Chartierc7853442015-03-27 14:35:38 -0700408#endif // ART_RUNTIME_ART_FIELD_INL_H_