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