blob: eb118c7d2fd2e915104a4ec8577f367f68039408 [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"
Ian Rogersef7d42f2014-01-06 12:55:46 -080024#include "object_reference.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080025#include "offsets.h"
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010026#include "runtime.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080027
28namespace art {
29
30class ImageWriter;
Ian Rogersd9c4fc92013-10-01 19:45:43 -070031class LockWord;
Mathieu Chartierad2541a2013-10-25 10:05:23 -070032class Monitor;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080033struct ObjectOffsets;
34class Thread;
Mathieu Chartier590fee92013-09-13 13:46:47 -070035template <typename T> class SirtRef;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080036
37namespace mirror {
38
Brian Carlstromea46f952013-07-30 01:26:50 -070039class ArtField;
40class ArtMethod;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080041class Array;
42class Class;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080043template<class T> class ObjectArray;
44template<class T> class PrimitiveArray;
45typedef PrimitiveArray<uint8_t> BooleanArray;
46typedef PrimitiveArray<int8_t> ByteArray;
47typedef PrimitiveArray<uint16_t> CharArray;
48typedef PrimitiveArray<double> DoubleArray;
49typedef PrimitiveArray<float> FloatArray;
50typedef PrimitiveArray<int32_t> IntArray;
51typedef PrimitiveArray<int64_t> LongArray;
52typedef PrimitiveArray<int16_t> ShortArray;
53class String;
54class Throwable;
55
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080056// 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 Rogersef7d42f2014-01-06 12:55:46 -080062constexpr bool kCheckFieldAssignments = false;
Ian Rogers04d7aa92013-03-16 14:29:17 -070063
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
Ian Rogersef7d42f2014-01-06 12:55:46 -080071 Class* GetClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080072
Ian Rogersef7d42f2014-01-06 12:55:46 -080073 void SetClass(Class* new_klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080074
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.
Ian Rogersef7d42f2014-01-06 12:55:46 -080077 bool VerifierInstanceOf(Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Jeff Haoa3faaf42013-09-03 19:07:00 -070078
Ian Rogersef7d42f2014-01-06 12:55:46 -080079 bool InstanceOf(Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080080
Ian Rogersef7d42f2014-01-06 12:55:46 -080081 size_t SizeOf() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080082
83 Object* Clone(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
84
Mathieu Chartierad2541a2013-10-25 10:05:23 -070085 int32_t IdentityHashCode() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080086
87 static MemberOffset MonitorOffset() {
88 return OFFSET_OF_OBJECT_MEMBER(Object, monitor_);
89 }
90
Ian Rogersef7d42f2014-01-06 12:55:46 -080091 LockWord GetLockWord();
Ian Rogersd9c4fc92013-10-01 19:45:43 -070092 void SetLockWord(LockWord new_val);
Ian Rogersef7d42f2014-01-06 12:55:46 -080093 bool CasLockWord(LockWord old_val, LockWord new_val) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogersd9c4fc92013-10-01 19:45:43 -070094 uint32_t GetLockOwnerThreadId();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080095
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -080096 mirror::Object* MonitorEnter(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080097 EXCLUSIVE_LOCK_FUNCTION(monitor_lock_);
98
Ian Rogers05f30572013-02-20 12:13:11 -080099 bool MonitorExit(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800100 UNLOCK_FUNCTION(monitor_lock_);
101
Ian Rogers05f30572013-02-20 12:13:11 -0800102 void Notify(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800103
Ian Rogers05f30572013-02-20 12:13:11 -0800104 void NotifyAll(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800105
Ian Rogers05f30572013-02-20 12:13:11 -0800106 void Wait(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800107
Ian Rogers05f30572013-02-20 12:13:11 -0800108 void Wait(Thread* self, int64_t timeout, int32_t nanos) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800109
Ian Rogersef7d42f2014-01-06 12:55:46 -0800110 bool IsClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800111
Ian Rogersef7d42f2014-01-06 12:55:46 -0800112 Class* AsClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800113
Ian Rogersef7d42f2014-01-06 12:55:46 -0800114 bool IsObjectArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800115
116 template<class T>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800117 ObjectArray<T>* AsObjectArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800118
Ian Rogersef7d42f2014-01-06 12:55:46 -0800119 bool IsArrayInstance() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800120
Ian Rogersef7d42f2014-01-06 12:55:46 -0800121 Array* AsArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800122
Ian Rogersef7d42f2014-01-06 12:55:46 -0800123 BooleanArray* AsBooleanArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
124 ByteArray* AsByteArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
125 ByteArray* AsByteSizedArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800126
Ian Rogersef7d42f2014-01-06 12:55:46 -0800127 CharArray* AsCharArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
128 ShortArray* AsShortArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
129 ShortArray* AsShortSizedArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800130
Ian Rogersef7d42f2014-01-06 12:55:46 -0800131 IntArray* AsIntArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
132 LongArray* AsLongArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800133
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100134 FloatArray* AsFloatArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
135 DoubleArray* AsDoubleArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
136
Ian Rogersef7d42f2014-01-06 12:55:46 -0800137 String* AsString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800138
139 Throwable* AsThrowable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
140
Ian Rogersef7d42f2014-01-06 12:55:46 -0800141 bool IsArtMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800142
Ian Rogersef7d42f2014-01-06 12:55:46 -0800143 ArtMethod* AsArtMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800144
Ian Rogersef7d42f2014-01-06 12:55:46 -0800145 bool IsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800146
Brian Carlstromea46f952013-07-30 01:26:50 -0700147 ArtField* AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800148
Ian Rogersef7d42f2014-01-06 12:55:46 -0800149 bool IsReferenceInstance() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800150
Ian Rogersef7d42f2014-01-06 12:55:46 -0800151 bool IsWeakReferenceInstance() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800152
Ian Rogersef7d42f2014-01-06 12:55:46 -0800153 bool IsSoftReferenceInstance() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800154
Ian Rogersef7d42f2014-01-06 12:55:46 -0800155 bool IsFinalizerReferenceInstance() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800156
Ian Rogersef7d42f2014-01-06 12:55:46 -0800157 bool IsPhantomReferenceInstance() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800158
Ian Rogersef7d42f2014-01-06 12:55:46 -0800159 // Accessor for Java type fields.
160 template<class T> T* GetFieldObject(MemberOffset field_offset, bool is_volatile)
161 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100162 template<bool kTransactionActive, bool kCheckTransaction = true>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800163 void SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, Object* new_value,
164 bool is_volatile, bool this_is_valid = true)
165 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100166 template<bool kTransactionActive, bool kCheckTransaction = true>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800167 void SetFieldObject(MemberOffset field_offset, Object* new_value, bool is_volatile,
168 bool this_is_valid = true)
169 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100170 template<bool kTransactionActive, bool kCheckTransaction = true>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800171 bool CasFieldObject(MemberOffset field_offset, Object* old_value, Object* new_value)
172 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800173
Ian Rogersef7d42f2014-01-06 12:55:46 -0800174 HeapReference<Object>* GetFieldObjectReferenceAddr(MemberOffset field_offset) ALWAYS_INLINE {
Mathieu Chartier11409ae2013-09-23 11:49:36 -0700175 VerifyObject(this);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800176 return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<byte*>(this) +
177 field_offset.Int32Value());
Mathieu Chartier11409ae2013-09-23 11:49:36 -0700178 }
179
Ian Rogers29501cf2014-02-07 21:00:25 -0800180 int32_t GetField32(MemberOffset field_offset, bool is_volatile);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800181
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100182 template<bool kTransactionActive, bool kCheckTransaction = true>
Ian Rogers29501cf2014-02-07 21:00:25 -0800183 void SetField32(MemberOffset field_offset, int32_t new_value, bool is_volatile,
Ian Rogersb122a4b2013-11-19 18:00:50 -0800184 bool this_is_valid = true);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800185
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100186 template<bool kTransactionActive, bool kCheckTransaction = true>
Ian Rogers29501cf2014-02-07 21:00:25 -0800187 bool CasField32(MemberOffset field_offset, int32_t old_value, int32_t new_value)
Ian Rogersef7d42f2014-01-06 12:55:46 -0800188 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700189
Ian Rogers29501cf2014-02-07 21:00:25 -0800190 int64_t GetField64(MemberOffset field_offset, bool is_volatile);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800191
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100192 template<bool kTransactionActive, bool kCheckTransaction = true>
Ian Rogers29501cf2014-02-07 21:00:25 -0800193 void SetField64(MemberOffset field_offset, int64_t new_value, bool is_volatile,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800194 bool this_is_valid = true);
195
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100196 template<bool kTransactionActive, bool kCheckTransaction = true>
Ian Rogers29501cf2014-02-07 21:00:25 -0800197 bool CasField64(MemberOffset field_offset, int64_t old_value, int64_t new_value)
Ian Rogersef7d42f2014-01-06 12:55:46 -0800198 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800199
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100200 template<bool kTransactionActive, bool kCheckTransaction = true, typename T>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800201 void SetFieldPtr(MemberOffset field_offset, T new_value, bool is_volatile,
202 bool this_is_valid = true) {
203#ifndef __LP64__
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100204 SetField32<kTransactionActive, kCheckTransaction>(field_offset,
205 reinterpret_cast<int32_t>(new_value),
206 is_volatile, this_is_valid);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800207#else
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100208 SetField64<kTransactionActive, kCheckTransaction>(field_offset,
209 reinterpret_cast<int64_t>(new_value),
210 is_volatile, this_is_valid);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800211#endif
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800212 }
213
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800214 protected:
215 // Accessors for non-Java type fields
216 template<class T>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800217 T GetFieldPtr(MemberOffset field_offset, bool is_volatile) {
218#ifndef __LP64__
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800219 return reinterpret_cast<T>(GetField32(field_offset, is_volatile));
Ian Rogersef7d42f2014-01-06 12:55:46 -0800220#else
221 return reinterpret_cast<T>(GetField64(field_offset, is_volatile));
222#endif
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800223 }
224
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800225 private:
Ian Rogersef7d42f2014-01-06 12:55:46 -0800226 static void VerifyObject(Object* obj) ALWAYS_INLINE;
Ian Rogers04d7aa92013-03-16 14:29:17 -0700227 // Verify the type correctness of stores to fields.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800228 void CheckFieldAssignmentImpl(MemberOffset field_offset, Object* new_value)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800229 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800230 void CheckFieldAssignment(MemberOffset field_offset, Object* new_value)
Ian Rogers04d7aa92013-03-16 14:29:17 -0700231 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
232 if (kCheckFieldAssignments) {
233 CheckFieldAssignmentImpl(field_offset, new_value);
234 }
235 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800236
Mathieu Chartierad2541a2013-10-25 10:05:23 -0700237 // Generate an identity hash code.
Mathieu Chartier4e6a31e2013-10-31 10:35:05 -0700238 static int32_t GenerateIdentityHashCode();
Mathieu Chartierad2541a2013-10-25 10:05:23 -0700239
Ian Rogersef7d42f2014-01-06 12:55:46 -0800240 // The Class representing the type of the object.
241 HeapReference<Class> klass_;
242 // Monitor and hash code information.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800243 uint32_t monitor_;
244
245 friend class art::ImageWriter;
Mathieu Chartierad2541a2013-10-25 10:05:23 -0700246 friend class art::Monitor;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800247 friend struct art::ObjectOffsets; // for verifying offset information
248 DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
249};
250
251} // namespace mirror
252} // namespace art
253
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700254#endif // ART_RUNTIME_MIRROR_OBJECT_H_