diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-11 00:08:37 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-11 00:08:37 +0000 |
commit | bc1eae2c47e4bda12bf2319ee9547a690870744f (patch) | |
tree | 879564d0e1ba606ccad3422f26c2fabc3004c4da | |
parent | c82ab8a9ae4f81478d68a274e59ee030d272d1c3 (diff) | |
download | chromium_src-bc1eae2c47e4bda12bf2319ee9547a690870744f.zip chromium_src-bc1eae2c47e4bda12bf2319ee9547a690870744f.tar.gz chromium_src-bc1eae2c47e4bda12bf2319ee9547a690870744f.tar.bz2 |
[Mac] Make CrZombie a superclass-less class.
CrZombie manually overrode all NSObject methods which weren't
overriden to throw. Unfortunately, there were a lot of such methods
from system categories, which made startup slow. Converting CrZombie
to an object with no superclass means there is no need to override
those methods.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/2729015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49476 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/cocoa/objc_zombie.mm | 51 |
1 files changed, 14 insertions, 37 deletions
diff --git a/chrome/browser/cocoa/objc_zombie.mm b/chrome/browser/cocoa/objc_zombie.mm index 1e6584d..35607c5 100644 --- a/chrome/browser/cocoa/objc_zombie.mm +++ b/chrome/browser/cocoa/objc_zombie.mm @@ -15,11 +15,12 @@ #import "chrome/app/breakpad_mac.h" #import "chrome/browser/cocoa/objc_method_swizzle.h" -// Deallocated objects are re-classed as |CrZombie|. Overrides most -// |NSObject| methods to log fatal errors. -@interface CrZombie : NSObject { +// Deallocated objects are re-classed as |CrZombie|. No superclass +// because then the class would have to override many/most of the +// inherited methods (|NSObject| is like a category magnet!). +@interface CrZombie { + Class isa; } - @end // Objects with enough space are made into "fat" zombies, which @@ -95,23 +96,6 @@ DestructFn* LookupObjectCxxDestruct() { return (DestructFn*)((char*)&class_addIvar - nl[1].n_value + nl[0].n_value); } -// Replace all methods in |refClass| which are not implemented in -// |aClass| with |anImp|. -void class_replaceUnimplementedWith(Class aClass, Class refClass, IMP anImp) { - unsigned int methodCount = 0; - Method* methodList = class_copyMethodList(refClass, &methodCount); - if (methodList) { - for (unsigned int i = 0; i < methodCount; ++i) { - const SEL name = method_getName(methodList[i]); - const char* types = method_getTypeEncoding(methodList[i]); - - // Fails if the method already exists, which is fine. - class_addMethod(aClass, name, anImp, types); - } - free(methodList); - } -} - // Replacement |-dealloc| which turns objects into zombies and places // them into |g_zombies| to be freed later. void ZombieDealloc(id self, SEL _cmd) { @@ -221,12 +205,6 @@ void LogAndDie(id object, SEL aSelector, SEL viaSelector) { LOG(FATAL) << [aString UTF8String]; } -// Implements a method which will be used to override NSObject methods -// that zombies don't explicitly implement. -void DoesNotRecognize(id self, SEL _cmd) { - LogAndDie(self, _cmd, 0); -} - // Initialize our globals, returning YES on success. BOOL ZombieInit() { static BOOL initialized = NO; @@ -238,19 +216,15 @@ BOOL ZombieInit() { g_object_cxxDestruct = LookupObjectCxxDestruct(); g_originalDeallocIMP = class_getMethodImplementation(rootClass, @selector(dealloc)); - g_zombieClass = [CrZombie class]; - g_fatZombieClass = [CrFatZombie class]; + // objc_getClass() so CrZombie doesn't need +class. + g_zombieClass = objc_getClass("CrZombie"); + g_fatZombieClass = objc_getClass("CrFatZombie"); g_fatZombieSize = class_getInstanceSize(g_fatZombieClass); if (!g_object_cxxDestruct || !g_originalDeallocIMP || !g_zombieClass || !g_fatZombieClass) return NO; - // Override any inherited methods from |NSObject| with - // |DoesNotRecognize()|. - class_replaceUnimplementedWith(g_zombieClass, rootClass, - (IMP)DoesNotRecognize); - initialized = YES; return YES; } @@ -259,9 +233,12 @@ BOOL ZombieInit() { @implementation CrZombie -// |DoesNotRecognize()| will log and crash for any selector send to -// instances of the class. Override a few methods related to message -// dispatch to provide more specific diagnostic information. +// The Objective-C runtime needs to be able to call this successfully. ++ (void)initialize { +} + +// Override a few methods related to message dispatch to provide +// diagnostic information. - (BOOL)respondsToSelector:(SEL)aSelector { LogAndDie(self, aSelector, _cmd); return NO; |