Re: NSAllocateCollectable() questions
Re: NSAllocateCollectable() questions
- Subject: Re: NSAllocateCollectable() questions
- From: Greg Parker <email@hidden>
- Date: Tue, 15 Apr 2008 13:53:35 -0700
Brendan Younger wrote:
I've been writing a library that uses NSAllocateCollectable() quite
a bit and I have a few questions about proper usage.
For those of you playing along at home, let me summarize the reasons
for the garbage collector's special functions.
Some heap blocks are "GC-managed". The garbage collector will destroy
a GC-managed block if no pointers to it are found during the GC's
scan. NSAllocateCollectable() and [NSObject alloc] return GC-managed
blocks. malloc() does not.
Some memory areas are "GC-scanned". The garbage collector will look in
these regions for interesting pointer values.
NSAllocateCollectable(NSScannedOption) returns a block of scanned
memory. NSAllocateCollectable(no NSScannedOption) and malloc() do not;
their contents are invisible to the garbage collector.
The Rule for Write Barriers:
If you write a pointer to a GC-managed block into GC-scanned heap
memory, you must use an appropriate write barrier.
Why? Speed. Write barriers allow the garbage collector to cheat, like
not scanning large swaths of memory, or allowing other threads to
continue running (and modifying memory) while a scan is in progress.
Without write barriers, the collector might miss a pointer because
it's cheating.
Usually, the compiler does this for you. If `variable` is of an
Objective-C object type or a __strong pointer type, and you write
`variable = value`, then the compiler will emit an appropriate write
barrier for you.
Note that __weak memory, and memory outside the heap like globals and
thread stacks, are all handled differently.
- Copying data
if I am copying to a malloc'd block, I can use memmove() regardless
of whether the source is GC'd or not, right?
if I am copying to a GC block allocated with nonscanned memory, I
can use memmove(), right?
Correct. If you're writing to GC-unscanned heap memory, then you don't
need a write barrier. Of course, the contents of the malloc block and
managed-but-unscanned block are invisible to the garbage collector, so
you need to be wary of writing GC-managed pointers into it.
if I am copying to a GC block allocated with NSScannedOption, I need
to use objc_memmove_collectable(), right?
Correct. The only exception is if the memory being copied contains no
GC-managed pointer values then you may use memmove(). If you're not
sure, use objc_memmove_collectable().
- Zero'ing data
There does not seem to be a GC-compatible bzero(). If I loop through
and zero out each pointer in a scanned block, that would generate a
write barrier for each pointer which is expensive. However, if I use
bzero(), then libauto won't know that I've messed with the block.
Will it eventually figure it out when it does an exhaustive scan? Or
will it never notice that I've zero'd out the block?
You don't need a write barrier when erasing GC-scanned memory. The
write barrier helps the collector see pointers that it might otherwise
miss because it's cheating. It does not help the collector "forget" a
value that it saw previously. (In particular, the old pointer value
might be gone from the zeroed location, but without re-scanning
everything there's no way to know that it doesn't still exist
somewhere else.)
--
Greg Parker email@hidden Runtime Wrangler
_______________________________________________
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