blob: e3f5c101c1a1c4442150e8e789f561307379c19a [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;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080030struct ObjectOffsets;
31class Thread;
32
33namespace mirror {
34
Brian Carlstromea46f952013-07-30 01:26:50 -070035class ArtField;
36class ArtMethod;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080037class Array;
38class Class;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080039template<class T> class ObjectArray;
40template<class T> class PrimitiveArray;
41typedef PrimitiveArray<uint8_t> BooleanArray;
42typedef PrimitiveArray<int8_t> ByteArray;
43typedef PrimitiveArray<uint16_t> CharArray;
44typedef PrimitiveArray<double> DoubleArray;
45typedef PrimitiveArray<float> FloatArray;
46typedef PrimitiveArray<int32_t> IntArray;
47typedef PrimitiveArray<int64_t> LongArray;
48typedef PrimitiveArray<int16_t> ShortArray;
49class String;
50class Throwable;
51
52// Classes shared with the managed side of the world need to be packed so that they don't have
53// extra platform specific padding.
54#define MANAGED PACKED(4)
55
56// Fields within mirror objects aren't accessed directly so that the appropriate amount of
57// handshaking is done with GC (for example, read and write barriers). This macro is used to
58// compute an offset for the Set/Get methods defined in Object that can safely access fields.
59#define OFFSET_OF_OBJECT_MEMBER(type, field) \
60 MemberOffset(OFFSETOF_MEMBER(type, field))
61
Ian Rogers04d7aa92013-03-16 14:29:17 -070062const bool kCheckFieldAssignments = false;
63
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080064// C++ mirror of java.lang.Object
65class MANAGED Object {
66 public:
67 static MemberOffset ClassOffset() {
68 return OFFSET_OF_OBJECT_MEMBER(Object, klass_);
69 }
70
71 Class* GetClass() const;
72
73 void SetClass(Class* new_klass);
74
Jeff Haoa3faaf42013-09-03 19:07:00 -070075 // The verifier treats all interfaces as java.lang.Object and relies on runtime checks in
76 // invoke-interface to detect incompatible interface types.
77 bool VerifierInstanceOf(const Class* klass) const
78 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
79
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080080 bool InstanceOf(const Class* klass) const
81 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
82
83 size_t SizeOf() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
84
85 Object* Clone(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
86
87 int32_t IdentityHashCode() const {
Ian Rogersa436fde2013-08-27 23:34:06 -070088#ifdef MOVING_GARBAGE_COLLECTOR
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080089 // TODO: we'll need to use the Object's internal concept of identity
Ian Rogersa436fde2013-08-27 23:34:06 -070090 UNIMPLEMENTED(FATAL);
91#endif
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080092 return reinterpret_cast<int32_t>(this);
93 }
94
95 static MemberOffset MonitorOffset() {
96 return OFFSET_OF_OBJECT_MEMBER(Object, monitor_);
97 }
98
Ian Rogersd9c4fc92013-10-01 19:45:43 -070099 LockWord GetLockWord();
100 void SetLockWord(LockWord new_val);
101 bool CasLockWord(LockWord old_val, LockWord new_val);
102 uint32_t GetLockOwnerThreadId();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800103
Ian Rogers05f30572013-02-20 12:13:11 -0800104 void MonitorEnter(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800105 EXCLUSIVE_LOCK_FUNCTION(monitor_lock_);
106
Ian Rogers05f30572013-02-20 12:13:11 -0800107 bool MonitorExit(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800108 UNLOCK_FUNCTION(monitor_lock_);
109
Ian Rogers05f30572013-02-20 12:13:11 -0800110 void Notify(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800111
Ian Rogers05f30572013-02-20 12:13:11 -0800112 void NotifyAll(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800113
Ian Rogers05f30572013-02-20 12:13:11 -0800114 void Wait(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800115
Ian Rogers05f30572013-02-20 12:13:11 -0800116 void Wait(Thread* self, int64_t timeout, int32_t nanos) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800117
118 bool IsClass() const;
119
120 Class* AsClass();
121
122 const Class* AsClass() const;
123
124 bool IsObjectArray() const;
125
126 template<class T>
127 ObjectArray<T>* AsObjectArray();
128
129 template<class T>
130 const ObjectArray<T>* AsObjectArray() const;
131
132 bool IsArrayInstance() const;
133
134 Array* AsArray();
135
136 const Array* AsArray() const;
137
138 BooleanArray* AsBooleanArray();
139 ByteArray* AsByteArray();
140 CharArray* AsCharArray();
141 ShortArray* AsShortArray();
142 IntArray* AsIntArray();
143 LongArray* AsLongArray();
144
145 String* AsString();
146
147 Throwable* AsThrowable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
148
Brian Carlstromea46f952013-07-30 01:26:50 -0700149 bool IsArtMethod() const;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800150
Brian Carlstromea46f952013-07-30 01:26:50 -0700151 ArtMethod* AsArtMethod();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800152
Brian Carlstromea46f952013-07-30 01:26:50 -0700153 const ArtMethod* AsArtMethod() const;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800154
Brian Carlstromea46f952013-07-30 01:26:50 -0700155 bool IsArtField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800156
Brian Carlstromea46f952013-07-30 01:26:50 -0700157 ArtField* AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800158
Brian Carlstromea46f952013-07-30 01:26:50 -0700159 const ArtField* AsArtField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800160
161 bool IsReferenceInstance() const;
162
163 bool IsWeakReferenceInstance() const;
164
165 bool IsSoftReferenceInstance() const;
166
167 bool IsFinalizerReferenceInstance() const;
168
169 bool IsPhantomReferenceInstance() const;
170
171 // Accessors for Java type fields
172 template<class T>
173 T GetFieldObject(MemberOffset field_offset, bool is_volatile) const {
174 T result = reinterpret_cast<T>(GetField32(field_offset, is_volatile));
175 VerifyObject(result);
176 return result;
177 }
178
179 void SetFieldObject(MemberOffset field_offset, const Object* new_value, bool is_volatile,
180 bool this_is_valid = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
181 VerifyObject(new_value);
182 SetField32(field_offset, reinterpret_cast<uint32_t>(new_value), is_volatile, this_is_valid);
183 if (new_value != NULL) {
184 CheckFieldAssignment(field_offset, new_value);
185 WriteBarrierField(this, field_offset, new_value);
186 }
187 }
188
Mathieu Chartier11409ae2013-09-23 11:49:36 -0700189 Object** GetFieldObjectAddr(MemberOffset field_offset) ALWAYS_INLINE {
190 VerifyObject(this);
191 return reinterpret_cast<Object**>(reinterpret_cast<byte*>(this) + field_offset.Int32Value());
192 }
193
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800194 uint32_t GetField32(MemberOffset field_offset, bool is_volatile) const {
195 VerifyObject(this);
196 const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
197 const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr);
198 if (UNLIKELY(is_volatile)) {
199 return android_atomic_acquire_load(word_addr);
200 } else {
201 return *word_addr;
202 }
203 }
204
205 void SetField32(MemberOffset field_offset, uint32_t new_value, bool is_volatile,
206 bool this_is_valid = true) {
207 if (this_is_valid) {
208 VerifyObject(this);
209 }
210 byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
211 uint32_t* word_addr = reinterpret_cast<uint32_t*>(raw_addr);
212 if (UNLIKELY(is_volatile)) {
213 /*
214 * TODO: add an android_atomic_synchronization_store() function and
215 * use it in the 32-bit volatile set handlers. On some platforms we
216 * can use a fast atomic instruction and avoid the barriers.
217 */
218 ANDROID_MEMBAR_STORE();
219 *word_addr = new_value;
220 ANDROID_MEMBAR_FULL();
221 } else {
222 *word_addr = new_value;
223 }
224 }
225
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700226 bool CasField32(MemberOffset field_offset, uint32_t old_value, uint32_t new_value);
227
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800228 uint64_t GetField64(MemberOffset field_offset, bool is_volatile) const;
229
230 void SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile);
231
232 protected:
233 // Accessors for non-Java type fields
234 template<class T>
235 T GetFieldPtr(MemberOffset field_offset, bool is_volatile) const {
236 return reinterpret_cast<T>(GetField32(field_offset, is_volatile));
237 }
238
239 template<typename T>
240 void SetFieldPtr(MemberOffset field_offset, T new_value, bool is_volatile, bool this_is_valid = true) {
241 SetField32(field_offset, reinterpret_cast<uint32_t>(new_value), is_volatile, this_is_valid);
242 }
243
244 private:
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700245 static void VerifyObject(const Object* obj) ALWAYS_INLINE;
Ian Rogers04d7aa92013-03-16 14:29:17 -0700246
247 // Verify the type correctness of stores to fields.
248 void CheckFieldAssignmentImpl(MemberOffset field_offset, const Object* new_value)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800249 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers04d7aa92013-03-16 14:29:17 -0700250 void CheckFieldAssignment(MemberOffset field_offset, const Object* new_value)
251 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
252 if (kCheckFieldAssignments) {
253 CheckFieldAssignmentImpl(field_offset, new_value);
254 }
255 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800256
257 // Write barrier called post update to a reference bearing field.
258 static void WriteBarrierField(const Object* dst, MemberOffset offset, const Object* new_value);
259
260 Class* klass_;
261
262 uint32_t monitor_;
263
264 friend class art::ImageWriter;
265 friend struct art::ObjectOffsets; // for verifying offset information
266 DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
267};
268
269} // namespace mirror
270} // namespace art
271
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700272#endif // ART_RUNTIME_MIRROR_OBJECT_H_