art_field-inl.h revision ffc788cb7b5b9f53734d7bb8af2d5e45d885546b
1/*
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
17#ifndef ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
18#define ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
19
20#include "art_field.h"
21
22#include "base/logging.h"
23#include "dex_cache.h"
24#include "gc/accounting/card_table-inl.h"
25#include "jvalue.h"
26#include "object-inl.h"
27#include "primitive.h"
28#include "scoped_thread_state_change.h"
29#include "well_known_classes.h"
30
31namespace art {
32namespace mirror {
33
34inline uint32_t ArtField::ClassSize() {
35  uint32_t vtable_entries = Object::kVTableLength + 6;
36  return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0);
37}
38
39inline Class* ArtField::GetDeclaringClass() {
40  Class* result = GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(ArtField, declaring_class_));
41  DCHECK(result != NULL);
42  DCHECK(result->IsLoaded() || result->IsErroneous());
43  return result;
44}
45
46inline void ArtField::SetDeclaringClass(Class *new_declaring_class) {
47  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, declaring_class_), new_declaring_class);
48}
49
50inline uint32_t ArtField::GetAccessFlags() {
51  DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
52  return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, access_flags_));
53}
54
55inline MemberOffset ArtField::GetOffset() {
56  DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
57  return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_)));
58}
59
60inline MemberOffset ArtField::GetOffsetDuringLinking() {
61  DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
62  return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_)));
63}
64
65inline uint32_t ArtField::Get32(Object* object) {
66  DCHECK(object != nullptr) << PrettyField(this);
67  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
68  if (UNLIKELY(IsVolatile())) {
69    return object->GetField32Volatile(GetOffset());
70  }
71  return object->GetField32(GetOffset());
72}
73
74template<bool kTransactionActive>
75inline void ArtField::Set32(Object* object, uint32_t new_value) {
76  DCHECK(object != nullptr) << PrettyField(this);
77  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
78  if (UNLIKELY(IsVolatile())) {
79    object->SetField32Volatile<kTransactionActive>(GetOffset(), new_value);
80  } else {
81    object->SetField32<kTransactionActive>(GetOffset(), new_value);
82  }
83}
84
85inline uint64_t ArtField::Get64(Object* object) {
86  DCHECK(object != NULL) << PrettyField(this);
87  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
88  if (UNLIKELY(IsVolatile())) {
89    return object->GetField64Volatile(GetOffset());
90  }
91  return object->GetField64(GetOffset());
92}
93
94template<bool kTransactionActive>
95inline void ArtField::Set64(Object* object, uint64_t new_value) {
96  DCHECK(object != NULL) << PrettyField(this);
97  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
98  if (UNLIKELY(IsVolatile())) {
99    object->SetField64Volatile<kTransactionActive>(GetOffset(), new_value);
100  } else {
101    object->SetField64<kTransactionActive>(GetOffset(), new_value);
102  }
103}
104
105inline Object* ArtField::GetObj(Object* object) {
106  DCHECK(object != NULL) << PrettyField(this);
107  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
108  if (UNLIKELY(IsVolatile())) {
109    return object->GetFieldObjectVolatile<Object>(GetOffset());
110  }
111  return object->GetFieldObject<Object>(GetOffset());
112}
113
114template<bool kTransactionActive>
115inline void ArtField::SetObj(Object* object, Object* new_value) {
116  DCHECK(object != NULL) << PrettyField(this);
117  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
118  if (UNLIKELY(IsVolatile())) {
119    object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value);
120  } else {
121    object->SetFieldObject<kTransactionActive>(GetOffset(), new_value);
122  }
123}
124
125inline bool ArtField::GetBoolean(Object* object) {
126  DCHECK_EQ(Primitive::kPrimBoolean, GetTypeAsPrimitiveType()) << PrettyField(this);
127  return Get32(object);
128}
129
130template<bool kTransactionActive>
131inline void ArtField::SetBoolean(Object* object, bool z) {
132  DCHECK_EQ(Primitive::kPrimBoolean, GetTypeAsPrimitiveType()) << PrettyField(this);
133  Set32<kTransactionActive>(object, z);
134}
135
136inline int8_t ArtField::GetByte(Object* object) {
137  DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField(this);
138  return Get32(object);
139}
140
141template<bool kTransactionActive>
142inline void ArtField::SetByte(Object* object, int8_t b) {
143  DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField(this);
144  Set32<kTransactionActive>(object, b);
145}
146
147inline uint16_t ArtField::GetChar(Object* object) {
148  DCHECK_EQ(Primitive::kPrimChar, GetTypeAsPrimitiveType()) << PrettyField(this);
149  return Get32(object);
150}
151
152template<bool kTransactionActive>
153inline void ArtField::SetChar(Object* object, uint16_t c) {
154  DCHECK_EQ(Primitive::kPrimChar, GetTypeAsPrimitiveType()) << PrettyField(this);
155  Set32<kTransactionActive>(object, c);
156}
157
158inline int16_t ArtField::GetShort(Object* object) {
159  DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField(this);
160  return Get32(object);
161}
162
163template<bool kTransactionActive>
164inline void ArtField::SetShort(Object* object, int16_t s) {
165  DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField(this);
166  Set32<kTransactionActive>(object, s);
167}
168
169inline int32_t ArtField::GetInt(Object* object) {
170  if (kIsDebugBuild) {
171    Primitive::Type type = GetTypeAsPrimitiveType();
172    CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
173  }
174  return Get32(object);
175}
176
177template<bool kTransactionActive>
178inline void ArtField::SetInt(Object* object, int32_t i) {
179  if (kIsDebugBuild) {
180    Primitive::Type type = GetTypeAsPrimitiveType();
181    CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
182  }
183  Set32<kTransactionActive>(object, i);
184}
185
186inline int64_t ArtField::GetLong(Object* object) {
187  if (kIsDebugBuild) {
188    Primitive::Type type = GetTypeAsPrimitiveType();
189    CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
190  }
191  return Get64(object);
192}
193
194template<bool kTransactionActive>
195inline void ArtField::SetLong(Object* object, int64_t j) {
196  if (kIsDebugBuild) {
197    Primitive::Type type = GetTypeAsPrimitiveType();
198    CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
199  }
200  Set64<kTransactionActive>(object, j);
201}
202
203inline float ArtField::GetFloat(Object* object) {
204  DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
205  JValue bits;
206  bits.SetI(Get32(object));
207  return bits.GetF();
208}
209
210template<bool kTransactionActive>
211inline void ArtField::SetFloat(Object* object, float f) {
212  DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
213  JValue bits;
214  bits.SetF(f);
215  Set32<kTransactionActive>(object, bits.GetI());
216}
217
218inline double ArtField::GetDouble(Object* object) {
219  DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
220  JValue bits;
221  bits.SetJ(Get64(object));
222  return bits.GetD();
223}
224
225template<bool kTransactionActive>
226inline void ArtField::SetDouble(Object* object, double d) {
227  DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
228  JValue bits;
229  bits.SetD(d);
230  Set64<kTransactionActive>(object, bits.GetJ());
231}
232
233inline Object* ArtField::GetObject(Object* object) {
234  DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
235  return GetObj(object);
236}
237
238template<bool kTransactionActive>
239inline void ArtField::SetObject(Object* object, Object* l) {
240  DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
241  SetObj<kTransactionActive>(object, l);
242}
243
244inline const char* ArtField::GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
245  uint32_t field_index = GetDexFieldIndex();
246  if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
247    DCHECK(IsStatic());
248    DCHECK_LT(field_index, 2U);
249    return field_index == 0 ? "interfaces" : "throws";
250  }
251  const DexFile* dex_file = GetDexFile();
252  return dex_file->GetFieldName(dex_file->GetFieldId(field_index));
253}
254
255inline const char* ArtField::GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
256  uint32_t field_index = GetDexFieldIndex();
257  if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
258    DCHECK(IsStatic());
259    DCHECK_LT(field_index, 2U);
260    // 0 == Class[] interfaces; 1 == Class[][] throws;
261    return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
262  }
263  const DexFile* dex_file = GetDexFile();
264  const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
265  return dex_file->GetFieldTypeDescriptor(field_id);
266}
267
268inline Primitive::Type ArtField::GetTypeAsPrimitiveType()
269    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
270  return Primitive::GetType(GetTypeDescriptor()[0]);
271}
272
273inline bool ArtField::IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
274  return GetTypeAsPrimitiveType() != Primitive::kPrimNot;
275}
276
277inline size_t ArtField::FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
278  return Primitive::FieldSize(GetTypeAsPrimitiveType());
279}
280
281inline mirror::DexCache* ArtField::GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
282  return GetDeclaringClass()->GetDexCache();
283}
284
285inline const DexFile* ArtField::GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
286  return GetDexCache()->GetDexFile();
287}
288
289inline ArtField* ArtField::FromReflectedField(const ScopedObjectAccessAlreadyRunnable& soa,
290                                              jobject jlr_field) {
291  mirror::ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_reflect_Field_artField);
292  mirror::ArtField* field = f->GetObject(soa.Decode<mirror::Object*>(jlr_field))->AsArtField();
293  DCHECK(field != nullptr);
294  return field;
295}
296
297}  // namespace mirror
298}  // namespace art
299
300#endif  // ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
301