From: bcannard@hppcb36.mentorg.com (Bob Cannard @ PCB x5565)
Subject: Re: Garbage Collection for C++
Originator: bcannard@hppcb36
Date: Tue, 18 Aug 1992 02:14:53 GMT
Organization: Mentor Graphics 
Keywords: 
Followup-To: 


In article <TMB.92Aug16164940@arolla.idiap.ch>, tmb@arolla.idiap.ch (Thomas M. Breuel) writes:
|> In article <1992Aug15.025613.4571@news.mentorg.com> bcannard@hppcb36.mentorg.com (Bob Cannard @ PCB x5565) writes:
|> 
|> OK, let's go through this again. You propose that there be "non-GC
|> pointers" in C++. I don't see how this helps speed.
|> 
|>  (1) The memory pointed to by non-GC pointers still needs to
|>      be examined by the garbage collector.

No. The GC scans the various non-GC heaps to find (allocated) objects that
contain GC pointers. It does not have to determine whether or not those objects
are accessible; the fact that an object has been allocated but not deleted is
sufficient. Suppose such an object contains 6 pointers. In your conservative
scheme, those 6 pointers must then be checked because they might refer
to GC objects. If those pointers are declared non-GC, the GC doesn't even
have to think about them; it can go straight on to the next memory block.
Depending on the proportion of GC to non-GC, this could be a major saving.

This requires run-time type information at the start of each memory block. I
can't see a way around that at the moment: this may prove a fatal flaw in the
declared-GC scheme.

|>  (2) With a conservative GC, there is no tagging/untagging cost
|>      associated with GC pointers; GC pointers are just as efficient
|>      and simple as non-GC pointers.

Agreed.

|>  (3) Even in a system with (conservative) GC, you can still return
|>      memory to the system using some form of unsafe "free" or "delete"
|>      (e.g., as provided by Boehm's collector).

Agreed, but there has to be some point in doing so. I see two possible reasons
for having an explicit delete:

1. To take advantage of any performance improvement. Regardless of who's
   right in this debate, I doubt that there is any benefit for GC objects.

2. To invoke destructors at a specific point in time. This makes a lot more
   sense, even if the "delete" doesn't actually free the memory. This
   may prove important.

Any others?

|>  (4) Why ever would you _not_ want to call a GC if you run out
|>      of "non-GC memory"? The alternative is a program crash.
|> 
|> It seems to me that the facilities you really want are: (a) an "free"
|> function (which would be just as unsafe as it is now),

Hmm, not exactly. I can clearly and accurately specify the lifetimes of some
of my data structures, whereas others are more open. Delete is used with a high
degree of safety on the former; GC is needed for the latter.

|> and (b) a
|> version of the "new" operator that says "this memory block doesn't
|> contain any pointers". Not surprisingly, these functions are offered
|> by conservative GC's for C/C++.

Better to let the compiler make the choice. If GC pointers are declared, the
compiler can extend it to "this memory block doesn't contain any pointers
significant to the GC".

|> Beyond these two facilities, I simply fail to see the need to divide
|> memory or pointers "garbage collected" and "not garbage collected" on
|> the basis of efficiency.

Because efficiency is a major issue, and the declaration could make a very
large difference. Simple as that. If there is a way of
doing GC that is comparable to the best manual - given all the other pain
in C++ - I will accept you argument, but it should prove hard to convince
the larger C++ community.

[snip]
|> ... the same tricks you play in
|> C/C++ for memory management right now can also be applied in a GC'd
|> context so GC is at least not inherently slower than manual storage
|> management.

How do you get the GC to figure out _at_compile_time_ that certain pieces
of memory become available at certain points in the program? That's the
big win for manual.

|> Now, it turns out that in some cases, GC is actually "guaranteed" to
|> be faster, in the sense that it can combine very low-cost allocation
|> with no overhead deallocation (that is, 0 machine cycles per word).

And in some cases manual allocation can do the same thing, if the programmer
is prepared to take control of the memory allocation (some of my more critical
data structures do exactly that). A GC system is still stuck with figuring out
which memory areas are available for recycling - an overhead performed at
compile time for manual.

The point remains: every optimisation that can be done for manual can also be
done for GC, and vice-versa. _Except_ making a compile-time decision of when to
delete memory. Maybe there are cases where a well-designed GC, fully integrated
with the rest of the system, could do that, too. And I wouldn't be surprised
to find that a simple conservative system works better than the current
new and delete...

(I'm only arguing this point because it's important to whether or not
GC pointers should be declared.)

Cheers,

      Bob.

-- 
bob_cannard@mentorg.com         "Human beings? ... Well, I suppose they are a
                                 form of life, even if they are unspeakable"
Exprssed opinions are not necessarily those of Mentor Graphics Corporation.
Newsgroups: comp.lang.c++