Topic: Of vptrs and vtbls (was: Garbage collection: state of?)
Author: anatoli@my-dejanews.com
Date: 1999/01/25 Raw View
I find it appropriate to start a new thread here, because (a) the old
thread seems to be getting nowhere, and (b) I tried once, long before the
C++ standard was accepted, to formulate much the same thing.
Below is what I have found, in straight terms, with pictures.
A typical heap manager operates as follows. When asked to allocate a
block of size N, it allocates a block of size N+K, K being a constant.
The heap manager then fills the first K units (bytes) of the block with
an info that will help to deallocate the block later. The address returned
is that of the allocated block plus K. Thus, a (conforming) client program
does not have access to the block header.
|<----- K --------->|<----------- N ----------------->|
+-------------------+---------------------------------+
+ heap manager info + block returned to the program +
+-------------------+---------------------------------+
^
|
+--------- this address is returned
The info that the heap manager places at the block header can be an integer
that indicates the block size. Or it can be a pointer to a function that
deallocates the block (blocks of different sizes will have different
deallocators of course). Or it can be a pointer to some table, which
may contain some pointers to functions and some other data, such as the block
size, at predefined places.
+- K = sizeof (MachinePointerType)
|
v
|< --- >|< -------------- N ------------->|
+-------+---------------------------------+
+ ptr* + block returned to the program +
+-----|-+---------------------------------+
| ^
| |
| +--------- this address is returned
|
v
+------------+
| block size | = N + K
+------------+
| other |
+------------+
| info |
+------------+
The latter case looks very much like the vptr/vtbl pair. A typical C++
implementation has vptrs/vtbls exactly like those. Not all classes have
vptrs, but some do. For those classes that do have a vptr, the question
is: can we merge the heap manager's block header with the vptr?
Let me repeat: the question is *not* whether a conforming C++
implementation can place vptrs in PODs. It sure cannot. But we
don't need to. We are talking about *memory blocks in the heap*,
and the question is whether a vptr (if a class does have one)
can take place of the block header.
Obviously (?) the answer is positive *if* we can have vptr at a *negative*
offset from the object address. Thus, our main question becomes: can
a conforming C++ implementation place vptrs at a negative offset from
the object address?
+- K = sizeof (MachinePointerType)
|
v
|< --- >|< ------- N = sizeof (T) - K --->|
+-------+---------------------------------+
+ vptr* + object data +
+-----|-+---------------------------------+
| ^
| |
| +--------- the address of the object
|
v
+------------+
| sizeof (T) | = N + K
+------------+
| other |
+------------+
| info |
+------------+
| pfunc1 |
+------------+
| pfunc2 |
+------------+
To this time I did not find any indication that it cannot.
I did not follow the original thread *very* closely, so I could
have missed the definitive answer. Also, even if the answer is yes, there
are probably some pathological examples that rule out such implementation.
Standard Gurus: what have I missed?
--
Regards
Anatoli (anatoli at ptc dot com) opinions aren't
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Jeff Greif" <jmg@spam-me-not.trivida.com>
Date: 1999/01/25 Raw View
You only need one heap manager pointer for an array of X (possibly used in
an STL container), but you need one vptr for each of the X's in the array.
Also, if you have only a single X object, and it is not heap allocated how
do you indicate that the vptr is naked (negatively offset from the object)
and not part of a heap manager info block. All of this is presumably
possible, but seems tricky to implement efficiently.
Jeff
anatoli@my-dejanews.com wrote in message
<78hact$6j0$1@nnrp1.dejanews.com>...
>...
>Thus, our main question becomes: can
>a conforming C++ implementation place vptrs at a negative offset from
>the object address?
>...
>We are talking about *memory blocks in the heap*,
>and the question is whether a vptr (if a class does have one)
>can take place of the block header.
>...
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: michael.finney@acm.org (Michael Lee Finney)
Date: 1999/01/25 Raw View
In article <1C1r2.1322$e32.109576326@dca1-nnrp1.news.digex.net>, jmg@spam-
me-not.trivida.com says...
> You only need one heap manager pointer for an array of X (possibly used in
> an STL container), but you need one vptr for each of the X's in the array.
> Also, if you have only a single X object, and it is not heap allocated how
> do you indicate that the vptr is naked (negatively offset from the object)
> and not part of a heap manager info block. All of this is presumably
> possible, but seems tricky to implement efficiently.
> Jeff
> anatoli@my-dejanews.com wrote in message
> <78hact$6j0$1@nnrp1.dejanews.com>...
> >...
> >Thus, our main question becomes: can
> >a conforming C++ implementation place vptrs at a negative offset from
> >the object address?
> >...
> >We are talking about *memory blocks in the heap*,
> >and the question is whether a vptr (if a class does have one)
> >can take place of the block header.
If X is a POD, then you only need one vptr as you say and sizeof(POD) does
not include the vptr. There may be additional information in the header
block which indicates the number of elements in an array of PODs. However,
for a virtual object (vobj), every object in the array has its own vptr and
sizeof(vobj) does include the vptr. Adding that offset to the pointer will
take you to the same relative location in the next vobj. Since these are
vptrs, they may occur both as a result of memory allocation and as a result
of normal object construction. The presence of a vptr does not imply that
the following object was dynamically allocated. The memory manager can
determine that by looking at ranges of allocated objects -- a table which it
presumably must maintain in any case. If we are talking about a garbage
collector instead of a memory manager there may be some additional problems
mentioned in the "Garbage Collection, State of ?" thread. However, for
simple memory management this is all there is, there are no other problems
that I can see at all because everything works exactly as it does now except
for how the memory manager interprets the data in the header block.
--
Michael Lee Finney
michael.finney@acm.org
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]