Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/cocoa/objc_zombie.h" | 5 #import "chrome/browser/cocoa/objc_zombie.h" |
| 6 | 6 |
| 7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
| 8 #include <mach-o/dyld.h> | 8 #include <mach-o/dyld.h> |
| 9 #include <mach-o/nlist.h> | 9 #include <mach-o/nlist.h> |
| 10 | 10 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 137 | 137 |
| 138 Class wasa = object_getClass(self); | 138 Class wasa = object_getClass(self); |
| 139 const size_t size = class_getInstanceSize(wasa); | 139 const size_t size = class_getInstanceSize(wasa); |
| 140 | 140 |
| 141 // Destroy the instance by calling C++ destructors and clearing it | 141 // Destroy the instance by calling C++ destructors and clearing it |
| 142 // to something unlikely to work well if someone references it. | 142 // to something unlikely to work well if someone references it. |
| 143 (*g_object_cxxDestruct)(self); | 143 (*g_object_cxxDestruct)(self); |
| 144 memset(self, '!', size); | 144 memset(self, '!', size); |
| 145 | 145 |
| 146 // If the instance is big enough, make it into a fat zombie and have | 146 // If the instance is big enough, make it into a fat zombie and have |
| 147 // it remember the old isa. Otherwise make it a regular zombie. | 147 // it remember the old |isa|. Otherwise make it a regular zombie. |
| 148 // Setting |isa| rather than using |object_setClass()| because that | |
| 149 // function is implemented with a memory barrier. The runtime's | |
| 150 // |_internal_object_dispose()| (in objc-class.m) does this, so it | |
| 151 // should be safe (messaging free'd objects shouldn't be expected to | |
| 152 // be thread-safe in the first place). | |
| 148 if (size >= g_fatZombieSize) { | 153 if (size >= g_fatZombieSize) { |
| 149 object_setClass(self, g_fatZombieClass); | 154 self->isa = g_fatZombieClass; |
| 150 static_cast<CrFatZombie*>(self)->wasa = wasa; | 155 static_cast<CrFatZombie*>(self)->wasa = wasa; |
| 151 } else { | 156 } else { |
| 152 object_setClass(self, g_zombieClass); | 157 self->isa = g_zombieClass; |
|
Avi (use Gerrit)
2010/06/03 19:16:51
Huh. isa is still public in the objc2 runtime? If
Scott Hess - ex-Googler
2010/06/03 19:46:33
Not sure what you mean. struct objc_class has OBJ
| |
| 153 } | 158 } |
| 154 | 159 |
| 155 // The new record to swap into |g_zombies|. If |g_zombieCount| is | 160 // The new record to swap into |g_zombies|. If |g_zombieCount| is |
| 156 // zero, then |self| will be freed immediately. | 161 // zero, then |self| will be freed immediately. |
| 157 ZombieRecord zombieToFree = {self, wasa}; | 162 ZombieRecord zombieToFree = {self, wasa}; |
| 158 | 163 |
| 159 { | 164 { |
| 160 AutoLock pin(lock_); | 165 AutoLock pin(lock_); |
| 161 if (g_zombieCount > 0) { | 166 if (g_zombieCount > 0) { |
| 162 // Put the current object on the treadmill and keep the previous | 167 // Put the current object on the treadmill and keep the previous |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 if (oldZombies) { | 395 if (oldZombies) { |
| 391 for (size_t i = 0; i < oldCount; ++i) { | 396 for (size_t i = 0; i < oldCount; ++i) { |
| 392 if (oldZombies[i].object) | 397 if (oldZombies[i].object) |
| 393 free(oldZombies[i].object); | 398 free(oldZombies[i].object); |
| 394 } | 399 } |
| 395 free(oldZombies); | 400 free(oldZombies); |
| 396 } | 401 } |
| 397 } | 402 } |
| 398 | 403 |
| 399 } // namespace ObjcEvilDoers | 404 } // namespace ObjcEvilDoers |
| OLD | NEW |