RefBase.cpp revision 6d4419d9b130719dd2355861907dc8f87368a51c
1cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
2cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project
3cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *
4cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * you may not use this file except in compliance with the License.
6cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * You may obtain a copy of the License at
7cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *
8cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *
10cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * See the License for the specific language governing permissions and
14cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * limitations under the License.
15cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
16cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
17cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define LOG_TAG "RefBase"
188a4cdbcdb935554a660c78e20686afdad8e8ca75Mathias Agopian#define LOG_NDEBUG 0
19cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
20cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/RefBase.h>
21cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
22cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/Atomic.h>
23cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/CallStack.h>
24cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/Log.h>
25cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/threads.h>
26ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#include <utils/TextOutput.h>
27cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
28cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <stdlib.h>
29cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <stdio.h>
30cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <typeinfo>
31cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <sys/types.h>
32cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <sys/stat.h>
33cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <fcntl.h>
34cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <unistd.h>
35cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
36cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// compile with refcounting debugging enabled
37cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define DEBUG_REFS                      0
386d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian
396d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian// whether ref-tracking is enabled by default, if not, trackMe(true, false)
406d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian// needs to be called explicitly
416d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian#define DEBUG_REFS_ENABLED_BY_DEFAULT   0
426d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian
436d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian// whether callstack are collected (significantly slows things down)
44cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define DEBUG_REFS_CALLSTACK_ENABLED    1
45cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
466d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian// folder where stack traces are saved when DEBUG_REFS is enabled
476d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian// this folder needs to exist and be writable
486d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian#define DEBUG_REFS_CALLSTACK_PATH       "/data/debug"
496d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian
50cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// log all reference counting operations
51cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define PRINT_REFS                      0
52cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
53cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
54cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
55cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectnamespace android {
56cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
57cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define INITIAL_STRONG_VALUE (1<<28)
58cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
59cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
60cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
61cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectclass RefBase::weakref_impl : public RefBase::weakref_type
62cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
63cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectpublic:
64cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    volatile int32_t    mStrong;
65cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    volatile int32_t    mWeak;
66cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    RefBase* const      mBase;
67cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    volatile int32_t    mFlags;
689c8fa9ed4111c69c82ace01c8a7ac3beeacdce78Mathias Agopian
69cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if !DEBUG_REFS
70cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
71cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    weakref_impl(RefBase* base)
72cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        : mStrong(INITIAL_STRONG_VALUE)
73cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        , mWeak(0)
74cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        , mBase(base)
75cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        , mFlags(0)
76cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    {
77cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
78cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
79cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    void addStrongRef(const void* /*id*/) { }
80cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    void removeStrongRef(const void* /*id*/) { }
81ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }
82cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    void addWeakRef(const void* /*id*/) { }
83cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    void removeWeakRef(const void* /*id*/) { }
84ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }
85cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    void printRefs() const { }
86cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    void trackMe(bool, bool) { }
87cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
88cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#else
89cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
90cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    weakref_impl(RefBase* base)
91cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        : mStrong(INITIAL_STRONG_VALUE)
92cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        , mWeak(0)
93cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        , mBase(base)
94cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        , mFlags(0)
95cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        , mStrongRefs(NULL)
96cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        , mWeakRefs(NULL)
97cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
98cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        , mRetain(false)
99cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    {
100cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
101cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
102cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    ~weakref_impl()
103cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    {
104ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        bool dumpStack = false;
105ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        if (!mRetain && mStrongRefs != NULL) {
106ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            dumpStack = true;
1071b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block            ALOGE("Strong references remain:");
108ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            ref_entry* refs = mStrongRefs;
109ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            while (refs) {
110ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                char inc = refs->ref >= 0 ? '+' : '-';
111eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block                ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
112ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#if DEBUG_REFS_CALLSTACK_ENABLED
113ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                refs->stack.dump();
114ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#endif
115ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                refs = refs->next;
116ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            }
117ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        }
118ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
119ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        if (!mRetain && mWeakRefs != NULL) {
120ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            dumpStack = true;
1211b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block            ALOGE("Weak references remain!");
122ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            ref_entry* refs = mWeakRefs;
123ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            while (refs) {
124ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                char inc = refs->ref >= 0 ? '+' : '-';
125eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block                ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
126ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#if DEBUG_REFS_CALLSTACK_ENABLED
127ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                refs->stack.dump();
128ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#endif
129ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                refs = refs->next;
130ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            }
131ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        }
132ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        if (dumpStack) {
1331b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block            ALOGE("above errors at:");
134ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            CallStack stack;
135ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            stack.update();
136ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            stack.dump();
137ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        }
138cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
139cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
140ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    void addStrongRef(const void* id) {
141eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block        //ALOGD_IF(mTrackEnabled,
142ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        //        "addStrongRef: RefBase=%p, id=%p", mBase, id);
143cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        addRef(&mStrongRefs, id, mStrong);
144cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
145cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
146ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    void removeStrongRef(const void* id) {
147eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block        //ALOGD_IF(mTrackEnabled,
148ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        //        "removeStrongRef: RefBase=%p, id=%p", mBase, id);
149ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        if (!mRetain) {
150cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            removeRef(&mStrongRefs, id);
151ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        } else {
152cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            addRef(&mStrongRefs, id, -mStrong);
153ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        }
154cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
155cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
156ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    void renameStrongRefId(const void* old_id, const void* new_id) {
157eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block        //ALOGD_IF(mTrackEnabled,
158ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        //        "renameStrongRefId: RefBase=%p, oid=%p, nid=%p",
159ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        //        mBase, old_id, new_id);
160ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        renameRefsId(mStrongRefs, old_id, new_id);
161ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    }
162ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
163ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    void addWeakRef(const void* id) {
164cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        addRef(&mWeakRefs, id, mWeak);
165cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
166cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
167ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    void removeWeakRef(const void* id) {
168ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        if (!mRetain) {
169cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            removeRef(&mWeakRefs, id);
170ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        } else {
171cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            addRef(&mWeakRefs, id, -mWeak);
172ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        }
173ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    }
174ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
175ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    void renameWeakRefId(const void* old_id, const void* new_id) {
176ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        renameRefsId(mWeakRefs, old_id, new_id);
177cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
178cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
179cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    void trackMe(bool track, bool retain)
180cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    {
181cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        mTrackEnabled = track;
182cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        mRetain = retain;
183cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
184cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
185cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    void printRefs() const
186cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    {
187cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        String8 text;
188cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
189cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        {
190ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            Mutex::Autolock _l(mMutex);
191cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            char buf[128];
192cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
193cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            text.append(buf);
194cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            printRefsLocked(&text, mStrongRefs);
195cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this);
196cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            text.append(buf);
197cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            printRefsLocked(&text, mWeakRefs);
198cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
199cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
200cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        {
201cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            char name[100];
2026d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian            snprintf(name, 100, DEBUG_REFS_CALLSTACK_PATH "/%p.stack", this);
203769828d2d44fca3829e628bb424aa426aa468ee9Mathias Agopian            int rc = open(name, O_RDWR | O_CREAT | O_APPEND, 644);
204cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            if (rc >= 0) {
205cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                write(rc, text.string(), text.length());
206cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                close(rc);
207eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block                ALOGD("STACK TRACE for %p saved in %s", this, name);
208cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            }
2091b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block            else ALOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this,
210cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                      name, strerror(errno));
211cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
212cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
213cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
214cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectprivate:
215cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    struct ref_entry
216cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    {
217cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        ref_entry* next;
218cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        const void* id;
219cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED
220cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        CallStack stack;
221cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif
222cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        int32_t ref;
223cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    };
224cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
225cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    void addRef(ref_entry** refs, const void* id, int32_t mRef)
226cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    {
227cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        if (mTrackEnabled) {
228cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            AutoMutex _l(mMutex);
229ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
230cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            ref_entry* ref = new ref_entry;
231cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            // Reference count at the time of the snapshot, but before the
232cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            // update.  Positive value means we increment, negative--we
233cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            // decrement the reference count.
234cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            ref->ref = mRef;
235cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            ref->id = id;
236cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED
237cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            ref->stack.update(2);
238cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif
239cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            ref->next = *refs;
240cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            *refs = ref;
241cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
242cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
243cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
244cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    void removeRef(ref_entry** refs, const void* id)
245cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    {
246cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        if (mTrackEnabled) {
247cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            AutoMutex _l(mMutex);
248cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
249ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            ref_entry* const head = *refs;
250ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            ref_entry* ref = head;
251cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            while (ref != NULL) {
252cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                if (ref->id == id) {
253cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                    *refs = ref->next;
254cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                    delete ref;
255cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                    return;
256cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                }
257cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                refs = &ref->next;
258cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                ref = *refs;
259cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            }
260ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
2611b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block            ALOGE("RefBase: removing id %p on RefBase %p"
262ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                    "(weakref_type %p) that doesn't exist!",
263ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                    id, mBase, this);
264ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
265ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            ref = head;
266ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            while (ref) {
267ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                char inc = ref->ref >= 0 ? '+' : '-';
268eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block                ALOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref);
269ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                ref = ref->next;
270ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            }
271ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
272ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            CallStack stack;
273ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            stack.update();
274ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            stack.dump();
275ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        }
276ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    }
277ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
278ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    void renameRefsId(ref_entry* r, const void* old_id, const void* new_id)
279ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    {
280ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        if (mTrackEnabled) {
281ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            AutoMutex _l(mMutex);
282ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            ref_entry* ref = r;
283ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            while (ref != NULL) {
284ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                if (ref->id == old_id) {
285ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                    ref->id = new_id;
286ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                }
287ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                ref = ref->next;
288ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            }
289cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
290cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
291cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
292cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    void printRefsLocked(String8* out, const ref_entry* refs) const
293cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    {
294cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        char buf[128];
295cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        while (refs) {
296cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            char inc = refs->ref >= 0 ? '+' : '-';
297cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            sprintf(buf, "\t%c ID %p (ref %d):\n",
298cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                    inc, refs->id, refs->ref);
299cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            out->append(buf);
300cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED
301cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            out->append(refs->stack.toString("\t\t"));
302cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#else
303cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            out->append("\t\t(call stacks disabled)");
304cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif
305cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            refs = refs->next;
306cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
307cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
308cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
309ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    mutable Mutex mMutex;
310cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    ref_entry* mStrongRefs;
311cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    ref_entry* mWeakRefs;
312cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
313cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    bool mTrackEnabled;
314cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    // Collect stack traces on addref and removeref, instead of deleting the stack references
315cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    // on removeref that match the address ones.
316cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    bool mRetain;
317cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
318cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif
319cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project};
320cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
321cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
322cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
323cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::incStrong(const void* id) const
324cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
325cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    weakref_impl* const refs = mRefs;
326cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    refs->incWeak(id);
327cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
328cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    refs->addStrongRef(id);
329cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    const int32_t c = android_atomic_inc(&refs->mStrong);
330ae07445e9793724324b93bb593fe20be2a386707Steve Block    ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
331cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if PRINT_REFS
332eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
333cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif
334cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (c != INITIAL_STRONG_VALUE)  {
335cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        return;
336cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
337cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
338cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
339ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    refs->mBase->onFirstRef();
340cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
341cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
342cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::decStrong(const void* id) const
343cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
344cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    weakref_impl* const refs = mRefs;
345cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    refs->removeStrongRef(id);
346cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    const int32_t c = android_atomic_dec(&refs->mStrong);
347cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if PRINT_REFS
348eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
349cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif
350ae07445e9793724324b93bb593fe20be2a386707Steve Block    ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
351cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (c == 1) {
352ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        refs->mBase->onLastStrongRef(id);
353ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
3549c8fa9ed4111c69c82ace01c8a7ac3beeacdce78Mathias Agopian            delete this;
355cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
356cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
357cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    refs->decWeak(id);
358cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
359cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
360cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::forceIncStrong(const void* id) const
361cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
362cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    weakref_impl* const refs = mRefs;
363cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    refs->incWeak(id);
364cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
365cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    refs->addStrongRef(id);
366cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    const int32_t c = android_atomic_inc(&refs->mStrong);
367ae07445e9793724324b93bb593fe20be2a386707Steve Block    ALOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",
368cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project               refs);
369cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if PRINT_REFS
370eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c);
371cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif
372cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
373cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    switch (c) {
374cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    case INITIAL_STRONG_VALUE:
375cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
376cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        // fall through...
377cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    case 0:
378ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        refs->mBase->onFirstRef();
379cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
380cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
381cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
382cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint32_t RefBase::getStrongCount() const
383cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
384cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return mRefs->mStrong;
385cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
386cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
387cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectRefBase* RefBase::weakref_type::refBase() const
388cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
389cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return static_cast<const weakref_impl*>(this)->mBase;
390cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
391cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
392cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::weakref_type::incWeak(const void* id)
393cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
394cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    weakref_impl* const impl = static_cast<weakref_impl*>(this);
395cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    impl->addWeakRef(id);
396cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    const int32_t c = android_atomic_inc(&impl->mWeak);
397ae07445e9793724324b93bb593fe20be2a386707Steve Block    ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
398cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
399cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
400ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
401cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::weakref_type::decWeak(const void* id)
402cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
403cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    weakref_impl* const impl = static_cast<weakref_impl*>(this);
404cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    impl->removeWeakRef(id);
405cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    const int32_t c = android_atomic_dec(&impl->mWeak);
406ae07445e9793724324b93bb593fe20be2a386707Steve Block    ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
407cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (c != 1) return;
408ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
409ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
410ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        // This is the regular lifetime case. The object is destroyed
411ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        // when the last strong reference goes away. Since weakref_impl
412ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        // outlive the object, it is not destroyed in the dtor, and
413ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        // we'll have to do it here.
414ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        if (impl->mStrong == INITIAL_STRONG_VALUE) {
415ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            // Special case: we never had a strong reference, so we need to
416ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            // destroy the object now.
4179c8fa9ed4111c69c82ace01c8a7ac3beeacdce78Mathias Agopian            delete impl->mBase;
418ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        } else {
419b37fbe9f810545bf62468fea5958325caa3635beSteve Block            // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
420cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            delete impl;
421cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
422cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    } else {
423ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
424cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        impl->mBase->onLastWeakRef(id);
425ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
426ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
427ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            // is gone, we can destroy the object.
4289c8fa9ed4111c69c82ace01c8a7ac3beeacdce78Mathias Agopian            delete impl->mBase;
429cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
430cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
431cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
432cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
433cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectbool RefBase::weakref_type::attemptIncStrong(const void* id)
434cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
435cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    incWeak(id);
436cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
437cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    weakref_impl* const impl = static_cast<weakref_impl*>(this);
438cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    int32_t curCount = impl->mStrong;
439a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn
440a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn    ALOG_ASSERT(curCount >= 0,
441a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            "attemptIncStrong called on %p after underflow", this);
442a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn
443cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
444a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        // we're in the easy/common case of promoting a weak-reference
445a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        // from an existing strong reference.
446cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
447cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            break;
448cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
449a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        // the strong count has changed on us, we need to re-assert our
450a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        // situation.
451cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        curCount = impl->mStrong;
452cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
453cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
454cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
455a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        // we're now in the harder case of either:
456a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        // - there never was a strong reference on us
457a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        // - or, all strong references have been released
458a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
459a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            // this object has a "normal" life-time, i.e.: it gets destroyed
460a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            // when the last strong reference goes away
461a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            if (curCount <= 0) {
462a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                // the last strong-reference got released, the object cannot
463a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                // be revived.
464a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                decWeak(id);
465a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                return false;
466a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            }
467a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn
468a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            // here, curCount == INITIAL_STRONG_VALUE, which means
469a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            // there never was a strong-reference, so we can try to
470a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            // promote this object; we need to do that atomically.
471a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            while (curCount > 0) {
472a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                if (android_atomic_cmpxchg(curCount, curCount + 1,
473a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                        &impl->mStrong) == 0) {
474a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                    break;
475a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                }
476a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                // the strong count has changed on us, we need to re-assert our
477a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                // situation (e.g.: another thread has inc/decStrong'ed us)
478a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                curCount = impl->mStrong;
479a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            }
480a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn
481a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            if (curCount <= 0) {
482a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                // promote() failed, some other thread destroyed us in the
483a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                // meantime (i.e.: strong count reached zero).
484a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                decWeak(id);
485a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                return false;
486a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            }
487cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        } else {
488a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            // this object has an "extended" life-time, i.e.: it can be
489a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            // revived from a weak-reference only.
490a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            // Ask the object's implementation if it agrees to be revived
491a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) {
492a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                // it didn't so give-up.
493a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                decWeak(id);
494a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                return false;
495a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            }
496a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            // grab a strong-reference, which is always safe due to the
497a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            // extended life-time.
498a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            curCount = android_atomic_inc(&impl->mStrong);
499cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
500cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
501cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        // If the strong reference count has already been incremented by
502cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        // someone else, the implementor of onIncStrongAttempted() is holding
503cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        // an unneeded reference.  So call onLastStrongRef() here to remove it.
504cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        // (No, this is not pretty.)  Note that we MUST NOT do this if we
505cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        // are in fact acquiring the first reference.
506cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
507cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            impl->mBase->onLastStrongRef(id);
508cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
509cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
510cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
511cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    impl->addStrongRef(id);
512cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
513cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if PRINT_REFS
514eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
515cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif
516cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
517a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn    // now we need to fix-up the count if it was INITIAL_STRONG_VALUE
518a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn    // this must be done safely, i.e.: handle the case where several threads
519a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn    // were here in attemptIncStrong().
520a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn    curCount = impl->mStrong;
521a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn    while (curCount >= INITIAL_STRONG_VALUE) {
522a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        ALOG_ASSERT(curCount > INITIAL_STRONG_VALUE,
523a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                "attemptIncStrong in %p underflowed to INITIAL_STRONG_VALUE",
524a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                this);
525a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        if (android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE,
526a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn                &impl->mStrong) == 0) {
527a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn            break;
528a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        }
529a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        // the strong-count changed on us, we need to re-assert the situation,
530a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        // for e.g.: it's possible the fix-up happened in another thread.
531a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn        curCount = impl->mStrong;
532cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
533a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn
534cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return true;
535cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
536cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
537cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectbool RefBase::weakref_type::attemptIncWeak(const void* id)
538cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
539cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    weakref_impl* const impl = static_cast<weakref_impl*>(this);
540ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
541cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    int32_t curCount = impl->mWeak;
542ae07445e9793724324b93bb593fe20be2a386707Steve Block    ALOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
543cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project               this);
544cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    while (curCount > 0) {
545cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) {
546cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            break;
547cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
548cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        curCount = impl->mWeak;
549cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
550cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
551cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (curCount > 0) {
552cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        impl->addWeakRef(id);
553cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
554cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
555cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return curCount > 0;
556cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
557cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
558cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint32_t RefBase::weakref_type::getWeakCount() const
559cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
560cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return static_cast<const weakref_impl*>(this)->mWeak;
561cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
562cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
563cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::weakref_type::printRefs() const
564cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
565cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    static_cast<const weakref_impl*>(this)->printRefs();
566cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
567cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
568cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::weakref_type::trackMe(bool enable, bool retain)
569cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
570ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    static_cast<weakref_impl*>(this)->trackMe(enable, retain);
571cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
572cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
573cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectRefBase::weakref_type* RefBase::createWeak(const void* id) const
574cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
575cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    mRefs->incWeak(id);
576cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return mRefs;
577cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
578cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
579cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectRefBase::weakref_type* RefBase::getWeakRefs() const
580cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
581cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return mRefs;
582cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
583cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
584cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectRefBase::RefBase()
585cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    : mRefs(new weakref_impl(this))
586cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
587cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
588cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
589cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectRefBase::~RefBase()
590cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
591ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    if (mRefs->mStrong == INITIAL_STRONG_VALUE) {
592ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        // we never acquired a strong (and/or weak) reference on this object.
5939c8fa9ed4111c69c82ace01c8a7ac3beeacdce78Mathias Agopian        delete mRefs;
594ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    } else {
595ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        // life-time of this object is extended to WEAK or FOREVER, in
596ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        // which case weakref_impl doesn't out-live the object and we
597ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        // can free it now.
598ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {
599ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            // It's possible that the weak count is not 0 if the object
600ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            // re-acquired a weak reference in its destructor
601ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            if (mRefs->mWeak == 0) {
602ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian                delete mRefs;
603ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian            }
604ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        }
605cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
606ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    // for debugging purposes, clear this.
607ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    const_cast<weakref_impl*&>(mRefs) = NULL;
608cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
609cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
610cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::extendObjectLifetime(int32_t mode)
611cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
612cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    android_atomic_or(mode, &mRefs->mFlags);
613cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
614cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
615cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::onFirstRef()
616cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
617cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
618cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
619cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::onLastStrongRef(const void* /*id*/)
620cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
621cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
622cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
623cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectbool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
624cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
625cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return (flags&FIRST_INC_STRONG) ? true : false;
626cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
627cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
628cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::onLastWeakRef(const void* /*id*/)
629cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{
630cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
631ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
632ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian// ---------------------------------------------------------------------------
633ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
634ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopianvoid RefBase::moveReferences(void* dst, void const* src, size_t n,
635ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        const ReferenceConverterBase& caster)
636ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian{
637ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#if DEBUG_REFS
638ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    const size_t itemSize = caster.getReferenceTypeSize();
639ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    for (size_t i=0 ; i<n ; i++) {
640ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        void*       d = reinterpret_cast<void      *>(intptr_t(dst) + i*itemSize);
641ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        void const* s = reinterpret_cast<void const*>(intptr_t(src) + i*itemSize);
642ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        RefBase* ref(reinterpret_cast<RefBase*>(caster.getReferenceBase(d)));
643ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        ref->mRefs->renameStrongRefId(s, d);
644ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian        ref->mRefs->renameWeakRefId(s, d);
645ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    }
646ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#endif
647ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian}
648ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
649ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian// ---------------------------------------------------------------------------
650ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
651ad09965050f8226fda6f5238db060ce65abaa71cMathias AgopianTextOutput& printStrongPointer(TextOutput& to, const void* val)
652ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian{
653ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    to << "sp<>(" << val << ")";
654ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    return to;
655ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian}
656ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
657ad09965050f8226fda6f5238db060ce65abaa71cMathias AgopianTextOutput& printWeakPointer(TextOutput& to, const void* val)
658ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian{
659ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    to << "wp<>(" << val << ")";
660ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian    return to;
661ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian}
662ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
663ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian
664cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}; // namespace android
665