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_ART_FIELD_H_
18#define ART_RUNTIME_ART_FIELD_H_
19
20#include <jni.h>
21
22#include "dex_file_types.h"
23#include "gc_root.h"
24#include "modifiers.h"
25#include "obj_ptr.h"
26#include "offsets.h"
27#include "primitive.h"
28#include "read_barrier_option.h"
29
30namespace art {
31
32class DexFile;
33class ScopedObjectAccessAlreadyRunnable;
34
35namespace mirror {
36class Class;
37class DexCache;
38class Object;
39class String;
40}  // namespace mirror
41
42class ArtField FINAL {
43 public:
44  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
45  ObjPtr<mirror::Class> GetDeclaringClass() REQUIRES_SHARED(Locks::mutator_lock_);
46
47  void SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class)
48      REQUIRES_SHARED(Locks::mutator_lock_);
49
50  mirror::CompressedReference<mirror::Object>* GetDeclaringClassAddressWithoutBarrier() {
51    return declaring_class_.AddressWithoutBarrier();
52  }
53
54  uint32_t GetAccessFlags() REQUIRES_SHARED(Locks::mutator_lock_) {
55    if (kIsDebugBuild) {
56      GetAccessFlagsDCheck();
57    }
58    return access_flags_;
59  }
60
61  void SetAccessFlags(uint32_t new_access_flags) REQUIRES_SHARED(Locks::mutator_lock_) {
62    // Not called within a transaction.
63    access_flags_ = new_access_flags;
64  }
65
66  bool IsPublic() REQUIRES_SHARED(Locks::mutator_lock_) {
67    return (GetAccessFlags() & kAccPublic) != 0;
68  }
69
70  bool IsStatic() REQUIRES_SHARED(Locks::mutator_lock_) {
71    return (GetAccessFlags() & kAccStatic) != 0;
72  }
73
74  bool IsFinal() REQUIRES_SHARED(Locks::mutator_lock_) {
75    return (GetAccessFlags() & kAccFinal) != 0;
76  }
77
78  uint32_t GetDexFieldIndex() {
79    return field_dex_idx_;
80  }
81
82  void SetDexFieldIndex(uint32_t new_idx) {
83    // Not called within a transaction.
84    field_dex_idx_ = new_idx;
85  }
86
87  // Offset to field within an Object.
88  MemberOffset GetOffset() REQUIRES_SHARED(Locks::mutator_lock_) {
89    if (kIsDebugBuild) {
90      GetOffsetDCheck();
91    }
92    return MemberOffset(offset_);
93  }
94
95  static MemberOffset OffsetOffset() {
96    return MemberOffset(OFFSETOF_MEMBER(ArtField, offset_));
97  }
98
99  MemberOffset GetOffsetDuringLinking() REQUIRES_SHARED(Locks::mutator_lock_);
100
101  void SetOffset(MemberOffset num_bytes) REQUIRES_SHARED(Locks::mutator_lock_);
102
103  // field access, null object for static fields
104  uint8_t GetBoolean(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
105
106  template<bool kTransactionActive>
107  void SetBoolean(ObjPtr<mirror::Object> object, uint8_t z) REQUIRES_SHARED(Locks::mutator_lock_);
108
109  int8_t GetByte(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
110
111  template<bool kTransactionActive>
112  void SetByte(ObjPtr<mirror::Object> object, int8_t b) REQUIRES_SHARED(Locks::mutator_lock_);
113
114  uint16_t GetChar(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
115
116  template<bool kTransactionActive>
117  void SetChar(ObjPtr<mirror::Object> object, uint16_t c) REQUIRES_SHARED(Locks::mutator_lock_);
118
119  int16_t GetShort(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
120
121  template<bool kTransactionActive>
122  void SetShort(ObjPtr<mirror::Object> object, int16_t s) REQUIRES_SHARED(Locks::mutator_lock_);
123
124  int32_t GetInt(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
125
126  template<bool kTransactionActive>
127  void SetInt(ObjPtr<mirror::Object> object, int32_t i) REQUIRES_SHARED(Locks::mutator_lock_);
128
129  int64_t GetLong(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
130
131  template<bool kTransactionActive>
132  void SetLong(ObjPtr<mirror::Object> object, int64_t j) REQUIRES_SHARED(Locks::mutator_lock_);
133
134  float GetFloat(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
135
136  template<bool kTransactionActive>
137  void SetFloat(ObjPtr<mirror::Object> object, float f) REQUIRES_SHARED(Locks::mutator_lock_);
138
139  double GetDouble(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
140
141  template<bool kTransactionActive>
142  void SetDouble(ObjPtr<mirror::Object> object, double d) REQUIRES_SHARED(Locks::mutator_lock_);
143
144  ObjPtr<mirror::Object> GetObject(ObjPtr<mirror::Object> object)
145      REQUIRES_SHARED(Locks::mutator_lock_);
146
147  template<bool kTransactionActive>
148  void SetObject(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> l)
149      REQUIRES_SHARED(Locks::mutator_lock_);
150
151  // Raw field accesses.
152  uint32_t Get32(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
153
154  template<bool kTransactionActive>
155  void Set32(ObjPtr<mirror::Object> object, uint32_t new_value)
156      REQUIRES_SHARED(Locks::mutator_lock_);
157
158  uint64_t Get64(ObjPtr<mirror::Object> object) REQUIRES_SHARED(Locks::mutator_lock_);
159
160  template<bool kTransactionActive>
161  void Set64(ObjPtr<mirror::Object> object, uint64_t new_value)
162      REQUIRES_SHARED(Locks::mutator_lock_);
163
164  template<class MirrorType = mirror::Object>
165  ObjPtr<MirrorType> GetObj(ObjPtr<mirror::Object> object)
166      REQUIRES_SHARED(Locks::mutator_lock_);
167
168  template<bool kTransactionActive>
169  void SetObj(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> new_value)
170      REQUIRES_SHARED(Locks::mutator_lock_);
171
172  // NO_THREAD_SAFETY_ANALYSIS since we don't know what the callback requires.
173  template<typename RootVisitorType>
174  void VisitRoots(RootVisitorType& visitor) NO_THREAD_SAFETY_ANALYSIS;
175
176  bool IsVolatile() REQUIRES_SHARED(Locks::mutator_lock_) {
177    return (GetAccessFlags() & kAccVolatile) != 0;
178  }
179
180  // Returns an instance field with this offset in the given class or null if not found.
181  // If kExactOffset is true then we only find the matching offset, not the field containing the
182  // offset.
183  template <bool kExactOffset = true>
184  static ArtField* FindInstanceFieldWithOffset(ObjPtr<mirror::Class> klass, uint32_t field_offset)
185      REQUIRES_SHARED(Locks::mutator_lock_);
186
187  // Returns a static field with this offset in the given class or null if not found.
188  // If kExactOffset is true then we only find the matching offset, not the field containing the
189  // offset.
190  template <bool kExactOffset = true>
191  static ArtField* FindStaticFieldWithOffset(ObjPtr<mirror::Class> klass, uint32_t field_offset)
192      REQUIRES_SHARED(Locks::mutator_lock_);
193
194  const char* GetName() REQUIRES_SHARED(Locks::mutator_lock_);
195
196  // Resolves / returns the name from the dex cache.
197  ObjPtr<mirror::String> GetStringName(Thread* self, bool resolve)
198      REQUIRES_SHARED(Locks::mutator_lock_);
199
200  const char* GetTypeDescriptor() REQUIRES_SHARED(Locks::mutator_lock_);
201
202  Primitive::Type GetTypeAsPrimitiveType() REQUIRES_SHARED(Locks::mutator_lock_);
203
204  bool IsPrimitiveType() REQUIRES_SHARED(Locks::mutator_lock_);
205
206  template <bool kResolve>
207  ObjPtr<mirror::Class> GetType() REQUIRES_SHARED(Locks::mutator_lock_);
208
209  size_t FieldSize() REQUIRES_SHARED(Locks::mutator_lock_);
210
211  ObjPtr<mirror::DexCache> GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_);
212
213  const DexFile* GetDexFile() REQUIRES_SHARED(Locks::mutator_lock_);
214
215  GcRoot<mirror::Class>& DeclaringClassRoot() {
216    return declaring_class_;
217  }
218
219  // Returns a human-readable signature. Something like "a.b.C.f" or
220  // "int a.b.C.f" (depending on the value of 'with_type').
221  static std::string PrettyField(ArtField* f, bool with_type = true)
222      REQUIRES_SHARED(Locks::mutator_lock_);
223  std::string PrettyField(bool with_type = true)
224      REQUIRES_SHARED(Locks::mutator_lock_);
225
226  // Update the declaring class with the passed in visitor. Does not use read barrier.
227  template <typename Visitor>
228  ALWAYS_INLINE void UpdateObjects(const Visitor& visitor)
229      REQUIRES_SHARED(Locks::mutator_lock_);
230
231 private:
232  ObjPtr<mirror::Class> ProxyFindSystemClass(const char* descriptor)
233      REQUIRES_SHARED(Locks::mutator_lock_);
234  ObjPtr<mirror::String> ResolveGetStringName(Thread* self,
235                                              const DexFile& dex_file,
236                                              dex::StringIndex string_idx,
237                                              ObjPtr<mirror::DexCache> dex_cache)
238      REQUIRES_SHARED(Locks::mutator_lock_);
239
240  void GetAccessFlagsDCheck() REQUIRES_SHARED(Locks::mutator_lock_);
241  void GetOffsetDCheck() REQUIRES_SHARED(Locks::mutator_lock_);
242
243  GcRoot<mirror::Class> declaring_class_;
244
245  uint32_t access_flags_ = 0;
246
247  // Dex cache index of field id
248  uint32_t field_dex_idx_ = 0;
249
250  // Offset of field within an instance or in the Class' static fields
251  uint32_t offset_ = 0;
252};
253
254}  // namespace art
255
256#endif  // ART_RUNTIME_ART_FIELD_H_
257