Home | History | Annotate | Download | only in mirror
      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_OBJECT_INL_H_
     18 #define ART_RUNTIME_MIRROR_OBJECT_INL_H_
     19 
     20 #include "object.h"
     21 
     22 #include "art_field.h"
     23 #include "art_method.h"
     24 #include "atomic.h"
     25 #include "array-inl.h"
     26 #include "class.h"
     27 #include "monitor.h"
     28 #include "runtime.h"
     29 #include "throwable.h"
     30 
     31 namespace art {
     32 namespace mirror {
     33 
     34 inline Class* Object::GetClass() const {
     35   return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
     36 }
     37 
     38 inline void Object::SetClass(Class* new_klass) {
     39   // new_klass may be NULL prior to class linker initialization
     40   // We don't mark the card since the class is guaranteed to be referenced from another location.
     41   // Proxy classes are held live by the class loader, and other classes are roots of the class
     42   // linker.
     43   SetFieldPtr(OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false, false);
     44 }
     45 
     46 inline uint32_t Object::GetThinLockId() {
     47   return Monitor::GetThinLockId(monitor_);
     48 }
     49 
     50 inline void Object::MonitorEnter(Thread* self) {
     51   Monitor::MonitorEnter(self, this);
     52 }
     53 
     54 inline bool Object::MonitorExit(Thread* self) {
     55   return Monitor::MonitorExit(self, this);
     56 }
     57 
     58 inline void Object::Notify(Thread* self) {
     59   Monitor::Notify(self, this);
     60 }
     61 
     62 inline void Object::NotifyAll(Thread* self) {
     63   Monitor::NotifyAll(self, this);
     64 }
     65 
     66 inline void Object::Wait(Thread* self) {
     67   Monitor::Wait(self, this, 0, 0, true, kWaiting);
     68 }
     69 
     70 inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
     71   Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
     72 }
     73 
     74 inline bool Object::VerifierInstanceOf(const Class* klass) const {
     75   DCHECK(klass != NULL);
     76   DCHECK(GetClass() != NULL);
     77   return klass->IsInterface() || InstanceOf(klass);
     78 }
     79 
     80 inline bool Object::InstanceOf(const Class* klass) const {
     81   DCHECK(klass != NULL);
     82   DCHECK(GetClass() != NULL);
     83   return klass->IsAssignableFrom(GetClass());
     84 }
     85 
     86 inline bool Object::IsClass() const {
     87   Class* java_lang_Class = GetClass()->GetClass();
     88   return GetClass() == java_lang_Class;
     89 }
     90 
     91 inline Class* Object::AsClass() {
     92   DCHECK(IsClass());
     93   return down_cast<Class*>(this);
     94 }
     95 
     96 inline const Class* Object::AsClass() const {
     97   DCHECK(IsClass());
     98   return down_cast<const Class*>(this);
     99 }
    100 
    101 inline bool Object::IsObjectArray() const {
    102   return IsArrayInstance() && !GetClass()->GetComponentType()->IsPrimitive();
    103 }
    104 
    105 template<class T>
    106 inline ObjectArray<T>* Object::AsObjectArray() {
    107   DCHECK(IsObjectArray());
    108   return down_cast<ObjectArray<T>*>(this);
    109 }
    110 
    111 template<class T>
    112 inline const ObjectArray<T>* Object::AsObjectArray() const {
    113   DCHECK(IsObjectArray());
    114   return down_cast<const ObjectArray<T>*>(this);
    115 }
    116 
    117 inline bool Object::IsArrayInstance() const {
    118   return GetClass()->IsArrayClass();
    119 }
    120 
    121 inline bool Object::IsArtField() const {
    122   return GetClass()->IsArtFieldClass();
    123 }
    124 
    125 inline ArtField* Object::AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    126   DCHECK(IsArtField());
    127   return down_cast<ArtField*>(this);
    128 }
    129 
    130 inline const ArtField* Object::AsArtField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    131   DCHECK(IsArtField());
    132   return down_cast<const ArtField*>(this);
    133 }
    134 
    135 inline bool Object::IsArtMethod() const {
    136   return GetClass()->IsArtMethodClass();
    137 }
    138 
    139 inline ArtMethod* Object::AsArtMethod() {
    140   DCHECK(IsArtMethod());
    141   return down_cast<ArtMethod*>(this);
    142 }
    143 
    144 inline const ArtMethod* Object::AsArtMethod() const {
    145   DCHECK(IsArtMethod());
    146   return down_cast<const ArtMethod*>(this);
    147 }
    148 
    149 inline bool Object::IsReferenceInstance() const {
    150   return GetClass()->IsReferenceClass();
    151 }
    152 
    153 inline Array* Object::AsArray() {
    154   DCHECK(IsArrayInstance());
    155   return down_cast<Array*>(this);
    156 }
    157 
    158 inline const Array* Object::AsArray() const {
    159   DCHECK(IsArrayInstance());
    160   return down_cast<const Array*>(this);
    161 }
    162 
    163 inline BooleanArray* Object::AsBooleanArray() {
    164   DCHECK(GetClass()->IsArrayClass());
    165   DCHECK(GetClass()->GetComponentType()->IsPrimitiveBoolean());
    166   return down_cast<BooleanArray*>(this);
    167 }
    168 
    169 inline ByteArray* Object::AsByteArray() {
    170   DCHECK(GetClass()->IsArrayClass());
    171   DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte());
    172   return down_cast<ByteArray*>(this);
    173 }
    174 
    175 inline CharArray* Object::AsCharArray() {
    176   DCHECK(GetClass()->IsArrayClass());
    177   DCHECK(GetClass()->GetComponentType()->IsPrimitiveChar());
    178   return down_cast<CharArray*>(this);
    179 }
    180 
    181 inline ShortArray* Object::AsShortArray() {
    182   DCHECK(GetClass()->IsArrayClass());
    183   DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort());
    184   return down_cast<ShortArray*>(this);
    185 }
    186 
    187 inline IntArray* Object::AsIntArray() {
    188   DCHECK(GetClass()->IsArrayClass());
    189   DCHECK(GetClass()->GetComponentType()->IsPrimitiveInt() ||
    190          GetClass()->GetComponentType()->IsPrimitiveFloat());
    191   return down_cast<IntArray*>(this);
    192 }
    193 
    194 inline LongArray* Object::AsLongArray() {
    195   DCHECK(GetClass()->IsArrayClass());
    196   DCHECK(GetClass()->GetComponentType()->IsPrimitiveLong() ||
    197          GetClass()->GetComponentType()->IsPrimitiveDouble());
    198   return down_cast<LongArray*>(this);
    199 }
    200 
    201 inline String* Object::AsString() {
    202   DCHECK(GetClass()->IsStringClass());
    203   return down_cast<String*>(this);
    204 }
    205 
    206 inline Throwable* Object::AsThrowable() {
    207   DCHECK(GetClass()->IsThrowableClass());
    208   return down_cast<Throwable*>(this);
    209 }
    210 
    211 inline bool Object::IsWeakReferenceInstance() const {
    212   return GetClass()->IsWeakReferenceClass();
    213 }
    214 
    215 inline bool Object::IsSoftReferenceInstance() const {
    216   return GetClass()->IsSoftReferenceClass();
    217 }
    218 
    219 inline bool Object::IsFinalizerReferenceInstance() const {
    220   return GetClass()->IsFinalizerReferenceClass();
    221 }
    222 
    223 inline bool Object::IsPhantomReferenceInstance() const {
    224   return GetClass()->IsPhantomReferenceClass();
    225 }
    226 
    227 inline size_t Object::SizeOf() const {
    228   size_t result;
    229   if (IsArrayInstance()) {
    230     result = AsArray()->SizeOf();
    231   } else if (IsClass()) {
    232     result = AsClass()->SizeOf();
    233   } else {
    234     result = GetClass()->GetObjectSize();
    235   }
    236   DCHECK(!IsArtField()  || result == sizeof(ArtField));
    237   DCHECK(!IsArtMethod() || result == sizeof(ArtMethod));
    238   return result;
    239 }
    240 
    241 inline uint64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) const {
    242   VerifyObject(this);
    243   const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
    244   const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
    245   if (UNLIKELY(is_volatile)) {
    246     uint64_t result = QuasiAtomic::Read64(addr);
    247     ANDROID_MEMBAR_FULL();
    248     return result;
    249   } else {
    250     return *addr;
    251   }
    252 }
    253 
    254 inline void Object::SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile) {
    255   VerifyObject(this);
    256   byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
    257   int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
    258   if (UNLIKELY(is_volatile)) {
    259     ANDROID_MEMBAR_STORE();
    260     QuasiAtomic::Write64(addr, new_value);
    261     // Post-store barrier not required due to use of atomic op or mutex.
    262   } else {
    263     *addr = new_value;
    264   }
    265 }
    266 
    267 inline void Object::WriteBarrierField(const Object* dst, MemberOffset field_offset,
    268                                       const Object* new_value) {
    269   Runtime::Current()->GetHeap()->WriteBarrierField(dst, field_offset, new_value);
    270 }
    271 
    272 inline void Object::VerifyObject(const Object* obj) {
    273   if (kIsDebugBuild) {
    274     Runtime::Current()->GetHeap()->VerifyObject(obj);
    275   }
    276 }
    277 
    278 }  // namespace mirror
    279 }  // namespace art
    280 
    281 #endif  // ART_RUNTIME_MIRROR_OBJECT_INL_H_
    282