Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!samsung!uunet!lotus!lotus.com!robertk From: robertk@lotatg.lotus.com (Robert Krajewski) Newsgroups: comp.lang.c++ Subject: Re: reference counting vs. scanning GC Summary: Experience with Lisp Machine generational GCs... Keywords: locality, large address spaces, reference counting, garbage collection Message-ID: Date: 20 May 91 22:19:51 GMT References: <1991Apr24.192424.23745@kestrel.edu> <72149@microsoft.UUCP> <1991May11.054648.2483@kestrel.edu> <72384@microsoft.UUCP> Sender: news@lotus.com Organization: Lotus Development Corporation Lines: 60 In-Reply-To: jimad@microsoft.UUCP's message of 16 May 91 17:23:05 GMT In article <72384@microsoft.UUCP> jimad@microsoft.UUCP (Jim ADCOCK) writes: From: jimad@microsoft.UUCP (Jim ADCOCK) Newsgroups: comp.lang.c++ Some people claim the right thing to do is to let the end programmer specify where the object will be created, either by specifying how long the programmer guesses the object will live: FOO* pYoungFoo = new (SHORT_LIVED) foo(23); FOO* pOldFoo = new (LONG_LIVED) foo(123); or by specifying a neighborhood of objects that are all going to die at about the same time: FOO* pYoungFool = new (BELLEVUE) fool(34); FOO* pOldFool = new (SEATTLE) fool(92); FOO* pMiddleAgedFool = new (MERCER_ISLAND) fool(45); I think this is a cop-out... ... but even so, even one of the examples of ultimate Right Thing object storage implementations, the Lisp Machine, had a similar strategy for programmers that wanted to optimized locality. Lisp Machine storage was divided into areas -- there was a normally working storage area, but one could also direct allocation into other areas, either through explicit arguments in special versions of CONS or MAKE-ARRAY, or through binding a special implicit parameter to the allocator. The Lisp Machine compiler used areas in a particularly nasty way: after compilation was complete, the area was *reset*, that is, totally deallocated. That saved a lot of the work for the garbage collector, but modification of the compiler could be very dangerous if you left things outside pointing to the compiler area. After the generation-based GC was moved in, the compiler area was retained, but reset code was taken out. With this change, compilation time *sped up* because the generational GC had a chance to reclaim new objects before the compiler was finished; that storage was then freed up for other objects, and the machine did not have to page to get more unused pages. In general, with the ephemeral GC in place, areas were much less important than before. However, they still provide some information about locality, so there is a place for them. The only way I cn see to do that is either to move objects around, implicitly moving left-behind holes too, or by building hardware with virtual memory paging hardware more in tune with the needs of OOP [how often do we make 4K-sized objects?] Well, it's been done, although it's more of a question of low-level software (object storage) conventions than anything else. There's very little about a Lisp Machine that makes it a *Lisp* machine per se. I don't think there is ever going to be a version of C++ that's going to allow similar object architectures to fly at full speed, since there are some many programs that manipulate addresses in a non-object-oriented fashion. What is more reachable is getting enough reasonable features and latitude in spec so that, if one wanted to, one could write code in a clean dialect of C++ that would not be hostile to a true object architecture.