blob: 11473cd3991a80df17c1232a50ca66f025404709 [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 Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_MIRROR_OBJECT_H_
18#define ART_RUNTIME_MIRROR_OBJECT_H_
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080019
20#include "base/casts.h"
21#include "base/logging.h"
22#include "base/macros.h"
23#include "cutils/atomic-inline.h"
24#include "offsets.h"
25
26namespace art {
27
28class ImageWriter;
Ian Rogersd9c4fc92013-10-01 19:45:43 -070029class LockWord;
Mathieu Chartierad2541a2013-10-25 10:05:23 -070030class Monitor;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080031struct ObjectOffsets;
32class Thread;
33
34namespace mirror {
35
Brian Carlstromea46f952013-07-30 01:26:50 -070036class ArtField;
37class ArtMethod;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080038class Array;
39class Class;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080040template<class T> class ObjectArray;
41template<class T> class PrimitiveArray;
42typedef PrimitiveArray<uint8_t> BooleanArray;
43typedef PrimitiveArray<int8_t> ByteArray;
44typedef PrimitiveArray<uint16_t> CharArray;
45typedef PrimitiveArray<double> DoubleArray;
46typedef PrimitiveArray<float> FloatArray;
47typedef PrimitiveArray<int32_t> IntArray;
48typedef PrimitiveArray<int64_t> LongArray;
49typedef PrimitiveArray<int16_t> ShortArray;
50class String;
51class Throwable;
52
53// Classes shared with the managed side of the world need to be packed so that they don't have
54// extra platform specific padding.
55#define MANAGED PACKED(4)
56
57// Fields within mirror objects aren't accessed directly so that the appropriate amount of
58// handshaking is done with GC (for example, read and write barriers). This macro is used to
59// compute an offset for the Set/Get methods defined in Object that can safely access fields.
60#define OFFSET_OF_OBJECT_MEMBER(type, field) \
61 MemberOffset(OFFSETOF_MEMBER(type, field))
62
Ian Rogers04d7aa92013-03-16 14:29:17 -070063const bool kCheckFieldAssignments = false;
64
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080065// C++ mirror of java.lang.Object
66class MANAGED Object {
67 public:
68 static MemberOffset ClassOffset() {
69 return OFFSET_OF_OBJECT_MEMBER(Object, klass_);
70 }
71
72 Class* GetClass() const;
73
74 void SetClass(Class* new_klass);
75
Jeff Haoa3faaf42013-09-03 19:07:00 -070076 // The verifier treats all interfaces as java.lang.Object and relies on runtime checks in
77 // invoke-interface to detect incompatible interface types.
78 bool VerifierInstanceOf(const Class* klass) const
79 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
80
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080081 bool InstanceOf(const Class* klass) const
82 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
83
84 size_t SizeOf() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
85
86 Object* Clone(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
87
Mathieu Chartierad2541a2013-10-25 10:05:23 -070088 int32_t IdentityHashCode() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080089
90 static MemberOffset MonitorOffset() {
91 return OFFSET_OF_OBJECT_MEMBER(Object, monitor_);
92 }
93
Mathieu Chartierad2541a2013-10-25 10:05:23 -070094 LockWord GetLockWord() const;
Ian Rogersd9c4fc92013-10-01 19:45:43 -070095 void SetLockWord(LockWord new_val);
96 bool CasLockWord(LockWord old_val, LockWord new_val);
97 uint32_t GetLockOwnerThreadId();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080098
Ian Rogers05f30572013-02-20 12:13:11 -080099 void MonitorEnter(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800100 EXCLUSIVE_LOCK_FUNCTION(monitor_lock_);
101
Ian Rogers05f30572013-02-20 12:13:11 -0800102 bool MonitorExit(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800103 UNLOCK_FUNCTION(monitor_lock_);
104
Ian Rogers05f30572013-02-20 12:13:11 -0800105 void Notify(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800106
Ian Rogers05f30572013-02-20 12:13:11 -0800107 void NotifyAll(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800108
Ian Rogers05f30572013-02-20 12:13:11 -0800109 void Wait(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800110
Ian Rogers05f30572013-02-20 12:13:11 -0800111 void Wait(Thread* self, int64_t timeout, int32_t nanos) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800112
113 bool IsClass() const;
114
115 Class* AsClass();
116
117 const Class* AsClass() const;
118
119 bool IsObjectArray() const;
120
121 template<class T>
122 ObjectArray<T>* AsObjectArray();
123
124 template<class T>
125 const ObjectArray<T>* AsObjectArray() const;
126
127 bool IsArrayInstance() const;
128
129 Array* AsArray();
130
131 const Array* AsArray() const;
132
133 BooleanArray* AsBooleanArray();
134 ByteArray* AsByteArray();
135 CharArray* AsCharArray();
136 ShortArray* AsShortArray();
137 IntArray* AsIntArray();
138 LongArray* AsLongArray();
139
140 String* AsString();
141
142 Throwable* AsThrowable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
143
Brian Carlstromea46f952013-07-30 01:26:50 -0700144 bool IsArtMethod() const;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800145
Brian Carlstromea46f952013-07-30 01:26:50 -0700146 ArtMethod* AsArtMethod();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800147
Brian Carlstromea46f952013-07-30 01:26:50 -0700148 const ArtMethod* AsArtMethod() const;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800149
Brian Carlstromea46f952013-07-30 01:26:50 -0700150 bool IsArtField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800151
Brian Carlstromea46f952013-07-30 01:26:50 -0700152 ArtField* AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800153
Brian Carlstromea46f952013-07-30 01:26:50 -0700154 const ArtField* AsArtField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800155
156 bool IsReferenceInstance() const;
157
158 bool IsWeakReferenceInstance() const;
159
160 bool IsSoftReferenceInstance() const;
161
162 bool IsFinalizerReferenceInstance() const;
163
164 bool IsPhantomReferenceInstance() const;
165
166 // Accessors for Java type fields
167 template<class T>
168 T GetFieldObject(MemberOffset field_offset, bool is_volatile) const {
169 T result = reinterpret_cast<T>(GetField32(field_offset, is_volatile));
170 VerifyObject(result);
171 return result;
172 }
173
174 void SetFieldObject(MemberOffset field_offset, const Object* new_value, bool is_volatile,
175 bool this_is_valid = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
176 VerifyObject(new_value);
177 SetField32(field_offset, reinterpret_cast<uint32_t>(new_value), is_volatile, this_is_valid);
178 if (new_value != NULL) {
179 CheckFieldAssignment(field_offset, new_value);
180 WriteBarrierField(this, field_offset, new_value);
181 }
182 }
183
Mathieu Chartier11409ae2013-09-23 11:49:36 -0700184 Object** GetFieldObjectAddr(MemberOffset field_offset) ALWAYS_INLINE {
185 VerifyObject(this);
186 return reinterpret_cast<Object**>(reinterpret_cast<byte*>(this) + field_offset.Int32Value());
187 }
188
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800189 uint32_t GetField32(MemberOffset field_offset, bool is_volatile) const {
190 VerifyObject(this);
191 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
192 const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr);
193 if (UNLIKELY(is_volatile)) {
194 return android_atomic_acquire_load(word_addr);
195 } else {
196 return *word_addr;
197 }
198 }
199
200 void SetField32(MemberOffset field_offset, uint32_t new_value, bool is_volatile,
201 bool this_is_valid = true) {
202 if (this_is_valid) {
203 VerifyObject(this);
204 }
205 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
206 uint32_t* word_addr = reinterpret_cast<uint32_t*>(raw_addr);
207 if (UNLIKELY(is_volatile)) {
208 /*
209 * TODO: add an android_atomic_synchronization_store() function and
210 * use it in the 32-bit volatile set handlers. On some platforms we
211 * can use a fast atomic instruction and avoid the barriers.
212 */
213 ANDROID_MEMBAR_STORE();
214 *word_addr = new_value;
215 ANDROID_MEMBAR_FULL();
216 } else {
217 *word_addr = new_value;
218 }
219 }
220
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700221 bool CasField32(MemberOffset field_offset, uint32_t old_value, uint32_t new_value);
222
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800223 uint64_t GetField64(MemberOffset field_offset, bool is_volatile) const;
224
225 void SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile);
226
227 protected:
228 // Accessors for non-Java type fields
229 template<class T>
230 T GetFieldPtr(MemberOffset field_offset, bool is_volatile) const {
231 return reinterpret_cast<T>(GetField32(field_offset, is_volatile));
232 }
233
234 template<typename T>
235 void SetFieldPtr(MemberOffset field_offset, T new_value, bool is_volatile, bool this_is_valid = true) {
236 SetField32(field_offset, reinterpret_cast<uint32_t>(new_value), is_volatile, this_is_valid);
237 }
238
239 private:
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700240 static void VerifyObject(const Object* obj) ALWAYS_INLINE;
Ian Rogers04d7aa92013-03-16 14:29:17 -0700241 // Verify the type correctness of stores to fields.
242 void CheckFieldAssignmentImpl(MemberOffset field_offset, const Object* new_value)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800243 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers04d7aa92013-03-16 14:29:17 -0700244 void CheckFieldAssignment(MemberOffset field_offset, const Object* new_value)
245 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
246 if (kCheckFieldAssignments) {
247 CheckFieldAssignmentImpl(field_offset, new_value);
248 }
249 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800250
Mathieu Chartierad2541a2013-10-25 10:05:23 -0700251 // Generate an identity hash code.
252 static uint32_t GenerateIdentityHashCode();
253
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800254 // Write barrier called post update to a reference bearing field.
255 static void WriteBarrierField(const Object* dst, MemberOffset offset, const Object* new_value);
256
257 Class* klass_;
258
259 uint32_t monitor_;
260
261 friend class art::ImageWriter;
Mathieu Chartierad2541a2013-10-25 10:05:23 -0700262 friend class art::Monitor;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800263 friend struct art::ObjectOffsets; // for verifying offset information
264 DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
265};
266
267} // namespace mirror
268} // namespace art
269
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700270#endif // ART_RUNTIME_MIRROR_OBJECT_H_