Date: Sat, 7 Jun 2008 15:31:43 +0100
From: "Hamish Allan" <[EMAIL PROTECTED]>

On Sat, Jun 7, 2008 at 2:18 PM, Michael Ash <[EMAIL PROTECTED]> wrote:

The business about scanning the stack is essentially an
implementation detail; the promise that is being made is that objects
which you're still pointing to won't go away.

We're just interpreting this promise differently. To my mind, while
the variable is still in scope, I *do* have a pointer to the object.

All due respect, "to my mind" isn't a valid technical specification.

It is available for my use until the end of that scope. The fact that
I don't actually make use of it, and the optimising compiler thinks
I'm done with it: *that*'s an implementation detail.

No, it's not. It's a _semantic_ detail. If you do in fact not use the reference, then it is in fact _unused_. Garbage collection is all about what's being used or not. Even if the compiler did not optimize away the use of the variable past that point in the code, if the GC system could otherwise determine you weren't ever going to use it again, it would _still_ be valid for the GC system to collect the object.

How would it be less straightforward? If it returned collected memory
then everything will Just Work for the common case of using the
pointer on the stack. [...]

I agree with you that if it returned collected memory, it would be
more powerful than under retain/release/autorelease. But power and
straightforwardness do not always go hand in hand ;)

Well, in this case I believe they do. The real issue here is that a garbage collection system is trying to co-exist peacefully with a non- GC system. GC systems have been around for a long time, but in many of the examples, the entire environment is garbage-collected and this sort of thing just doesn't come up in normal code.

That said, even in .NET (for example), the GC system has a "GC.KeepAlive()" method for this very purpose. It doesn't actually do anything, but it interrupts optimizations the compiler might make that would otherwise allow an object to be collected (it would be used exactly as the proposed "[data self]" call would be). This is to allow for situations where the only reference to the object is in "unmanaged" code -- that is, it's been passed across the interface from .NET to the older non-GC'ed Windows API.

In .NET, a situation more like the one we're talking about here is less common -- unmanaged objects are (almost?) never passed to managed code without also passing responsibility for maintenance of that unmanaged object to the recipient -- but inasmuch as they might come up as well, using GC.KeepAlive() would also be required. (Every single place I've come into contact with where an unmanaged object is passed back to managed code from a managed object, the recipient is required to free the object when they are done with it. I suppose there might be an exception to that rule, but if there is, it's a very rare case).

I'm less familiar with how Java's memory management works, but given that it also has interfaces between the Java run-time and the host environment, I suspect it also has the same sort of potential issue. This is going to come up any time GC and non-GC are mixed; either a GC object will be held outside of the visibility of the GC system, or some non-GC object will be dependent on a GC object. In either case, the programmer will have to be aware of this possibility and deal with it.

Not only is it not a bug for the compiler to not concern itself with the issue, the fact is that the extant example here is just the tip of the iceberg. While you might argue that the compiler _could_ prevent this particular problem, a) it requires the compiler to get into the business of memory management, and b) there will still be lots of other scenarios that are similar, but not solvable by the compiler.

It *does* do this. The error is not in the GC, but rather in the
assumption that "declared in the current scope" is equivalent to "is
on the stack frame"

Again, I see that as an implementation detail. From the documentation:

"The root set is comprised of all objects reachable from root objects
and all possible references found by examining the call stacks of
every Cocoa thread."

Given that the programmer cannot possibly know the state of the call
stack any other way than by considering normal variable scoping rules,
either it's meaningless to consider any variable on the stack as a
root object, or the compiler needs to guarantee equivalence between
them.

No. As Mike points out, this is only a problem because the object is returning a pointer that the object itself can make invalid due to garbage collection, even while that pointer isn't itself subject to the GC rules. This is a design problem, not a compiler error.

There are a variety of solutions, none of them spectacular. It would be much better for all GC objects to themselves own only GC objects, and/or to never return a non-GC pointer that it might later make invalid (in other words, if it does pass back a non-GC object, management of that object should be handed off to the recipient). But inasmuch as this cannot be guaranteed 100%, there will always be a need for the programmer to be aware that GC-able objects are only guaranteed to live up to the very last point they are used.

And it seems to me that with GC being a relatively new addition to Obj-C, that the likelihood of running into such situations is going to be greater than in a more-evolved environment. It's just something that needs to be kept in mind, just as in the older retain/ release paradigm there were a number of rules that needed to be kept in mind. IMHO, inasmuch as the need to keep this particular issue in mind comes up less frequently than the retain/release rules needed to, the GC system is more accommodating (though I suppose it also means it's harder to get used to keeping the rule in mind :) ).

Pete
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to