object_reference.h revision 65f5f247a367af9d6b9ac63767b69ecf3ab079bc
1ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers/*
2ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * Copyright (C) 2014 The Android Open Source Project
3ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers *
4ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * Licensed under the Apache License, Version 2.0 (the "License");
5ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * you may not use this file except in compliance with the License.
6ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * You may obtain a copy of the License at
7ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers *
8ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers *      http://www.apache.org/licenses/LICENSE-2.0
9ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers *
10ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * Unless required by applicable law or agreed to in writing, software
11ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * distributed under the License is distributed on an "AS IS" BASIS,
12ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * See the License for the specific language governing permissions and
14ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * limitations under the License.
15ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers */
16ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
17ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers#ifndef ART_RUNTIME_MIRROR_OBJECT_REFERENCE_H_
18ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers#define ART_RUNTIME_MIRROR_OBJECT_REFERENCE_H_
19ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
20b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include "base/mutex.h"  // For Locks::mutator_lock_.
21e63a745f26fec5a5b4162fc83f6e88a1f696c30cHiroshi Yamauchi#include "globals.h"
22a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartier#include "obj_ptr.h"
23ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
24ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersnamespace art {
25ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersnamespace mirror {
26ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
27ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersclass Object;
28ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
29ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers// Classes shared with the managed side of the world need to be packed so that they don't have
30ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers// extra platform specific padding.
31ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers#define MANAGED PACKED(4)
32ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
33ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers// Value type representing a reference to a mirror::Object of type MirrorType.
34ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstemplate<bool kPoisonReferences, class MirrorType>
35ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersclass MANAGED ObjectReference {
36ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers public:
37bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  MirrorType* AsMirrorPtr() const REQUIRES_SHARED(Locks::mutator_lock_) {
38ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return UnCompress();
39ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
40ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
41bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  void Assign(MirrorType* other) REQUIRES_SHARED(Locks::mutator_lock_) {
42ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    reference_ = Compress(other);
43ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
44ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
451a5337fff2cc6cb9d563c8b32aca75f485d23373Mathieu Chartier  void Assign(ObjPtr<MirrorType> ptr)
461a5337fff2cc6cb9d563c8b32aca75f485d23373Mathieu Chartier      REQUIRES_SHARED(Locks::mutator_lock_);
471a5337fff2cc6cb9d563c8b32aca75f485d23373Mathieu Chartier
48ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void Clear() {
49ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    reference_ = 0;
50bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier    DCHECK(IsNull());
51bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  }
52bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier
53bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  bool IsNull() const {
54bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier    return reference_ == 0;
55ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
56ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
57ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  uint32_t AsVRegValue() const {
58ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return reference_;
59ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
60ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
61ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers protected:
62a5931185c97c7b17981a9fc5016834a0bdd9480bChih-Hung Hsieh  explicit ObjectReference(MirrorType* mirror_ptr)
63bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_)
64ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      : reference_(Compress(mirror_ptr)) {
65ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
66ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
67ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // Compress reference to its bit representation.
68bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  static uint32_t Compress(MirrorType* mirror_ptr) REQUIRES_SHARED(Locks::mutator_lock_) {
69ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uintptr_t as_bits = reinterpret_cast<uintptr_t>(mirror_ptr);
70ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return static_cast<uint32_t>(kPoisonReferences ? -as_bits : as_bits);
71ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
72ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
73ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // Uncompress an encoded reference from its bit representation.
74bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  MirrorType* UnCompress() const REQUIRES_SHARED(Locks::mutator_lock_) {
75ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uintptr_t as_bits = kPoisonReferences ? -reference_ : reference_;
76ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return reinterpret_cast<MirrorType*>(as_bits);
77ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
78ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
79ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  friend class Object;
80ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
81ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // The encoded reference to a mirror::Object.
82ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  uint32_t reference_;
83ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers};
84ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
85ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers// References between objects within the managed heap.
86ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstemplate<class MirrorType>
87e63a745f26fec5a5b4162fc83f6e88a1f696c30cHiroshi Yamauchiclass MANAGED HeapReference : public ObjectReference<kPoisonHeapReferences, MirrorType> {
88ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers public:
89ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  static HeapReference<MirrorType> FromMirrorPtr(MirrorType* mirror_ptr)
90bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
91ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return HeapReference<MirrorType>(mirror_ptr);
92ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
93a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartier
94a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartier  static HeapReference<MirrorType> FromObjPtr(ObjPtr<MirrorType> ptr)
95a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartier      REQUIRES_SHARED(Locks::mutator_lock_);
96a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartier
9765f5f247a367af9d6b9ac63767b69ecf3ab079bcHiroshi Yamauchi  bool CasWeakRelaxed(MirrorType* old_ptr, MirrorType* new_ptr)
9865f5f247a367af9d6b9ac63767b69ecf3ab079bcHiroshi Yamauchi      REQUIRES_SHARED(Locks::mutator_lock_);
9965f5f247a367af9d6b9ac63767b69ecf3ab079bcHiroshi Yamauchi
100ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers private:
101a5931185c97c7b17981a9fc5016834a0bdd9480bChih-Hung Hsieh  explicit HeapReference(MirrorType* mirror_ptr) REQUIRES_SHARED(Locks::mutator_lock_)
102e63a745f26fec5a5b4162fc83f6e88a1f696c30cHiroshi Yamauchi      : ObjectReference<kPoisonHeapReferences, MirrorType>(mirror_ptr) {}
103ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers};
104ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
105a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartierstatic_assert(sizeof(mirror::HeapReference<mirror::Object>) == kHeapReferenceSize,
106a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartier              "heap reference size does not match");
107a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartier
108d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier// Standard compressed reference used in the runtime. Used for StackReference and GC roots.
109bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiertemplate<class MirrorType>
110bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass MANAGED CompressedReference : public mirror::ObjectReference<false, MirrorType> {
111bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier public:
112bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  CompressedReference<MirrorType>() REQUIRES_SHARED(Locks::mutator_lock_)
113bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier      : mirror::ObjectReference<false, MirrorType>(nullptr) {}
114bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier
115bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  static CompressedReference<MirrorType> FromMirrorPtr(MirrorType* p)
116bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
117bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier    return CompressedReference<MirrorType>(p);
118bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  }
119bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier
120bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier private:
121a5931185c97c7b17981a9fc5016834a0bdd9480bChih-Hung Hsieh  explicit CompressedReference(MirrorType* p) REQUIRES_SHARED(Locks::mutator_lock_)
122bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier      : mirror::ObjectReference<false, MirrorType>(p) {}
123bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier};
124bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier
125ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}  // namespace mirror
126ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}  // namespace art
127ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
128ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers#endif  // ART_RUNTIME_MIRROR_OBJECT_REFERENCE_H_
129