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 |