blob: ae81ee8470daec36356bb69a976fe45d54619bef [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"
Ian Rogers1d54e732013-05-02 21:10:01 -070025#include "gc/accounting/card_table-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070026#include "gc_root-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"
Mathieu Chartier0795f232016-09-27 18:43:30 -070031#include "scoped_thread_state_change-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
Hiroshi Yamauchi7a62e672016-06-10 17:22:48 -070036template<ReadBarrierOption kReadBarrierOption>
Mathieu Chartier3398c782016-09-30 10:27:43 -070037inline ObjPtr<mirror::Class> ArtField::GetDeclaringClass() {
Hiroshi Yamauchi3f64f252015-06-12 18:35:06 -070038 GcRootSource gc_root_source(this);
Mathieu Chartier3398c782016-09-30 10:27:43 -070039 ObjPtr<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 Chartier3398c782016-09-30 10:27:43 -070045inline void ArtField::SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class) {
Mathieu Chartierc7853442015-03-27 14:35:38 -070046 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 MemberOffset ArtField::GetOffsetDuringLinking() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080050 DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
Mathieu Chartierc7853442015-03-27 14:35:38 -070051 return MemberOffset(offset_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080052}
53
Mathieu Chartier3398c782016-09-30 10:27:43 -070054inline uint32_t ArtField::Get32(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -070055 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080056 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070057 if (UNLIKELY(IsVolatile())) {
58 return object->GetField32Volatile(GetOffset());
59 }
60 return object->GetField32(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080061}
62
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010063template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -070064inline void ArtField::Set32(ObjPtr<mirror::Object> object, uint32_t new_value) {
David Sehr709b0702016-10-13 09:12:37 -070065 DCHECK(object != nullptr) << PrettyField();
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 object->SetField32Volatile<kTransactionActive>(GetOffset(), new_value);
69 } else {
70 object->SetField32<kTransactionActive>(GetOffset(), new_value);
71 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080072}
73
Mathieu Chartier3398c782016-09-30 10:27:43 -070074inline uint64_t ArtField::Get64(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -070075 DCHECK(object != nullptr) << PrettyField();
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 return object->GetField64Volatile(GetOffset());
79 }
80 return object->GetField64(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080081}
82
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010083template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -070084inline void ArtField::Set64(ObjPtr<mirror::Object> object, uint64_t new_value) {
David Sehr709b0702016-10-13 09:12:37 -070085 DCHECK(object != nullptr) << PrettyField();
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 object->SetField64Volatile<kTransactionActive>(GetOffset(), new_value);
89 } else {
90 object->SetField64<kTransactionActive>(GetOffset(), new_value);
91 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080092}
93
Mathieu Chartier3398c782016-09-30 10:27:43 -070094template<class MirrorType>
95inline ObjPtr<MirrorType> ArtField::GetObj(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -070096 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080097 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070098 if (UNLIKELY(IsVolatile())) {
Mathieu Chartier3398c782016-09-30 10:27:43 -070099 return object->GetFieldObjectVolatile<MirrorType>(GetOffset());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700100 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700101 return object->GetFieldObject<MirrorType>(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800102}
103
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100104template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700105inline void ArtField::SetObj(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> new_value) {
David Sehr709b0702016-10-13 09:12:37 -0700106 DCHECK(object != nullptr) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800107 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700108 if (UNLIKELY(IsVolatile())) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700109 object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700110 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700111 object->SetFieldObject<kTransactionActive>(GetOffset(), new_value);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700112 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800113}
114
Fred Shih37f05ef2014-07-16 18:38:08 -0700115#define FIELD_GET(object, type) \
David Sehr709b0702016-10-13 09:12:37 -0700116 DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(); \
117 DCHECK((object) != nullptr) << PrettyField(); \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700118 DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700119 if (UNLIKELY(IsVolatile())) { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700120 return (object)->GetField ## type ## Volatile(GetOffset()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700121 } \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700122 return (object)->GetField ## type(GetOffset());
Fred Shih37f05ef2014-07-16 18:38:08 -0700123
124#define FIELD_SET(object, type, value) \
David Sehr709b0702016-10-13 09:12:37 -0700125 DCHECK((object) != nullptr) << PrettyField(); \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700126 DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700127 if (UNLIKELY(IsVolatile())) { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700128 (object)->SetField ## type ## Volatile<kTransactionActive>(GetOffset(), value); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700129 } else { \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700130 (object)->SetField ## type<kTransactionActive>(GetOffset(), value); \
Fred Shih37f05ef2014-07-16 18:38:08 -0700131 }
132
Mathieu Chartier3398c782016-09-30 10:27:43 -0700133inline uint8_t ArtField::GetBoolean(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700134 FIELD_GET(object, Boolean);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800135}
136
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100137template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700138inline void ArtField::SetBoolean(ObjPtr<mirror::Object> object, uint8_t z) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000139 if (kIsDebugBuild) {
140 // For simplicity, this method is being called by the compiler entrypoint for
141 // both boolean and byte fields.
142 Primitive::Type type = GetTypeAsPrimitiveType();
143 DCHECK(type == Primitive::kPrimBoolean || type == Primitive::kPrimByte) << PrettyField();
144 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700145 FIELD_SET(object, Boolean, z);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800146}
147
Mathieu Chartier3398c782016-09-30 10:27:43 -0700148inline int8_t ArtField::GetByte(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700149 FIELD_GET(object, Byte);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800150}
151
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100152template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700153inline void ArtField::SetByte(ObjPtr<mirror::Object> object, int8_t b) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000154 DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField();
Fred Shih37f05ef2014-07-16 18:38:08 -0700155 FIELD_SET(object, Byte, b);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800156}
157
Mathieu Chartier3398c782016-09-30 10:27:43 -0700158inline uint16_t ArtField::GetChar(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700159 FIELD_GET(object, Char);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800160}
161
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100162template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700163inline void ArtField::SetChar(ObjPtr<mirror::Object> object, uint16_t c) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000164 if (kIsDebugBuild) {
165 // For simplicity, this method is being called by the compiler entrypoint for
166 // both char and short fields.
167 Primitive::Type type = GetTypeAsPrimitiveType();
168 DCHECK(type == Primitive::kPrimChar || type == Primitive::kPrimShort) << PrettyField();
169 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700170 FIELD_SET(object, Char, c);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800171}
172
Mathieu Chartier3398c782016-09-30 10:27:43 -0700173inline int16_t ArtField::GetShort(ObjPtr<mirror::Object> object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700174 FIELD_GET(object, Short);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800175}
176
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100177template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700178inline void ArtField::SetShort(ObjPtr<mirror::Object> object, int16_t s) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000179 DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField();
Fred Shih37f05ef2014-07-16 18:38:08 -0700180 FIELD_SET(object, Short, s);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800181}
182
Fred Shih37f05ef2014-07-16 18:38:08 -0700183#undef FIELD_GET
184#undef FIELD_SET
185
Mathieu Chartier3398c782016-09-30 10:27:43 -0700186inline int32_t ArtField::GetInt(ObjPtr<mirror::Object> object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100187 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000188 // For simplicity, this method is being called by the compiler entrypoint for
189 // both int and float fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700190 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700191 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100192 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800193 return Get32(object);
194}
195
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100196template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700197inline void ArtField::SetInt(ObjPtr<mirror::Object> object, int32_t i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100198 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000199 // For simplicity, this method is being called by the compiler entrypoint for
200 // both int and float fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700201 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700202 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100203 }
204 Set32<kTransactionActive>(object, i);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800205}
206
Mathieu Chartier3398c782016-09-30 10:27:43 -0700207inline int64_t ArtField::GetLong(ObjPtr<mirror::Object> object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100208 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000209 // For simplicity, this method is being called by the compiler entrypoint for
210 // both long and double fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700211 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700212 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100213 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800214 return Get64(object);
215}
216
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100217template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700218inline void ArtField::SetLong(ObjPtr<mirror::Object> object, int64_t j) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100219 if (kIsDebugBuild) {
Nicolas Geoffray5b3c6c02017-01-19 14:22:26 +0000220 // For simplicity, this method is being called by the compiler entrypoint for
221 // both long and double fields.
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700222 Primitive::Type type = GetTypeAsPrimitiveType();
David Sehr709b0702016-10-13 09:12:37 -0700223 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100224 }
225 Set64<kTransactionActive>(object, j);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800226}
227
Mathieu Chartier3398c782016-09-30 10:27:43 -0700228inline float ArtField::GetFloat(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700229 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800230 JValue bits;
231 bits.SetI(Get32(object));
232 return bits.GetF();
233}
234
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100235template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700236inline void ArtField::SetFloat(ObjPtr<mirror::Object> object, float f) {
David Sehr709b0702016-10-13 09:12:37 -0700237 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800238 JValue bits;
239 bits.SetF(f);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100240 Set32<kTransactionActive>(object, bits.GetI());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800241}
242
Mathieu Chartier3398c782016-09-30 10:27:43 -0700243inline double ArtField::GetDouble(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700244 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800245 JValue bits;
246 bits.SetJ(Get64(object));
247 return bits.GetD();
248}
249
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100250template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700251inline void ArtField::SetDouble(ObjPtr<mirror::Object> object, double d) {
David Sehr709b0702016-10-13 09:12:37 -0700252 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800253 JValue bits;
254 bits.SetD(d);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100255 Set64<kTransactionActive>(object, bits.GetJ());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800256}
257
Mathieu Chartier3398c782016-09-30 10:27:43 -0700258inline ObjPtr<mirror::Object> ArtField::GetObject(ObjPtr<mirror::Object> object) {
David Sehr709b0702016-10-13 09:12:37 -0700259 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField();
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800260 return GetObj(object);
261}
262
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100263template<bool kTransactionActive>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700264inline void ArtField::SetObject(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> l) {
David Sehr709b0702016-10-13 09:12:37 -0700265 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100266 SetObj<kTransactionActive>(object, l);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800267}
268
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700269inline const char* ArtField::GetName() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700270 uint32_t field_index = GetDexFieldIndex();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000271 if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700272 DCHECK(IsStatic());
273 DCHECK_LT(field_index, 2U);
274 return field_index == 0 ? "interfaces" : "throws";
275 }
276 const DexFile* dex_file = GetDexFile();
277 return dex_file->GetFieldName(dex_file->GetFieldId(field_index));
278}
279
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700280inline const char* ArtField::GetTypeDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700281 uint32_t field_index = GetDexFieldIndex();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000282 if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700283 DCHECK(IsStatic());
284 DCHECK_LT(field_index, 2U);
285 // 0 == Class[] interfaces; 1 == Class[][] throws;
286 return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
287 }
288 const DexFile* dex_file = GetDexFile();
289 const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
290 return dex_file->GetFieldTypeDescriptor(field_id);
291}
292
293inline Primitive::Type ArtField::GetTypeAsPrimitiveType()
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700294 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700295 return Primitive::GetType(GetTypeDescriptor()[0]);
296}
297
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700298inline bool ArtField::IsPrimitiveType() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700299 return GetTypeAsPrimitiveType() != Primitive::kPrimNot;
300}
301
Vladimir Marko208f6702017-12-08 12:00:50 +0000302inline ObjPtr<mirror::Class> ArtField::LookupResolvedType() {
Vladimir Marko4098a7a2017-11-06 16:00:51 +0000303 ScopedAssertNoThreadSuspension ants(__FUNCTION__);
304 const uint32_t field_index = GetDexFieldIndex();
305 ObjPtr<mirror::Class> declaring_class = GetDeclaringClass();
306 if (UNLIKELY(declaring_class->IsProxyClass())) {
307 return ProxyFindSystemClass(GetTypeDescriptor());
308 }
309 ObjPtr<mirror::DexCache> dex_cache = declaring_class->GetDexCache();
310 const DexFile* const dex_file = dex_cache->GetDexFile();
311 dex::TypeIndex type_idx = dex_file->GetFieldId(field_index).type_idx_;
312 ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx);
313 if (UNLIKELY(type == nullptr)) {
314 type = Runtime::Current()->GetClassLinker()->LookupResolvedType(
315 *dex_file, type_idx, dex_cache, declaring_class->GetClassLoader());
316 DCHECK(!Thread::Current()->IsExceptionPending());
317 }
318 return type.Ptr();
319}
320
321inline ObjPtr<mirror::Class> ArtField::ResolveType() {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700322 const uint32_t field_index = GetDexFieldIndex();
Mathieu Chartier3398c782016-09-30 10:27:43 -0700323 ObjPtr<mirror::Class> declaring_class = GetDeclaringClass();
Nicolas Geoffray3a090922015-11-24 09:17:30 +0000324 if (UNLIKELY(declaring_class->IsProxyClass())) {
325 return ProxyFindSystemClass(GetTypeDescriptor());
Ian Rogers08f1f502014-12-02 15:04:37 -0800326 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700327 auto* dex_cache = declaring_class->GetDexCache();
328 const DexFile* const dex_file = dex_cache->GetDexFile();
Vladimir Marko4098a7a2017-11-06 16:00:51 +0000329 dex::TypeIndex type_idx = dex_file->GetFieldId(field_index).type_idx_;
330 ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx);
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000331 if (UNLIKELY(type == nullptr)) {
332 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Vladimir Marko4098a7a2017-11-06 16:00:51 +0000333 type = class_linker->ResolveType(*dex_file, type_idx, declaring_class);
334 DCHECK_EQ(type == nullptr, Thread::Current()->IsExceptionPending());
Ian Rogers08f1f502014-12-02 15:04:37 -0800335 }
336 return type;
337}
338
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700339inline size_t ArtField::FieldSize() REQUIRES_SHARED(Locks::mutator_lock_) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700340 return Primitive::ComponentSize(GetTypeAsPrimitiveType());
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700341}
342
Mathieu Chartier3398c782016-09-30 10:27:43 -0700343inline ObjPtr<mirror::DexCache> ArtField::GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700344 return GetDeclaringClass()->GetDexCache();
345}
346
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700347inline const DexFile* ArtField::GetDexFile() REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700348 return GetDexCache()->GetDexFile();
349}
350
Mathieu Chartier3398c782016-09-30 10:27:43 -0700351inline ObjPtr<mirror::String> ArtField::GetStringName(Thread* self, bool resolve) {
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700352 auto dex_field_index = GetDexFieldIndex();
Andreas Gampee2abbc62017-09-15 11:59:26 -0700353 CHECK_NE(dex_field_index, dex::kDexNoIndex);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700354 ObjPtr<mirror::DexCache> dex_cache = GetDexCache();
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700355 const auto* dex_file = dex_cache->GetDexFile();
356 const auto& field_id = dex_file->GetFieldId(dex_field_index);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700357 ObjPtr<mirror::String> name = dex_cache->GetResolvedString(field_id.name_idx_);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700358 if (resolve && name == nullptr) {
Vladimir Marko3481ba22015-04-13 12:22:36 +0100359 name = ResolveGetStringName(self, *dex_file, field_id.name_idx_, dex_cache);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700360 }
361 return name;
Mathieu Chartier76433272014-09-26 14:32:37 -0700362}
363
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800364template <typename Visitor>
365inline void ArtField::UpdateObjects(const Visitor& visitor) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700366 ObjPtr<mirror::Class> old_class = DeclaringClassRoot().Read<kWithoutReadBarrier>();
Mathieu Chartier1cc62e42016-10-03 18:01:28 -0700367 ObjPtr<mirror::Class> new_class = visitor(old_class.Ptr());
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800368 if (old_class != new_class) {
369 SetDeclaringClass(new_class);
370 }
371}
372
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700373// If kExactOffset is true then we only find the matching offset, not the field containing the
374// offset.
375template <bool kExactOffset>
376static inline ArtField* FindFieldWithOffset(
377 const IterationRange<StrideIterator<ArtField>>& fields,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700378 uint32_t field_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700379 for (ArtField& field : fields) {
380 if (kExactOffset) {
381 if (field.GetOffset().Uint32Value() == field_offset) {
382 return &field;
383 }
384 } else {
385 const uint32_t offset = field.GetOffset().Uint32Value();
386 Primitive::Type type = field.GetTypeAsPrimitiveType();
387 const size_t field_size = Primitive::ComponentSize(type);
388 DCHECK_GT(field_size, 0u);
389 if (offset <= field_offset && field_offset < offset + field_size) {
390 return &field;
391 }
392 }
393 }
394 return nullptr;
395}
396
397template <bool kExactOffset>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700398inline ArtField* ArtField::FindInstanceFieldWithOffset(ObjPtr<mirror::Class> klass,
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700399 uint32_t field_offset) {
400 DCHECK(klass != nullptr);
401 ArtField* field = FindFieldWithOffset<kExactOffset>(klass->GetIFields(), field_offset);
402 if (field != nullptr) {
403 return field;
404 }
405 // We did not find field in the class: look into superclass.
406 return (klass->GetSuperClass() != nullptr) ?
407 FindInstanceFieldWithOffset<kExactOffset>(klass->GetSuperClass(), field_offset) : nullptr;
408}
409
410template <bool kExactOffset>
Mathieu Chartier3398c782016-09-30 10:27:43 -0700411inline ArtField* ArtField::FindStaticFieldWithOffset(ObjPtr<mirror::Class> klass,
412 uint32_t field_offset) {
Mathieu Chartiercb044bc2016-04-01 13:56:41 -0700413 DCHECK(klass != nullptr);
414 return FindFieldWithOffset<kExactOffset>(klass->GetSFields(), field_offset);
415}
416
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800417} // namespace art
418
Mathieu Chartierc7853442015-03-27 14:35:38 -0700419#endif // ART_RUNTIME_ART_FIELD_INL_H_