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

Unified Diff: chrome/browser/ui/cocoa/objc_zombie.mm

Issue 7084017: [Mac] Use object_destructInstance() if available. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/cocoa/objc_zombie.mm
diff --git a/chrome/browser/ui/cocoa/objc_zombie.mm b/chrome/browser/ui/cocoa/objc_zombie.mm
index 31d2a62a9f4d6c1ddbd121963dc02c57e8c5cc32..452789cb29ceb8b744670cbb95fcb1087e10242c 100644
--- a/chrome/browser/ui/cocoa/objc_zombie.mm
+++ b/chrome/browser/ui/cocoa/objc_zombie.mm
@@ -33,12 +33,13 @@
namespace {
-// |object_cxxDestruct()| is an Objective-C runtime function which
-// traverses the object's class tree for ".cxxdestruct" methods which
-// are run to call C++ destructors as part of |-dealloc|. The
-// function is not public, so must be looked up using nlist.
+// Function which destroys the contents of an object without freeing
+// the object. On 10.5 this is |object_cxxDestruct()|, which
+// traverses the class hierarchy to run the C++ destructors. On 10.6
+// this is |objc_destructInstance()| which calls
+// |object_cxxDestruct()| and removes associative references.
typedef void DestructFn(id obj);
Mark Mentovai 2011/05/28 13:20:46 Technically the function pointer types are incompa
Scott Hess - ex-Googler 2011/05/31 20:22:30 Augmented the comment to that end.
-DestructFn* g_object_cxxDestruct = NULL;
+DestructFn* g_objectDestruct = NULL;
// The original implementation for |-[NSObject dealloc]|.
IMP g_originalDeallocIMP = NULL;
@@ -70,9 +71,9 @@ typedef struct {
ZombieRecord* g_zombies = NULL;
-// Lookup the private |object_cxxDestruct| function and return a
-// pointer to it. Returns |NULL| on failure.
-DestructFn* LookupObjectCxxDestruct() {
+// Lookup the private object destruction function and return a pointer
+// to it. Returns |NULL| on failure.
+DestructFn* LookupObjectDestruct() {
#if ARCH_CPU_64_BITS
Mark Mentovai 2011/05/28 13:20:46 Put this below the dlsym (but keep it before the n
Scott Hess - ex-Googler 2011/05/31 20:22:30 You sure? I think it's the right long-term decisi
Mark Mentovai 2011/05/31 21:00:57 shess wrote:
Scott Hess - ex-Googler 2011/06/07 21:24:51 Done. AFAICT, nlist() isn't present for 64-bit, a
// TODO(shess): Port to 64-bit. I believe using struct nlist_64
// will suffice. http://crbug.com/44021 .
@@ -80,6 +81,10 @@ DestructFn* LookupObjectCxxDestruct() {
return NULL;
#endif
+ void* fn = dlsym(RTLD_DEFAULT, "objc_destructInstance");
Mark Mentovai 2011/05/29 22:02:31 RTLD_DEFAULT kind of sucks for a few reasons. It’l
Scott Hess - ex-Googler 2011/05/31 20:22:30 Done. I do not know what I'm doing in this area,
+ if (fn)
+ return (DestructFn*)fn;
Scott Hess - ex-Googler 2011/05/28 05:44:35 I need to clean up the casting in this function, a
Scott Hess - ex-Googler 2011/05/31 20:22:30 OK, casting is so annoying that I'm not sure I'm d
+
struct nlist nl[3];
Mark Mentovai 2011/05/29 22:02:31 If we can’t find objc_destructInstance with dlsym
Scott Hess - ex-Googler 2011/05/31 20:22:30 Earlier when I put in the whitelist, I left it way
Mark Mentovai 2011/05/31 21:00:57 shess wrote:
bzero(&nl, sizeof(nl));
@@ -109,12 +114,12 @@ void ZombieDealloc(id self, SEL _cmd) {
return;
}
- // Use the original |-dealloc| if |object_cxxDestruct| was never
+ // Use the original |-dealloc| if |g_objectDestruct| was never
// initialized, because otherwise C++ destructors won't be called.
// This case should be impossible, but doing it wrong would cause
// terrible problems.
- DCHECK(g_object_cxxDestruct);
- if (!g_object_cxxDestruct) {
+ DCHECK(g_objectDestruct);
+ if (!g_objectDestruct) {
g_originalDeallocIMP(self, _cmd);
return;
}
@@ -124,7 +129,11 @@ void ZombieDealloc(id self, SEL _cmd) {
// Destroy the instance by calling C++ destructors and clearing it
// to something unlikely to work well if someone references it.
- (*g_object_cxxDestruct)(self);
+ // NOTE(shess): |object_dispose()| will call this again when the
+ // zombie falls off the treadmill! But by then |isa| will be a
+ // class without C++ destructors or associative references, so it
+ // won't hurt anything.
Scott Hess - ex-Googler 2011/05/28 05:44:35 Sorry, I think this comment snuck over when I brok
Mark Mentovai 2011/05/28 13:20:46 shess wrote:
+ (*g_objectDestruct)(self);
memset(self, '!', size);
// If the instance is big enough, make it into a fat zombie and have
@@ -219,7 +228,7 @@ BOOL ZombieInit() {
Class rootClass = [NSObject class];
- g_object_cxxDestruct = LookupObjectCxxDestruct();
+ g_objectDestruct = LookupObjectDestruct();
g_originalDeallocIMP =
class_getMethodImplementation(rootClass, @selector(dealloc));
// objc_getClass() so CrZombie doesn't need +class.
@@ -227,7 +236,7 @@ BOOL ZombieInit() {
g_fatZombieClass = objc_getClass("CrFatZombie");
g_fatZombieSize = class_getInstanceSize(g_fatZombieClass);
- if (!g_object_cxxDestruct || !g_originalDeallocIMP ||
+ if (!g_objectDestruct || !g_originalDeallocIMP ||
!g_zombieClass || !g_fatZombieClass)
return NO;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698