chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-users] question about garbage collector


From: John Lenz
Subject: [Chicken-users] question about garbage collector
Date: Tue, 14 Dec 2004 07:34:14 +0000

For the reworking of the swig runtime I am currently working on, we need to 
provide two functions
swig_module_info *SWIG_Chicken_GetModule()
void SWIG_Chicken_SetModule(swig_module_info *mod)
The mod variable should be stored in a global variable that multiple loaded 
swig libraries can access.  Right now I am using the following...
Note, SWIG_TYPE_TABLE_NAME is a define that gets set by the -D command when
compiling the file, so we can't assume anything about its length.

static C_word SWIG_Chicken_LookupSymbol(char *name, C_SYMBOL_TABLE *stable) {
  C_word *a = C_alloc(C_SIZEOF_STRING (strlen (name)));
  C_word n = C_string2(&a, name);
  C_word sym = C_find_symbol(n, stable);
  if (C_truep(sym)) {
    return C_symbol_value(sym);
  } else {
    return C_SCHEME_FALSE;
  }
}

static char *chicken_runtimevar_name = "type_pointer" SWIG_TYPE_TABLE_NAME;

static swig_module_info *
SWIG_Chicken_GetModule() {
    swig_module_info *ret = 0;
    C_word sym;

    /* lookup the type pointer... it is stored in it's own symbol table */
    C_SYMBOL_TABLE *stable = C_find_symbol_table("swig_runtime_data" 
SWIG_RUNTIME_VERSION);
    if (stable != NULL) {
      sym = SWIG_Chicken_LookupSymbol(chicken_runtimevar_name, stable);
      if (C_truep(sym) && C_swig_is_ptr(sym)) {
        ret = (swig_module_info *) C_block_item(sym, 0);
      }
    }

    return ret;
}

static void
SWIG_Chicken_SetModule(swig_module_info *module) {
    C_word *a;
    C_SYMBOL_TABLE *stable;
    C_word sym;
    C_word pointer;
    static C_word *space = 0;
    
    /* type pointer is stored in it's own symbol table */
    stable = C_find_symbol_table("swig_runtime_data" SWIG_RUNTIME_VERSION);
    if (stable == NULL) {
      stable = C_new_symbol_table("swig_runtime_data" SWIG_RUNTIME_VERSION, 16);
    }

    if (!space) {
      space = (C_word *) C_malloc((C_SIZEOF_POINTER + 
C_SIZEOF_INTERNED_SYMBOL(C_strlen(chicken_runtimevar_name))) * sizeof(C_word));
    }
    a = space;
    pointer = C_mpointer(&a, (void *) module);
    sym = C_intern_in(&a, C_strlen(chicken_runtimevar_name), 
chicken_runtimevar_name, stable);
    C_set_block_item(sym, 0, pointer);

    /*
    if (!C_demand( C_SIZEOF_POINTER + 
C_SIZEOF_INTERNED_SYMBOL(C_strlen(chicken_runtimevar_name))))
      C_rereclaim((C_SIZEOF_POINTER + 
C_SIZEOF_INTERNED_SYMBOL(C_strlen(chicken_runtimevar_name))) * sizeof(C_word));
    sym = C_intern_in(C_heaptop, C_strlen(chicken_runtimevar_name), 
chicken_runtimevar_name, stable);
    C_set_block_item(sym, 0, C_mpointer(C_heaptop, (void *) module));*/
}

What I am doing here is creating a new symbol table, and then loading into it 
the type_pointer.
I create a memory region with C_malloc.  That memory is never freed, but 
instead it is reused.
These two functions are the only ones to access this pointer, so reusing memory 
should not be a
problem.  I first use space for the pointer, and the way C_intern_in works it 
does not allocate
data from a when the symbol is already found, so the memory from the initial 
call in space will
not be touched.
I can't use C_alloc since this function returns control back to some other 
function.

1) Does this interact correctly with the garbage collector?  Since the 
variables stored in
space do not have sub-objects, we don't need to recursivly call mark on 
anything.  Second,
the memory will not be collected because the pointer will exist thoughout the 
life of the program.
This is only around 50 bytes or so, and will only be one of these per module,
so it isn't really a problem.

2) Would it be better to use the code commented out there at the end, and use 
C_heaptop instead
of allocating data with C_malloc?    My concern with using C_heaptop is actually
the code there in C_demand and C_rereclaim.  What happens is that the swig_init 
function looks
something like this

void SWIG_init(int argc, C_word closure, C_word continuation) {
  // call SWIG_InitializeModule(), which calls SWIG_Chicken_GetModule and 
SWIG_Chicken_SetModule
  //other init stuff
  C_kontinue(continuation, ret);
}

Thus if during the call to SWIG_Chicken_SetModule, C_rereclaim is called, would 
the flow of
control correctly resume?  That is,  C_rereclaim returns with more space 
available, and
SWIG_Chicken_SetModule returns and then SWIG_init can continue running and call 
C_kontinue
correctly.  I question this because C_rereclaim is doing funny things with the 
stack, and it
needs to know to save all the way from SWIG_init down to SWIG_Chicken_SetModule 
because we
will return that far up the stack before C_kontinue ing back down the stack.

John






reply via email to

[Prev in Thread] Current Thread [Next in Thread]