blob: 03425cc3009393cbb0fb5867dacd333bc1e6978a [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
Brian Carlstromea46f952013-07-30 01:26:50 -070017#ifndef ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
18#define ART_RUNTIME_MIRROR_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 Rogers22d5e732014-07-15 22:23:51 -070023#include "dex_cache.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070024#include "gc/accounting/card_table-inl.h"
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080025#include "jvalue.h"
26#include "object-inl.h"
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080027#include "primitive.h"
Mathieu Chartier76433272014-09-26 14:32:37 -070028#include "thread-inl.h"
29#include "scoped_thread_state_change.h"
30#include "well_known_classes.h"
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080031
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080032namespace art {
33namespace mirror {
34
Mingyao Yang98d1cc82014-05-15 17:02:16 -070035inline uint32_t ArtField::ClassSize() {
36 uint32_t vtable_entries = Object::kVTableLength + 6;
Fred Shih37f05ef2014-07-16 18:38:08 -070037 return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0);
Mingyao Yang98d1cc82014-05-15 17:02:16 -070038}
39
Ian Rogersef7d42f2014-01-06 12:55:46 -080040inline Class* ArtField::GetDeclaringClass() {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070041 Class* result = GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(ArtField, declaring_class_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080042 DCHECK(result != NULL);
43 DCHECK(result->IsLoaded() || result->IsErroneous());
44 return result;
45}
46
Brian Carlstromea46f952013-07-30 01:26:50 -070047inline void ArtField::SetDeclaringClass(Class *new_declaring_class) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070048 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, declaring_class_), new_declaring_class);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080049}
50
Ian Rogersef7d42f2014-01-06 12:55:46 -080051inline uint32_t ArtField::GetAccessFlags() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080052 DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070053 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, access_flags_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080054}
55
Ian Rogersef7d42f2014-01-06 12:55:46 -080056inline MemberOffset ArtField::GetOffset() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080057 DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070058 return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_)));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080059}
60
Ian Rogersef7d42f2014-01-06 12:55:46 -080061inline MemberOffset ArtField::GetOffsetDuringLinking() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080062 DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070063 return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_)));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080064}
65
Ian Rogersef7d42f2014-01-06 12:55:46 -080066inline uint32_t ArtField::Get32(Object* object) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070067 DCHECK(object != nullptr) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080068 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070069 if (UNLIKELY(IsVolatile())) {
70 return object->GetField32Volatile(GetOffset());
71 }
72 return object->GetField32(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080073}
74
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010075template<bool kTransactionActive>
Ian Rogersef7d42f2014-01-06 12:55:46 -080076inline void ArtField::Set32(Object* object, uint32_t new_value) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070077 DCHECK(object != nullptr) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080078 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070079 if (UNLIKELY(IsVolatile())) {
80 object->SetField32Volatile<kTransactionActive>(GetOffset(), new_value);
81 } else {
82 object->SetField32<kTransactionActive>(GetOffset(), new_value);
83 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080084}
85
Ian Rogersef7d42f2014-01-06 12:55:46 -080086inline uint64_t ArtField::Get64(Object* object) {
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080087 DCHECK(object != NULL) << PrettyField(this);
88 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070089 if (UNLIKELY(IsVolatile())) {
90 return object->GetField64Volatile(GetOffset());
91 }
92 return object->GetField64(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080093}
94
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010095template<bool kTransactionActive>
Ian Rogersef7d42f2014-01-06 12:55:46 -080096inline void ArtField::Set64(Object* object, uint64_t new_value) {
Ian Rogersc0fa3ad2013-02-05 00:11:55 -080097 DCHECK(object != NULL) << PrettyField(this);
98 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070099 if (UNLIKELY(IsVolatile())) {
100 object->SetField64Volatile<kTransactionActive>(GetOffset(), new_value);
101 } else {
102 object->SetField64<kTransactionActive>(GetOffset(), new_value);
103 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800104}
105
Ian Rogersef7d42f2014-01-06 12:55:46 -0800106inline Object* ArtField::GetObj(Object* object) {
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800107 DCHECK(object != NULL) << PrettyField(this);
108 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700109 if (UNLIKELY(IsVolatile())) {
110 return object->GetFieldObjectVolatile<Object>(GetOffset());
111 }
112 return object->GetFieldObject<Object>(GetOffset());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800113}
114
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100115template<bool kTransactionActive>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800116inline void ArtField::SetObj(Object* object, Object* new_value) {
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800117 DCHECK(object != NULL) << PrettyField(this);
118 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700119 if (UNLIKELY(IsVolatile())) {
120 object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value);
121 } else {
122 object->SetFieldObject<kTransactionActive>(GetOffset(), new_value);
123 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800124}
125
Fred Shih37f05ef2014-07-16 18:38:08 -0700126#define FIELD_GET(object, type) \
127 DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(this); \
128 DCHECK(object != nullptr) << PrettyField(this); \
129 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
130 if (UNLIKELY(IsVolatile())) { \
131 return object->GetField ## type ## Volatile(GetOffset()); \
132 } \
133 return object->GetField ## type(GetOffset());
134
135#define FIELD_SET(object, type, value) \
136 DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(this); \
137 DCHECK(object != nullptr) << PrettyField(this); \
138 DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
139 if (UNLIKELY(IsVolatile())) { \
140 object->SetField ## type ## Volatile<kTransactionActive>(GetOffset(), value); \
141 } else { \
142 object->SetField ## type<kTransactionActive>(GetOffset(), value); \
143 }
144
145inline uint8_t ArtField::GetBoolean(Object* object) {
146 FIELD_GET(object, Boolean);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800147}
148
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100149template<bool kTransactionActive>
Fred Shih37f05ef2014-07-16 18:38:08 -0700150inline void ArtField::SetBoolean(Object* object, uint8_t z) {
151 FIELD_SET(object, Boolean, z);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800152}
153
Ian Rogersef7d42f2014-01-06 12:55:46 -0800154inline int8_t ArtField::GetByte(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>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800159inline void ArtField::SetByte(Object* object, int8_t b) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700160 FIELD_SET(object, Byte, b);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800161}
162
Ian Rogersef7d42f2014-01-06 12:55:46 -0800163inline uint16_t ArtField::GetChar(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>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800168inline void ArtField::SetChar(Object* object, uint16_t c) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700169 FIELD_SET(object, Char, c);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800170}
171
Ian Rogersef7d42f2014-01-06 12:55:46 -0800172inline int16_t ArtField::GetShort(Object* object) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700173 FIELD_GET(object, Short);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800174}
175
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100176template<bool kTransactionActive>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800177inline void ArtField::SetShort(Object* object, int16_t s) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700178 FIELD_SET(object, Short, s);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800179}
180
Fred Shih37f05ef2014-07-16 18:38:08 -0700181#undef FIELD_GET
182#undef FIELD_SET
183
Ian Rogersef7d42f2014-01-06 12:55:46 -0800184inline int32_t ArtField::GetInt(Object* object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100185 if (kIsDebugBuild) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700186 Primitive::Type type = GetTypeAsPrimitiveType();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100187 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
188 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800189 return Get32(object);
190}
191
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100192template<bool kTransactionActive>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800193inline void ArtField::SetInt(Object* object, int32_t i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100194 if (kIsDebugBuild) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700195 Primitive::Type type = GetTypeAsPrimitiveType();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100196 CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
197 }
198 Set32<kTransactionActive>(object, i);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800199}
200
Ian Rogersef7d42f2014-01-06 12:55:46 -0800201inline int64_t ArtField::GetLong(Object* object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100202 if (kIsDebugBuild) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700203 Primitive::Type type = GetTypeAsPrimitiveType();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100204 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
205 }
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800206 return Get64(object);
207}
208
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100209template<bool kTransactionActive>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800210inline void ArtField::SetLong(Object* object, int64_t j) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100211 if (kIsDebugBuild) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700212 Primitive::Type type = GetTypeAsPrimitiveType();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100213 CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
214 }
215 Set64<kTransactionActive>(object, j);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800216}
217
Ian Rogersef7d42f2014-01-06 12:55:46 -0800218inline float ArtField::GetFloat(Object* object) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700219 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800220 JValue bits;
221 bits.SetI(Get32(object));
222 return bits.GetF();
223}
224
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100225template<bool kTransactionActive>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800226inline void ArtField::SetFloat(Object* object, float f) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700227 DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800228 JValue bits;
229 bits.SetF(f);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100230 Set32<kTransactionActive>(object, bits.GetI());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800231}
232
Ian Rogersef7d42f2014-01-06 12:55:46 -0800233inline double ArtField::GetDouble(Object* object) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700234 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800235 JValue bits;
236 bits.SetJ(Get64(object));
237 return bits.GetD();
238}
239
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100240template<bool kTransactionActive>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800241inline void ArtField::SetDouble(Object* object, double d) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700242 DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800243 JValue bits;
244 bits.SetD(d);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100245 Set64<kTransactionActive>(object, bits.GetJ());
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800246}
247
Ian Rogersef7d42f2014-01-06 12:55:46 -0800248inline Object* ArtField::GetObject(Object* object) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700249 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800250 return GetObj(object);
251}
252
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100253template<bool kTransactionActive>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800254inline void ArtField::SetObject(Object* object, Object* l) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700255 DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100256 SetObj<kTransactionActive>(object, l);
Ian Rogersc0fa3ad2013-02-05 00:11:55 -0800257}
258
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700259inline const char* ArtField::GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
260 uint32_t field_index = GetDexFieldIndex();
261 if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
262 DCHECK(IsStatic());
263 DCHECK_LT(field_index, 2U);
264 return field_index == 0 ? "interfaces" : "throws";
265 }
266 const DexFile* dex_file = GetDexFile();
267 return dex_file->GetFieldName(dex_file->GetFieldId(field_index));
268}
269
270inline const char* ArtField::GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
271 uint32_t field_index = GetDexFieldIndex();
272 if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
273 DCHECK(IsStatic());
274 DCHECK_LT(field_index, 2U);
275 // 0 == Class[] interfaces; 1 == Class[][] throws;
276 return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
277 }
278 const DexFile* dex_file = GetDexFile();
279 const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
280 return dex_file->GetFieldTypeDescriptor(field_id);
281}
282
283inline Primitive::Type ArtField::GetTypeAsPrimitiveType()
284 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
285 return Primitive::GetType(GetTypeDescriptor()[0]);
286}
287
288inline bool ArtField::IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
289 return GetTypeAsPrimitiveType() != Primitive::kPrimNot;
290}
291
292inline size_t ArtField::FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700293 return Primitive::ComponentSize(GetTypeAsPrimitiveType());
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700294}
295
296inline mirror::DexCache* ArtField::GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
297 return GetDeclaringClass()->GetDexCache();
298}
299
300inline const DexFile* ArtField::GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
301 return GetDexCache()->GetDexFile();
302}
303
Mathieu Chartier76433272014-09-26 14:32:37 -0700304inline ArtField* ArtField::FromReflectedField(const ScopedObjectAccessAlreadyRunnable& soa,
305 jobject jlr_field) {
306 mirror::ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_reflect_Field_artField);
307 mirror::ArtField* field = f->GetObject(soa.Decode<mirror::Object*>(jlr_field))->AsArtField();
308 DCHECK(field != nullptr);
309 return field;
310}
311
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800312} // namespace mirror
313} // namespace art
314
Brian Carlstromea46f952013-07-30 01:26:50 -0700315#endif // ART_RUNTIME_MIRROR_ART_FIELD_INL_H_