[pypy-dev] Non dynalloc framework roots

Ben.Young at risk.sungard.com Ben.Young at risk.sungard.com
Mon Sep 4 12:59:48 CEST 2006


Hi PyPyr's

This is mainly for Carl or Michael as it concerns the framework gc, but I 
was just interested how easy it would be to track the roots without doing 
any dynamic memory allocation. I came up with the following code, which I 
am interested to see  how easily it could be translated to llpython or 
whatever the lowest level is called. 

If someone can give me some hints, I may even have a go at implementing it 
myself!

Cheers,
Ben

#include "assert.h"

// Code

typedef struct _GCFuncNode
{
    int count;
    void*** pointers;
    struct _GCFuncNode* prev;
} GCFuncNode;

GCFuncNode* GC_top_node;

void GC_push_func_node(GCFuncNode* node, int count, void*** pointers)
{
    GCFuncNode* old_top;

    node->count = count;
    node->pointers = pointers;
    old_top = GC_top_node;
    GC_top_node = node;
    node->prev = old_top;
}

void GC_pop_func_node(void)
{
    GC_top_node = GC_top_node->prev;
}

typedef struct _GCRootItr
{
    GCFuncNode* cur_node;
    int cur_ptr;
} GCRootItr;

void GC_init_root_itr(GCRootItr* itr)
{
    itr->cur_node = GC_top_node;
    itr->cur_ptr = 0;
}

void** GC_itr_cur(GCRootItr* itr)
{
    if(itr->cur_node)
    {
        return itr->cur_node->pointers[itr->cur_ptr];
    }
    else 
    {
        return (void**)0;
    }
}

void GC_itr_next(GCRootItr* itr)
{ 
    assert(itr->cur_ptr < itr->cur_node->count);

    // Find next non-null pointer
    while(1)
    {
        itr->cur_ptr++;
        if(itr->cur_ptr == itr->cur_node->count) 
        {
            itr->cur_node = itr->cur_node->prev;
            itr->cur_ptr = 0;
            return;
        }

        if(*itr->cur_node->pointers[itr->cur_ptr] != (void*)0)
        {
            return;
        }
    }
}

// Example

typedef void* PyObjPtr;

void example_func_2(PyObjPtr a, PyObjPtr b, int x, int y);

void example_func_1(int x, int y)
{
    PyObjPtr a = 0, b = 0, c = 0;

    // GC code
    GCFuncNode node;
    void** GC_local_vars[] = {&a, &b, &c};
    GC_push_func_node(&node, sizeof(GC_local_vars)/sizeof(void*), 
GC_local_vars);
    // end GC code

    // Do stuff with a, b, c

    example_func_2(a, b, 3, y);

    // GC code
    GC_pop_func_node();
    // end GC code
}

void example_func_2(PyObjPtr a, PyObjPtr b, int x, int y)
{
    PyObjPtr i = 0, j = 0;

    // GC code
    GCFuncNode node;
    void** GC_local_vars[] = {&i, &j};
    GC_push_func_node(&node, sizeof(GC_local_vars)/sizeof(void*), 
GC_local_vars);
    // end GC code

    // GC code
    GC_pop_func_node();
    // end GC code
}


int main(int argc, char* argv[])
{
        return 0;
}




More information about the Pypy-dev mailing list