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
208f4b056427a9d2321e3aa4f21ca8ffb18b3e5ae6David Sehr#include "base/atomic.h"
21b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include "base/mutex.h"  // For Locks::mutator_lock_.
22e63a745f26fec5a5b4162fc83f6e88a1f696c30cHiroshi Yamauchi#include "globals.h"
2309659c22dc2f2c85a0ade965d1fc5160944b8692Andreas Gampe#include "heap_poisoning.h"
24a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartier#include "obj_ptr.h"
25ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
26ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersnamespace art {
27ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersnamespace mirror {
28ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
29ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersclass Object;
30ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
31ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers// Classes shared with the managed side of the world need to be packed so that they don't have
32ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers// extra platform specific padding.
33ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers#define MANAGED PACKED(4)
34ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
35cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehmtemplate<bool kPoisonReferences, class MirrorType>
36cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehmclass PtrCompression {
37cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm public:
38cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  // Compress reference to its bit representation.
39cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  static uint32_t Compress(MirrorType* mirror_ptr) {
40cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    uintptr_t as_bits = reinterpret_cast<uintptr_t>(mirror_ptr);
41cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    return static_cast<uint32_t>(kPoisonReferences ? -as_bits : as_bits);
42cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  }
43cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm
44cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  // Uncompress an encoded reference from its bit representation.
45cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  static MirrorType* Decompress(uint32_t ref) {
46cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    uintptr_t as_bits = kPoisonReferences ? -ref : ref;
47cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    return reinterpret_cast<MirrorType*>(as_bits);
48cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  }
49cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm
50cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  // Convert an ObjPtr to a compressed reference.
51cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  static uint32_t Compress(ObjPtr<MirrorType> ptr) REQUIRES_SHARED(Locks::mutator_lock_) {
52cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    return Compress(ptr.Ptr());
53cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  }
54cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm};
55cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm
56ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers// Value type representing a reference to a mirror::Object of type MirrorType.
57ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstemplate<bool kPoisonReferences, class MirrorType>
58ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersclass MANAGED ObjectReference {
59cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm private:
60cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  using Compression = PtrCompression<kPoisonReferences, MirrorType>;
61cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm
62ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers public:
63cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  MirrorType* AsMirrorPtr() const {
64cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    return Compression::Decompress(reference_);
65ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
66ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
67cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  void Assign(MirrorType* other) {
68cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    reference_ = Compression::Compress(other);
69ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
70ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
71cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  void Assign(ObjPtr<MirrorType> ptr) REQUIRES_SHARED(Locks::mutator_lock_);
721a5337fff2cc6cb9d563c8b32aca75f485d23373Mathieu Chartier
73ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void Clear() {
74ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    reference_ = 0;
75bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier    DCHECK(IsNull());
76bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  }
77bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier
78bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  bool IsNull() const {
79bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier    return reference_ == 0;
80ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
81ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
82ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  uint32_t AsVRegValue() const {
83ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return reference_;
84ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
85ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
86cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  static ObjectReference<kPoisonReferences, MirrorType> FromMirrorPtr(MirrorType* mirror_ptr)
87cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm      REQUIRES_SHARED(Locks::mutator_lock_) {
88cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    return ObjectReference<kPoisonReferences, MirrorType>(mirror_ptr);
89ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
90ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
91cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm protected:
92cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  explicit ObjectReference(MirrorType* mirror_ptr) REQUIRES_SHARED(Locks::mutator_lock_)
93cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm      : reference_(Compression::Compress(mirror_ptr)) {
94ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
95ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
96ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // The encoded reference to a mirror::Object.
97ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  uint32_t reference_;
98ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers};
99ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
100ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers// References between objects within the managed heap.
101cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm// Similar API to ObjectReference, but not a value type. Supports atomic access.
102ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstemplate<class MirrorType>
103cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehmclass MANAGED HeapReference {
104cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm private:
105cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  using Compression = PtrCompression<kPoisonHeapReferences, MirrorType>;
106cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm
107ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers public:
108ad8ebb38059b9fe47fde8b1390113eabba2ac888Mathieu Chartier  HeapReference() REQUIRES_SHARED(Locks::mutator_lock_) : HeapReference(nullptr) {}
109ad8ebb38059b9fe47fde8b1390113eabba2ac888Mathieu Chartier
110cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  template <bool kIsVolatile = false>
111cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  MirrorType* AsMirrorPtr() const REQUIRES_SHARED(Locks::mutator_lock_) {
112cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    return Compression::Decompress(
113cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm        kIsVolatile ? reference_.LoadSequentiallyConsistent() : reference_.LoadJavaData());
114cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  }
115cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm
116cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  template <bool kIsVolatile = false>
117cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  void Assign(MirrorType* other) REQUIRES_SHARED(Locks::mutator_lock_) {
118cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    if (kIsVolatile) {
119cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm      reference_.StoreSequentiallyConsistent(Compression::Compress(other));
120cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    } else {
121cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm      reference_.StoreJavaData(Compression::Compress(other));
122cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    }
123cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  }
124cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm
125cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  template <bool kIsVolatile = false>
126cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  void Assign(ObjPtr<MirrorType> ptr) REQUIRES_SHARED(Locks::mutator_lock_);
127cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm
128cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  void Clear() {
129cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    reference_.StoreJavaData(0);
130cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    DCHECK(IsNull());
131cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  }
132cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm
133cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  bool IsNull() const {
134cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm    return reference_.LoadJavaData() == 0;
135cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  }
136cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm
137ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  static HeapReference<MirrorType> FromMirrorPtr(MirrorType* mirror_ptr)
138bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
139ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return HeapReference<MirrorType>(mirror_ptr);
140ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
141a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartier
14265f5f247a367af9d6b9ac63767b69ecf3ab079bcHiroshi Yamauchi  bool CasWeakRelaxed(MirrorType* old_ptr, MirrorType* new_ptr)
14365f5f247a367af9d6b9ac63767b69ecf3ab079bcHiroshi Yamauchi      REQUIRES_SHARED(Locks::mutator_lock_);
14465f5f247a367af9d6b9ac63767b69ecf3ab079bcHiroshi Yamauchi
145ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers private:
146a5931185c97c7b17981a9fc5016834a0bdd9480bChih-Hung Hsieh  explicit HeapReference(MirrorType* mirror_ptr) REQUIRES_SHARED(Locks::mutator_lock_)
147ad8ebb38059b9fe47fde8b1390113eabba2ac888Mathieu Chartier      : reference_(Compression::Compress(mirror_ptr)) {}
148cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm
149cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  // The encoded reference to a mirror::Object. Atomically updateable.
150cc55e1dcdd2ec669c635420468b3cc4c99740f0aHans Boehm  Atomic<uint32_t> reference_;
151ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers};
152ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
153a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartierstatic_assert(sizeof(mirror::HeapReference<mirror::Object>) == kHeapReferenceSize,
154a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartier              "heap reference size does not match");
155a058fdf0cf7435a13a6e8cae5e3a9bfa1513828dMathieu Chartier
156d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier// Standard compressed reference used in the runtime. Used for StackReference and GC roots.
157bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiertemplate<class MirrorType>
158bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass MANAGED CompressedReference : public mirror::ObjectReference<false, MirrorType> {
159bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier public:
160bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  CompressedReference<MirrorType>() REQUIRES_SHARED(Locks::mutator_lock_)
161bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier      : mirror::ObjectReference<false, MirrorType>(nullptr) {}
162bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier
163bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  static CompressedReference<MirrorType> FromMirrorPtr(MirrorType* p)
164bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
165bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier    return CompressedReference<MirrorType>(p);
166bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  }
167bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier
168bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier private:
169a5931185c97c7b17981a9fc5016834a0bdd9480bChih-Hung Hsieh  explicit CompressedReference(MirrorType* p) REQUIRES_SHARED(Locks::mutator_lock_)
170bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier      : mirror::ObjectReference<false, MirrorType>(p) {}
171bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier};
172bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier
173ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}  // namespace mirror
174ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}  // namespace art
175ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
176ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers#endif  // ART_RUNTIME_MIRROR_OBJECT_REFERENCE_H_
177