Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!cs.utexas.edu!sun-barr!newstop!exodus!rbbb.Eng.Sun.COM!chased From: chased@rbbb.Eng.Sun.COM (David Chase) Newsgroups: comp.lang.c++ Subject: Re: Smart Pointers -- A proposed language extension Keywords: smart pointers, garbage collection Message-ID: <6253@exodus.Eng.Sun.COM> Date: 18 Jan 91 19:34:19 GMT References: <1990Dec28.203554.21028@clear.com> <1991Jan6.072110.27136@cpsc.ucalgary.ca> <1991Jan16.224703.7647@xanadu.com> <1991Jan18.014050.27108@cpsc.ucalgary.ca> Sender: news@exodus.Eng.Sun.COM Organization: Sun Microsystems, Mt. View, Ca. Lines: 83 In article <1991Jan18.014050.27108@cpsc.ucalgary.ca> gintera@fsd.cpsc.ucalgary.ca (Andrew Ginter) writes: >I'm not sure what Chase's example of how optimizers generate >unregistered temporary pointers was supposed to show. His example is >a problem for a parallel garbage collector, yes. But serial and >incremental collectors would have no problems with his example since >his function does nothing that could trigger a garbage collection. If you re-examine Chase's example, you'll notice that it calls a function "f" in the middle of that loop. I thought it was clear what "f" might do. >I also disagree with Chase's assertion that "volatile" solves the >problem. ... [volatile] is good enough for memory >mapped registers and may be good enough for some smart pointer >applications, but it's not good enough for a compacting collector. I guess I wasn't clear. With existing compilation technology, it's not clear that you can get a fully compacting collector (relocating ALL the pointers) for C++, period. Edelson does this by registering all the pointers (creates aliases, too) and assuming single-threadedness. As soon as you have more than one thread sharing an address space (preemptively scheduled, just for entertainment), all bets on nailing all the references are off because one thread may get suspended in the middle of an addressing calculation. Since I ported a collector to Mach about a year ago, I regard this as a distinct possibility. Even without this, there's always Your Friend the signal handler. Bartlett combines compacting collection with conservative collection by not relocating objects referenced by "ambiguous" pointers. It's a neat trick, and I think it is a necessary one. Still, it needs at least one pointer to the base of an object, and that's what volatile solves for you, more or less (other people have pointed out that volatile is underspecified and slow -- what's not clear is whether it is significantly slower than any registration scheme that relies on aliasing to thwart the optimizer. Think about it.) I also think single-threaded programs will soon (within a few years) be regarded as a special case (on Unix, at least). It is certainly true that a garbage collector is more useful in a multi-threaded environment, because manual storage management is harder there. To me, fancy schemes for single-threaded garbage collection are interesting, but not useful in the long run. Not useful in the long run means that portability is less of an issue. (An aside -- what does it mean to be "portable" in a language that mutates every six months? Ack -- stifle that -- I must not think bad thoughts.) >Chase's claim that registration methods that work today may fail >tomorrow is also wrong. All of today's smart pointer registration >methods alias the smart pointer being registered. If the pointer is a >temporary, this aliasing means it must be allocated in memory. (All? You're certain of that? My intent was to warn anyone reading away from making the usual brain-dead assumptions about what the compiler "surely" must do in compiling code. "I'll do this -- it's faster, and it works for me, so it must be ok." You must have come across at least one person who prorgammed in that style.) Unless it says so in the standard, you cannot rely on this in general. Whole-program optimizers (e.g., Convex's) have the opportunity of caching "aliased" variables in registers when they cannot be modified. (So do less ambitious optimizers, but they have fewer opportunities for figuring this out.) The alias created MUST be to a variable that can eventually be reached by the garbage collector by standard-conforming code (and in fact, I all of the registration schemes I've seen do satisfy this constraint), and thus the optimizer will conclude (correctly) that the variable could change whenever the collector might be called. Again, this is heavyweight, and fails for multi-threaded programs (unless you say volatile). I think a better answer would be to blow off this goal of portability in standard C++, and instead get some compiler support or use a language that already supports garbage collection. IF you get garbage collection, it's a different language, anyway. Compiler support for garbage collection is a massive win as far as efficiency goes, and you don't have to screw around (as Edelson did) with different types for references from different locations (Local_Type, Global_Type, Heap_Type). It works, but it is tedious. David Chase Sun Microsystems