Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: chrome/browser/ui/cocoa/objc_zombie.mm

Issue 6142009: Upating the app, ceee, chrome, ipc, media, and net directories to use the correct lock.h file. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Unified patch updating all references to the new base/synchronization/lock.h Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/transport_security_persister.h ('k') | chrome/browser/ui/login/login_prompt.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ui/cocoa/objc_zombie.h" 5 #import "chrome/browser/ui/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
11 #import <objc/objc-class.h> 11 #import <objc/objc-class.h>
12 12
13 #include "base/lock.h"
14 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/synchronization/lock.h"
15 #import "chrome/app/breakpad_mac.h" 15 #import "chrome/app/breakpad_mac.h"
16 #import "chrome/browser/ui/cocoa/objc_method_swizzle.h" 16 #import "chrome/browser/ui/cocoa/objc_method_swizzle.h"
17 17
18 // Deallocated objects are re-classed as |CrZombie|. No superclass 18 // Deallocated objects are re-classed as |CrZombie|. No superclass
19 // because then the class would have to override many/most of the 19 // because then the class would have to override many/most of the
20 // inherited methods (|NSObject| is like a category magnet!). 20 // inherited methods (|NSObject| is like a category magnet!).
21 @interface CrZombie { 21 @interface CrZombie {
22 Class isa; 22 Class isa;
23 } 23 }
24 @end 24 @end
(...skipping 24 matching lines...) Expand all
49 // treadmill). 49 // treadmill).
50 Class g_zombieClass = Nil; // cached [CrZombie class] 50 Class g_zombieClass = Nil; // cached [CrZombie class]
51 Class g_fatZombieClass = Nil; // cached [CrFatZombie class] 51 Class g_fatZombieClass = Nil; // cached [CrFatZombie class]
52 size_t g_fatZombieSize = 0; 52 size_t g_fatZombieSize = 0;
53 53
54 // Whether to zombie all freed objects, or only those which return YES 54 // Whether to zombie all freed objects, or only those which return YES
55 // from |-shouldBecomeCrZombie|. 55 // from |-shouldBecomeCrZombie|.
56 BOOL g_zombieAllObjects = NO; 56 BOOL g_zombieAllObjects = NO;
57 57
58 // Protects |g_zombieCount|, |g_zombieIndex|, and |g_zombies|. 58 // Protects |g_zombieCount|, |g_zombieIndex|, and |g_zombies|.
59 Lock lock_; 59 base::Lock lock_;
60 60
61 // How many zombies to keep before freeing, and the current head of 61 // How many zombies to keep before freeing, and the current head of
62 // the circular buffer. 62 // the circular buffer.
63 size_t g_zombieCount = 0; 63 size_t g_zombieCount = 0;
64 size_t g_zombieIndex = 0; 64 size_t g_zombieIndex = 0;
65 65
66 typedef struct { 66 typedef struct {
67 id object; // The zombied object. 67 id object; // The zombied object.
68 Class wasa; // Value of |object->isa| before we replaced it. 68 Class wasa; // Value of |object->isa| before we replaced it.
69 } ZombieRecord; 69 } ZombieRecord;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 } else { 140 } else {
141 self->isa = g_zombieClass; 141 self->isa = g_zombieClass;
142 } 142 }
143 143
144 // The new record to swap into |g_zombies|. If |g_zombieCount| is 144 // The new record to swap into |g_zombies|. If |g_zombieCount| is
145 // zero, then |self| will be freed immediately. 145 // zero, then |self| will be freed immediately.
146 ZombieRecord zombieToFree = {self, wasa}; 146 ZombieRecord zombieToFree = {self, wasa};
147 147
148 // Don't involve the lock when creating zombies without a treadmill. 148 // Don't involve the lock when creating zombies without a treadmill.
149 if (g_zombieCount > 0) { 149 if (g_zombieCount > 0) {
150 AutoLock pin(lock_); 150 base::AutoLock pin(lock_);
151 151
152 // Check the count again in a thread-safe manner. 152 // Check the count again in a thread-safe manner.
153 if (g_zombieCount > 0) { 153 if (g_zombieCount > 0) {
154 // Put the current object on the treadmill and keep the previous 154 // Put the current object on the treadmill and keep the previous
155 // occupant. 155 // occupant.
156 std::swap(zombieToFree, g_zombies[g_zombieIndex]); 156 std::swap(zombieToFree, g_zombies[g_zombieIndex]);
157 157
158 // Bump the index forward. 158 // Bump the index forward.
159 g_zombieIndex = (g_zombieIndex + 1) % g_zombieCount; 159 g_zombieIndex = (g_zombieIndex + 1) % g_zombieCount;
160 } 160 }
161 } 161 }
162 162
163 // Do the free out here to prevent any chance of deadlock. 163 // Do the free out here to prevent any chance of deadlock.
164 if (zombieToFree.object) 164 if (zombieToFree.object)
165 free(zombieToFree.object); 165 free(zombieToFree.object);
166 } 166 }
167 167
168 // Attempt to determine the original class of zombie |object|. 168 // Attempt to determine the original class of zombie |object|.
169 Class ZombieWasa(id object) { 169 Class ZombieWasa(id object) {
170 // Fat zombies can hold onto their |wasa| past the point where the 170 // Fat zombies can hold onto their |wasa| past the point where the
171 // object was actually freed. Note that to arrive here at all, 171 // object was actually freed. Note that to arrive here at all,
172 // |object|'s memory must still be accessible. 172 // |object|'s memory must still be accessible.
173 if (object_getClass(object) == g_fatZombieClass) 173 if (object_getClass(object) == g_fatZombieClass)
174 return static_cast<CrFatZombie*>(object)->wasa; 174 return static_cast<CrFatZombie*>(object)->wasa;
175 175
176 // For instances which weren't big enough to store |wasa|, check if 176 // For instances which weren't big enough to store |wasa|, check if
177 // the object is still on the treadmill. 177 // the object is still on the treadmill.
178 AutoLock pin(lock_); 178 base::AutoLock pin(lock_);
179 for (size_t i=0; i < g_zombieCount; ++i) { 179 for (size_t i=0; i < g_zombieCount; ++i) {
180 if (g_zombies[i].object == object) 180 if (g_zombies[i].object == object)
181 return g_zombies[i].wasa; 181 return g_zombies[i].wasa;
182 } 182 }
183 183
184 return Nil; 184 return Nil;
185 } 185 }
186 186
187 // Log a message to a freed object. |wasa| is the object's original 187 // Log a message to a freed object. |wasa| is the object's original
188 // class. |aSelector| is the selector which the calling code was 188 // class. |aSelector| is the selector which the calling code was
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 const IMP prevDeallocIMP = method_setImplementation(m, (IMP)ZombieDealloc); 318 const IMP prevDeallocIMP = method_setImplementation(m, (IMP)ZombieDealloc);
319 DCHECK(prevDeallocIMP == g_originalDeallocIMP || 319 DCHECK(prevDeallocIMP == g_originalDeallocIMP ||
320 prevDeallocIMP == (IMP)ZombieDealloc); 320 prevDeallocIMP == (IMP)ZombieDealloc);
321 321
322 // Grab the current set of zombies. This is thread-safe because 322 // Grab the current set of zombies. This is thread-safe because
323 // only the main thread can change these. 323 // only the main thread can change these.
324 const size_t oldCount = g_zombieCount; 324 const size_t oldCount = g_zombieCount;
325 ZombieRecord* oldZombies = g_zombies; 325 ZombieRecord* oldZombies = g_zombies;
326 326
327 { 327 {
328 AutoLock pin(lock_); 328 base::AutoLock pin(lock_);
329 329
330 // Save the old index in case zombies need to be transferred. 330 // Save the old index in case zombies need to be transferred.
331 size_t oldIndex = g_zombieIndex; 331 size_t oldIndex = g_zombieIndex;
332 332
333 // Create the new zombie treadmill, disabling zombies in case of 333 // Create the new zombie treadmill, disabling zombies in case of
334 // failure. 334 // failure.
335 g_zombieIndex = 0; 335 g_zombieIndex = 0;
336 g_zombieCount = zombieCount; 336 g_zombieCount = zombieCount;
337 g_zombies = NULL; 337 g_zombies = NULL;
338 if (g_zombieCount) { 338 if (g_zombieCount) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 // Put back the original implementation of -[NSObject dealloc]. 389 // Put back the original implementation of -[NSObject dealloc].
390 Method m = class_getInstanceMethod([NSObject class], @selector(dealloc)); 390 Method m = class_getInstanceMethod([NSObject class], @selector(dealloc));
391 CHECK(m); 391 CHECK(m);
392 method_setImplementation(m, g_originalDeallocIMP); 392 method_setImplementation(m, g_originalDeallocIMP);
393 393
394 // Can safely grab this because it only happens on the main thread. 394 // Can safely grab this because it only happens on the main thread.
395 const size_t oldCount = g_zombieCount; 395 const size_t oldCount = g_zombieCount;
396 ZombieRecord* oldZombies = g_zombies; 396 ZombieRecord* oldZombies = g_zombies;
397 397
398 { 398 {
399 AutoLock pin(lock_); // In case any |-dealloc| are in-progress. 399 base::AutoLock pin(lock_); // In case any |-dealloc| are in-progress.
400 g_zombieCount = 0; 400 g_zombieCount = 0;
401 g_zombies = NULL; 401 g_zombies = NULL;
402 } 402 }
403 403
404 // Free any remaining zombies. 404 // Free any remaining zombies.
405 if (oldZombies) { 405 if (oldZombies) {
406 for (size_t i = 0; i < oldCount; ++i) { 406 for (size_t i = 0; i < oldCount; ++i) {
407 if (oldZombies[i].object) 407 if (oldZombies[i].object)
408 free(oldZombies[i].object); 408 free(oldZombies[i].object);
409 } 409 }
410 free(oldZombies); 410 free(oldZombies);
411 } 411 }
412 } 412 }
413 413
414 } // namespace ObjcEvilDoers 414 } // namespace ObjcEvilDoers
OLDNEW
« no previous file with comments | « chrome/browser/transport_security_persister.h ('k') | chrome/browser/ui/login/login_prompt.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698