[Gc] gc_typed.h

Brian Buchanan brian at ncircle.com
Thu May 11 13:20:11 PDT 2006


On Thu, 11 May 2006, Boehm, Hans wrote:

> It is current, minimally tested by gctest, but I believe infrequently
> used.  I don't recall any documentation beyond the somewhat cryptic
> comments in the header file.  There is some small performance cost to
> supporting it, so it wouldn't have stayed there if I felt it was
> useless.

Hans, Travis,

We use typed alloacation in production without any issues.  The only 
problems we've had have been when we modified the typed structure 
definition without also modifying the code that set up the type bitmask, 
resulting in objects getting prematurely collected.  We solved that 
problem by sticking a giant, impossible-to-miss comment before the 
structure definition warning anyone modifying the code that they needed to 
also modify the bitmask.

I wrote some macros and other scaffolding for setting up the GC_descr 
structures and making sure they get initialized at runtime:

(This code assumes you have BSD's linked list macros available, usually by 
importing sys/queue.h.  If you're not on BSD, substitute your own linked 
list implementation.)

#include "gc_typed.h"
#define GC_TYPE(__typename) __gcTypeDesc_ ## __typename
#define TYPEDMALLOC(__type) \
   GC_MALLOC_EXPLICITLY_TYPED(sizeof(__type), GC_TYPE(__type))

typedef GC_descr (*GCTypeDescConstructor)(void);
struct GCTypeDesc {
   GCTypeDescConstructor makeDesc;
   GC_descr *desc;
   SLIST_ENTRY(GCTypeDesc) link;
};
typedef struct GCTypeDesc GCTypeDesc;
typedef SLIST_HEAD(,GCTypeDesc) GCTypeDescList;
extern GCTypeDescList GCTypeDescriptors;

#define DECLARE_GC_TYPE(__typename) \
   static GC_descr GC_TYPE(__typename); \
   static GC_descr __gcTypeDesc_ ## __typename ## _make(void); \
   static GCTypeDesc __gcTypeDescStruct_ ## __typename = { \
     .makeDesc = __gcTypeDesc_ ## __typename ## _make, \
     .desc = &GC_TYPE(__typename) \
   }; \
   static void __gcTypeDesc_ ## __typename ## _declare(void) \
   __attribute__((constructor)); \
   static void __gcTypeDesc_ ## __typename ## _declare(void) \
   { \
     SLIST_INSERT_HEAD(&GCTypeDescriptors, &__gcTypeDescStruct_ ## 
__typename, li
nk); \
   } \
   static GC_descr __gcTypeDesc_ ## __typename ## _make(void)

At startup time, a function runs that iterates over the GCTypeDescriptors 
list and calls "makeDesc" on each entry.

Say we had the following structure:

struct server {
   char   IPv4Address[16];
   char  *username;
   char  *password;
   time_t lastConnectTime;
};
typedef struct server server;

The structure has two "pointerful" members and two "atomic" members.
We'd declare its type like this:

DECLARE_GC_TYPE(server) {
   GC_word server_bitmap[GC_BITMAP_SIZE(server)];

   bzero(server_bitmap, sizeof(server_bitmap));
   GC_set_bit(server_bitmap, GC_WORD_OFFSET(server, username));
   GC_set_bit(server_bitmap, GC_WORD_OFFSET(server, password));

   return GC_make_descriptor(server_bitmap, GC_WORD_LEN(server));
}

Hope you find this useful.  We used it successfully to deal with some 
false pointer issues originating from a few structures that had embedded 
char array text fields.  We're using -DUSE_MMAP, which has the effect of 
giving us heap addresses that can look a lot like ASCII (once we're past 
0x20202020), so we've found it very important to keep our pointerful and 
pointerfree data separate.

Regards,

Brian

-- 
Brian Buchanan <brian at ncircle.com>
Principal Engineer
nCircle Network Security                             http://www.ncircle.com/


More information about the Gc mailing list