blob: 99943f51d7eb575d79c52abeb8b2effe008c7fd0 [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"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070032#include "thread-current-inl.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
Vladimir Marko09c5ca42018-05-31 15:15:31 +010036inline bool ArtField::IsProxyField() {
Vladimir Marko415ac852019-03-21 12:49:10 +000037 // No read barrier needed, we're reading the constant declaring class only to read
38 // the constant proxy flag. See ReadBarrierOption.
Vladimir Marko09c5ca42018-05-31 15:15:31 +010039 return GetDeclaringClass<kWithoutReadBarrier>()->IsProxyClass<kVerifyNone>();
40}
41
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -070042template<ReadBarrierOption kReadBarrierOption>
Mathieu Chartier3398c782016-09-30 10:27:43 -070043inline ObjPtr<mirror::Class> ArtField::GetDeclaringClass() {
Hiroshi Yamauchi3f64f252015-06-12 18:35:06 -070044 GcRootSource gc_root_source(this);
Mathieu Chartier3398c782016-09-30 10:27:43 -070045 ObjPtr<mirror::Class> result = declaring_class_.Read<kReadBarrierOption>(&gc_root_source);
Mathieu Chartierc7853442015-03-27 14:35:38 -070046 DCHECK(result != nullptr);
Vladimir Marko09c5ca42018-05-31 15:15:31 +010047 DCHECK(result->IsIdxLoaded() || result->IsErroneous()) << result->GetStatus();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080048 return result;
49}
50
Mathieu Chartier3398c782016-09-30 10:27:43 -070051inline void ArtField::SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class) {
Mathieu Chartierc7853442015-03-27 14:35:38 -070052 declaring_class_ = GcRoot<mirror::Class>(new_declaring_class);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080053}
54
Ian Rogersef7d42f2014-01-06 12:55:46 -080055inline MemberOffset ArtField::GetOffsetDuringLinking() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080056 DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
Mathieu Chartierc7853442015-03-27 14:35:38 -070057 return MemberOffset(offset_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080058}
59
Mathieu Chartier3398c782016-09-30 10:27:43 -070060inline uint32_t ArtField::Get32(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -070061 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080062 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070063 if (UNLIKELY(IsVolatile())) {
64 return object->GetField32Volatile(GetOffset());
65 }
66 return object->GetField32(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080067}
68
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010069template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -070070inline void ArtField::Set32(ObjPtr<mirror::Object> object, uint32_t new_value) {
David Sehr709b0702016-10-13 09:12:37 -070071 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080072 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070073 if (UNLIKELY(IsVolatile())) {
74 object->SetField32Volatile<kTransactionActive>(GetOffset(), new_value);
75 } else {
76 object->SetField32<kTransactionActive>(GetOffset(), new_value);
77 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080078}
79
Mathieu Chartier3398c782016-09-30 10:27:43 -070080inline uint64_t ArtField::Get64(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -070081 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080082 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070083 if (UNLIKELY(IsVolatile())) {
84 return object->GetField64Volatile(GetOffset());
85 }
86 return object->GetField64(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080087}
88
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010089template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -070090inline void ArtField::Set64(ObjPtr<mirror::Object> object, uint64_t new_value) {
David Sehr709b0702016-10-13 09:12:37 -070091 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080092 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070093 if (UNLIKELY(IsVolatile())) {
94 object->SetField64Volatile<kTransactionActive>(GetOffset(), new_value);
95 } else {
96 object->SetField64<kTransactionActive>(GetOffset(), new_value);
97 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080098}
99
Mathieu Chartier3398c782016-09-30 10:27:43 -0700100template<class MirrorType>
101inline ObjPtr<MirrorType> ArtField::GetObj(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700102 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800103 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700104 if (UNLIKELY(IsVolatile())) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700105 return object->GetFieldObjectVolatile<MirrorType>(GetOffset());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700106 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700107 return object->GetFieldObject<MirrorType>(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800108}
109
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100110template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700111inline void ArtField::SetObj(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> new_value) {
David Sehr709b0702016-10-13 09:12:37 -0700112 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800113 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700114 if (UNLIKELY(IsVolatile())) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700115 object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700116 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700117 object->SetFieldObject<kTransactionActive>(GetOffset(), new_value);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700118 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800119}
120
Fred Shih37f05ef2014-07-16 18:38:08 -0700121#define FIELD_GET(object, type) \
David Sehr709b0702016-10-13 09:12:37 -0700122 DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(); \
123 DCHECK((object) != nullptr) << PrettyField(); \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700124 DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700125 if (UNLIKELY(IsVolatile())) { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700126 return (object)->GetField ## type ## Volatile(GetOffset()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700127 } \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700128 return (object)->GetField ## type(GetOffset());
Fred Shih37f05ef2014-07-16 18:38:08 -0700129
130#define FIELD_SET(object, type, value) \
David Sehr709b0702016-10-13 09:12:37 -0700131 DCHECK((object) != nullptr) << PrettyField(); \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700132 DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700133 if (UNLIKELY(IsVolatile())) { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700134 (object)->SetField ## type ## Volatile<kTransactionActive>(GetOffset(), value); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700135 } else { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700136 (object)->SetField ## type<kTransactionActive>(GetOffset(), value); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700137 }
138
Mathieu Chartier3398c782016-09-30 10:27:43 -0700139inline uint8_t ArtField::GetBoolean(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700140 FIELD_GET(object, Boolean);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800141}
142
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100143template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700144inline void ArtField::SetBoolean(ObjPtr<mirror::Object> object, uint8_t z) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000145 if (kIsDebugBuild) {
146 // For simplicity, this method is being called by the compiler entrypoint for
147 // both boolean and byte fields.
148 Primitive::Type type = GetTypeAsPrimitiveType();
149 DCHECK(type == Primitive::kPrimBoolean || type == Primitive::kPrimByte) << PrettyField();
150 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700151 FIELD_SET(object, Boolean, z);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800152}
153
Mathieu Chartier3398c782016-09-30 10:27:43 -0700154inline int8_t ArtField::GetByte(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700155 FIELD_GET(object, Byte);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800156}
157
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100158template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700159inline void ArtField::SetByte(ObjPtr<mirror::Object> object, int8_t b) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000160 DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField();
Fred Shih37f05ef2014-07-16 18:38:08 -0700161 FIELD_SET(object, Byte, b);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800162}
163
Mathieu Chartier3398c782016-09-30 10:27:43 -0700164inline uint16_t ArtField::GetChar(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700165 FIELD_GET(object, Char);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800166}
167
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100168template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700169inline void ArtField::SetChar(ObjPtr<mirror::Object> object, uint16_t c) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000170 if (kIsDebugBuild) {
171 // For simplicity, this method is being called by the compiler entrypoint for
172 // both char and short fields.
173 Primitive::Type type = GetTypeAsPrimitiveType();
174 DCHECK(type == Primitive::kPrimChar || type == Primitive::kPrimShort) << PrettyField();
175 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700176 FIELD_SET(object, Char, c);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800177}
178
Mathieu Chartier3398c782016-09-30 10:27:43 -0700179inline int16_t ArtField::GetShort(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700180 FIELD_GET(object, Short);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800181}
182
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100183template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700184inline void ArtField::SetShort(ObjPtr<mirror::Object> object, int16_t s) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000185 DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField();
Fred Shih37f05ef2014-07-16 18:38:08 -0700186 FIELD_SET(object, Short, s);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800187}
188
Fred Shih37f05ef2014-07-16 18:38:08 -0700189#undef FIELD_GET
190#undef FIELD_SET
191
Mathieu Chartier3398c782016-09-30 10:27:43 -0700192inline int32_t ArtField::GetInt(ObjPtr<mirror::Object> object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100193 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000194 // For simplicity, this method is being called by the compiler entrypoint for
195 // both int and float fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700196 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700197 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100198 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800199 return Get32(object);
200}
201
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100202template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700203inline void ArtField::SetInt(ObjPtr<mirror::Object> object, int32_t i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100204 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000205 // For simplicity, this method is being called by the compiler entrypoint for
206 // both int and float fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700207 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700208 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100209 }
210 Set32<kTransactionActive>(object, i);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800211}
212
Mathieu Chartier3398c782016-09-30 10:27:43 -0700213inline int64_t ArtField::GetLong(ObjPtr<mirror::Object> object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100214 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000215 // For simplicity, this method is being called by the compiler entrypoint for
216 // both long and double fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700217 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700218 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100219 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800220 return Get64(object);
221}
222
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100223template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700224inline void ArtField::SetLong(ObjPtr<mirror::Object> object, int64_t j) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100225 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000226 // For simplicity, this method is being called by the compiler entrypoint for
227 // both long and double fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700228 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700229 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100230 }
231 Set64<kTransactionActive>(object, j);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800232}
233
Mathieu Chartier3398c782016-09-30 10:27:43 -0700234inline float ArtField::GetFloat(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700235 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800236 JValue bits;
237 bits.SetI(Get32(object));
238 return bits.GetF();
239}
240
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100241template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700242inline void ArtField::SetFloat(ObjPtr<mirror::Object> object, float f) {
David Sehr709b0702016-10-13 09:12:37 -0700243 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800244 JValue bits;
245 bits.SetF(f);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100246 Set32<kTransactionActive>(object, bits.GetI());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800247}
248
Mathieu Chartier3398c782016-09-30 10:27:43 -0700249inline double ArtField::GetDouble(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700250 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800251 JValue bits;
252 bits.SetJ(Get64(object));
253 return bits.GetD();
254}
255
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100256template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700257inline void ArtField::SetDouble(ObjPtr<mirror::Object> object, double d) {
David Sehr709b0702016-10-13 09:12:37 -0700258 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800259 JValue bits;
260 bits.SetD(d);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100261 Set64<kTransactionActive>(object, bits.GetJ());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800262}
263
Mathieu Chartier3398c782016-09-30 10:27:43 -0700264inline ObjPtr<mirror::Object> ArtField::GetObject(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700265 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800266 return GetObj(object);
267}
268
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100269template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700270inline void ArtField::SetObject(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> l) {
David Sehr709b0702016-10-13 09:12:37 -0700271 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100272 SetObj<kTransactionActive>(object, l);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800273}
274
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700275inline const char* ArtField::GetName() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700276 uint32_t field_index = GetDexFieldIndex();
Vladimir Marko415ac852019-03-21 12:49:10 +0000277 if (UNLIKELY(IsProxyField())) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700278 DCHECK(IsStatic());
279 DCHECK_LT(field_index, 2U);
280 return field_index == 0 ? "interfaces" : "throws";
281 }
282 const DexFile* dex_file = GetDexFile();
283 return dex_file->GetFieldName(dex_file->GetFieldId(field_index));
284}
285
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700286inline const char* ArtField::GetTypeDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700287 uint32_t field_index = GetDexFieldIndex();
Vladimir Marko415ac852019-03-21 12:49:10 +0000288 if (UNLIKELY(IsProxyField())) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700289 DCHECK(IsStatic());
290 DCHECK_LT(field_index, 2U);
291 // 0 == Class[] interfaces; 1 == Class[][] throws;
292 return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
293 }
294 const DexFile* dex_file = GetDexFile();
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800295 const dex::FieldId& field_id = dex_file->GetFieldId(field_index);
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700296 return dex_file->GetFieldTypeDescriptor(field_id);
297}
298
299inline Primitive::Type ArtField::GetTypeAsPrimitiveType()
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700300 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700301 return Primitive::GetType(GetTypeDescriptor()[0]);
302}
303
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700304inline bool ArtField::IsPrimitiveType() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700305 return GetTypeAsPrimitiveType() != Primitive::kPrimNot;
306}
307
Vladimir Marko208f6702017-12-08 12:00:50 +0000308inline ObjPtr<mirror::Class> ArtField::LookupResolvedType() {
Vladimir Marko4098a7a2017-11-06 16:00:51 +0000309 ScopedAssertNoThreadSuspension ants(__FUNCTION__);
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100310 if (UNLIKELY(IsProxyField())) {
Vladimir Marko4098a7a2017-11-06 16:00:51 +0000311 return ProxyFindSystemClass(GetTypeDescriptor());
312 }
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000313 ObjPtr<mirror::Class> type = Runtime::Current()->GetClassLinker()->LookupResolvedType(
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100314 GetDexFile()->GetFieldId(GetDexFieldIndex()).type_idx_, this);
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000315 DCHECK(!Thread::Current()->IsExceptionPending());
316 return type;
Vladimir Marko4098a7a2017-11-06 16:00:51 +0000317}
318
319inline ObjPtr<mirror::Class> ArtField::ResolveType() {
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100320 if (UNLIKELY(IsProxyField())) {
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000321 return ProxyFindSystemClass(GetTypeDescriptor());
Ian Rogers08f1f502014-12-02 15:04:37 -0800322 }
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000323 ObjPtr<mirror::Class> type = Runtime::Current()->GetClassLinker()->ResolveType(
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100324 GetDexFile()->GetFieldId(GetDexFieldIndex()).type_idx_, this);
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000325 DCHECK_EQ(type == nullptr, Thread::Current()->IsExceptionPending());
Ian Rogers08f1f502014-12-02 15:04:37 -0800326 return type;
327}
328
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700329inline size_t ArtField::FieldSize() REQUIRES_SHARED(Locks::mutator_lock_) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700330 return Primitive::ComponentSize(GetTypeAsPrimitiveType());
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700331}
332
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100333template <ReadBarrierOption kReadBarrierOption>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700334inline ObjPtr<mirror::DexCache> ArtField::GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100335 ObjPtr<mirror::Class> klass = GetDeclaringClass<kReadBarrierOption>();
336 return klass->GetDexCache<kDefaultVerifyFlags, kReadBarrierOption>();
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700337}
338
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700339inline const DexFile* ArtField::GetDexFile() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100340 return GetDexCache<kWithoutReadBarrier>()->GetDexFile();
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700341}
342
Vladimir Marko18090d12018-06-01 16:53:12 +0100343inline ObjPtr<mirror::String> ArtField::ResolveNameString() {
344 uint32_t dex_field_index = GetDexFieldIndex();
Andreas Gampee2abbc62017-09-15 11:59:26 -0700345 CHECK_NE(dex_field_index, dex::kDexNoIndex);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800346 const dex::FieldId& field_id = GetDexFile()->GetFieldId(dex_field_index);
Vladimir Marko18090d12018-06-01 16:53:12 +0100347 return Runtime::Current()->GetClassLinker()->ResolveString(field_id.name_idx_, this);
Mathieu Chartier76433272014-09-26 14:32:37 -0700348}
349
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800350template <typename Visitor>
351inline void ArtField::UpdateObjects(const Visitor& visitor) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700352 ObjPtr<mirror::Class> old_class = DeclaringClassRoot().Read<kWithoutReadBarrier>();
Mathieu Chartier1cc62e42016-10-03 18:01:28 -0700353 ObjPtr<mirror::Class> new_class = visitor(old_class.Ptr());
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800354 if (old_class != new_class) {
355 SetDeclaringClass(new_class);
356 }
357}
358
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700359// If kExactOffset is true then we only find the matching offset, not the field containing the
360// offset.
361template <bool kExactOffset>
362static inline ArtField* FindFieldWithOffset(
363 const IterationRange<StrideIterator<ArtField>>& fields,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700364 uint32_t field_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700365 for (ArtField& field : fields) {
366 if (kExactOffset) {
367 if (field.GetOffset().Uint32Value() == field_offset) {
368 return &field;
369 }
370 } else {
371 const uint32_t offset = field.GetOffset().Uint32Value();
372 Primitive::Type type = field.GetTypeAsPrimitiveType();
373 const size_t field_size = Primitive::ComponentSize(type);
374 DCHECK_GT(field_size, 0u);
375 if (offset <= field_offset && field_offset < offset + field_size) {
376 return &field;
377 }
378 }
379 }
380 return nullptr;
381}
382
383template <bool kExactOffset>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700384inline ArtField* ArtField::FindInstanceFieldWithOffset(ObjPtr<mirror::Class> klass,
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700385 uint32_t field_offset) {
386 DCHECK(klass != nullptr);
387 ArtField* field = FindFieldWithOffset<kExactOffset>(klass->GetIFields(), field_offset);
388 if (field != nullptr) {
389 return field;
390 }
391 // We did not find field in the class: look into superclass.
392 return (klass->GetSuperClass() != nullptr) ?
393 FindInstanceFieldWithOffset<kExactOffset>(klass->GetSuperClass(), field_offset) : nullptr;
394}
395
396template <bool kExactOffset>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700397inline ArtField* ArtField::FindStaticFieldWithOffset(ObjPtr<mirror::Class> klass,
398 uint32_t field_offset) {
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700399 DCHECK(klass != nullptr);
400 return FindFieldWithOffset<kExactOffset>(klass->GetSFields(), field_offset);
401}
402
Andreas Gampe4835d212018-11-21 14:55:10 -0800403inline mirror::ClassLoader* ArtField::GetClassLoader() {
404 return GetDeclaringClass()->GetClassLoader();
405}
406
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800407} // namespace art
408
Mathieu Chartierc7853442015-03-27 14:35:38 -0700409#endif // ART_RUNTIME_ART_FIELD_INL_H_