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