Zeroing out instance variables
Zeroing out instance variables
- Subject: Zeroing out instance variables
- From: Ben Haller <email@hidden>
- Date: Fri, 16 Apr 2010 17:05:42 -0400
Hi all. I've got a situation where I need to reuse some Obj-C
objects. Basically, I'm allocating and deallocating these very
lightweight objects in staggering numbers, more or less continuously,
for minutes to hours at a time, and so the performance overhead of the
allocations really does add up. This app runs on a shared computing
cluster where time is at a premium, so this level of optimization
really is necessary. I am doing this in a retain/release world, not
with GC. The objects in question are subclasses of my own direct
subclass of NSObject.
So I'm keeping an "unused pool" of these objects, and when I'm done
with an object I throw it into the pool, and when I need a new one I
grab one from the pool. I do these operations with inline functions,
so I can get a new object instance very quickly indeed. This works
great, and I've been doing it for a while. Of course -init only gets
called when the object is truly allocated, the first time around.
From then on, I need to be careful to reuse the objects in a way that
is safe. I just got bitten by a bug where I wasn't zeroing out an
ivar that I should have zeroed out when I reused one of my objects,
though. This has led me to consider doing a quick "bzero" call to zap
all the ivars back to zero whenever I reuse an object, to be a bit
more safe. It would entail a bit of a speed hit, but this bug I just
found scared me a bit, so I want to at least try this idea and see how
much of a speed penalty I would pay for the added safety.
The question is how to zero out the ivars correctly. I have the
Class of the object I'm reusing, and I can do the math ahead of time
once. But the class is not fixed at compile time; it depends upon
choices the user makes at runtime. So I have to use the Objective-C
runtime to find my ivar block and zero it out. The first ivar in the
class is known, because it is defined by the common superclass of all
of these objects; it's called "pedigree". So what I'm thinking of
doing is:
1. individualIvarsOffset =
ivar_getOffset(class_getInstanceVariable(individualClass, "pedigree"));
2. individualIvarsSize = class_getInstanceSize(individualClass) -
individualIvarsOffset;
3. bzero(individual + individualIvarsOffset, individualIvarsSize);
Step one gets the offset of the known first instance variable.
This seems safe to me as long as the ivar layout is guaranteed not be
shuffled around arbitrarily; i.e. as long as variables occur in memory
in the order in which they are declared in the header file. Is that a
guarantee that Obj-C gives, or not?
Step two calculates the size of the ivars block that I own (i.e.
not NSObject's ivars, which I certainly don't want to touch; just the
ones for my subclasses) as the total instance size minus the offset of
the known first instance variable. This seems safe given the same
caveat as step one, plus the added caveat that no extra stuff can be
added to the object's memory block at the end; everything from my
first ivar to the end of the malloced block must belong to me. Again,
I'm not sure if this is a guarantee Obj-C gives...?
Step 3 zeros out the ivars of object "individual" for reuse. This
seems reasonable if the first two steps are reasonable. By the way,
the ivars in question are all non-pointers; I'm not risking zeroing
out pointers that should have been released or freed.
So, thoughts? Am I insane? Is the above scheme safe? Is there a
better way? Thanks for any feedback!
(I think this question is appropriate for cocoa-dev rather than the
objc-language list, but my apologies if I have posted to the wrong
forum...)
Ben Haller
McGill University
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden