Changeset 39

Show
Ignore:
Timestamp:
10/28/08 20:15:37 (4 years ago)
Author:
sean
Message:

Added static data segment support to the new Runtime.loadLibrary() features. This also replaces static data segment scanning for all apps by dropping rt_scanStaticData() in favor of a new initialization step that calls gc_addRange() for each static data segment. The upshot of this is that all GCs must track add/remove Root and Range calls so the info can be passed to a proxy if gc_setProxy() is called. See src/gc/stub/gc.d for a simple implementation of this.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/D1.0/src/gc/basic/gc.d

    r38 r39  
    2727module gc.gc; 
    2828 
    29 private import gcx; 
    30 private import gcstats; 
    31 private import core.stdc.stdlib; 
    32  
    33 version=GCCLASS; 
    34  
    35 version (GCCLASS) 
    36     alias GC gc_t; 
    37 else 
    38     alias GC* gc_t; 
    39  
    40 gc_t _gc; 
    41  
    42 extern (C) void thread_init(); 
     29private 
     30
     31    import gcx; 
     32    import gcstats; 
     33    import core.stdc.stdlib; 
     34 
     35    version = GCCLASS; 
     36 
     37    version( GCCLASS ) 
     38        alias GC gc_t; 
     39    else 
     40        alias GC* gc_t; 
     41 
     42    gc_t _gc; 
     43 
     44    extern (C) void thread_init(); 
     45 
     46    struct Proxy 
     47    { 
     48        extern (C) void function() gc_enable; 
     49        extern (C) void function() gc_disable; 
     50        extern (C) void function() gc_collect; 
     51        extern (C) void function() gc_minimize; 
     52 
     53        extern (C) uint function(void*) gc_getAttr; 
     54        extern (C) uint function(void*, uint) gc_setAttr; 
     55        extern (C) uint function(void*, uint) gc_clrAttr; 
     56 
     57        extern (C) void*  function(size_t, uint) gc_malloc; 
     58        extern (C) void*  function(size_t, uint) gc_calloc; 
     59        extern (C) void*  function(void*, size_t, uint ba) gc_realloc; 
     60        extern (C) size_t function(void*, size_t, size_t) gc_extend; 
     61        extern (C) size_t function(size_t) gc_reserve; 
     62        extern (C) void   function(void*) gc_free; 
     63 
     64        extern (C) void*   function(void*) gc_addrOf; 
     65        extern (C) size_t  function(void*) gc_sizeOf; 
     66 
     67        extern (C) BlkInfo function(void*) gc_query; 
     68 
     69        extern (C) void function(void*) gc_addRoot; 
     70        extern (C) void function(void*, size_t) gc_addRange; 
     71 
     72        extern (C) void function(void*) gc_removeRoot; 
     73        extern (C) void function(void*) gc_removeRange; 
     74    } 
     75 
     76    Proxy  pthis; 
     77    Proxy* proxy; 
     78 
     79    void initProxy() 
     80    { 
     81        pthis.gc_enable = &gc_enable; 
     82        pthis.gc_disable = &gc_disable; 
     83        pthis.gc_collect = &gc_collect; 
     84        pthis.gc_minimize = &gc_minimize; 
     85 
     86        pthis.gc_getAttr = &gc_getAttr; 
     87        pthis.gc_setAttr = &gc_setAttr; 
     88        pthis.gc_clrAttr = &gc_clrAttr; 
     89 
     90        pthis.gc_malloc = &gc_malloc; 
     91        pthis.gc_calloc = &gc_calloc; 
     92        pthis.gc_realloc = &gc_realloc; 
     93        pthis.gc_extend = &gc_extend; 
     94        pthis.gc_reserve = &gc_reserve; 
     95        pthis.gc_free = &gc_free; 
     96 
     97        pthis.gc_addrOf = &gc_addrOf; 
     98        pthis.gc_sizeOf = &gc_sizeOf; 
     99 
     100        pthis.gc_query = &gc_query; 
     101 
     102        pthis.gc_addRoot = &gc_addRoot; 
     103        pthis.gc_addRange = &gc_addRange; 
     104 
     105        pthis.gc_removeRoot = &gc_removeRoot; 
     106        pthis.gc_removeRange = &gc_removeRange; 
     107    } 
     108
    43109 
    44110extern (C) void gc_init() 
     
    60126    //       before its first collection. 
    61127    thread_init(); 
     128    initProxy(); 
    62129} 
    63130 
     
    235302} 
    236303 
    237 struct Proxy 
    238 { 
    239     extern (C) void function() gc_enable; 
    240     extern (C) void function() gc_disable; 
    241     extern (C) void function() gc_collect; 
    242     extern (C) void function() gc_minimize; 
    243  
    244     extern (C) uint function(void*) gc_getAttr; 
    245     extern (C) uint function(void*, uint) gc_setAttr; 
    246     extern (C) uint function(void*, uint) gc_clrAttr; 
    247  
    248     extern (C) void*  function(size_t, uint) gc_malloc; 
    249     extern (C) void*  function(size_t, uint) gc_calloc; 
    250     extern (C) void*  function(void*, size_t, uint ba) gc_realloc; 
    251     extern (C) size_t function(void*, size_t, size_t) gc_extend; 
    252     extern (C) size_t function(size_t) gc_reserve; 
    253     extern (C) void   function(void*) gc_free; 
    254  
    255     extern (C) void*   function(void*) gc_addrOf; 
    256     extern (C) size_t  function(void*) gc_sizeOf; 
    257  
    258     extern (C) BlkInfo function(void*) gc_query; 
    259  
    260     extern (C) void function(void*) gc_addRoot; 
    261     extern (C) void function(void*, size_t) gc_addRange; 
    262  
    263     extern (C) void function(void*) gc_removeRoot; 
    264     extern (C) void function(void*) gc_removeRange; 
    265 } 
    266  
    267 Proxy  pthis; 
    268 Proxy* proxy; 
    269  
    270 static this() 
    271 { 
    272     pthis.gc_enable = &gc_enable; 
    273     pthis.gc_disable = &gc_disable; 
    274     pthis.gc_collect = &gc_collect; 
    275     pthis.gc_minimize = &gc_minimize; 
    276  
    277     pthis.gc_getAttr = &gc_getAttr; 
    278     pthis.gc_setAttr = &gc_setAttr; 
    279     pthis.gc_clrAttr = &gc_clrAttr; 
    280  
    281     pthis.gc_malloc = &gc_malloc; 
    282     pthis.gc_calloc = &gc_calloc; 
    283     pthis.gc_realloc = &gc_realloc; 
    284     pthis.gc_extend = &gc_extend; 
    285     pthis.gc_reserve = &gc_reserve; 
    286     pthis.gc_free = &gc_free; 
    287  
    288     pthis.gc_addrOf = &gc_addrOf; 
    289     pthis.gc_sizeOf = &gc_sizeOf; 
    290  
    291     pthis.gc_query = &gc_query; 
    292  
    293     pthis.gc_addRoot = &gc_addRoot; 
    294     pthis.gc_addRange = &gc_addRange; 
    295  
    296     pthis.gc_removeRoot = &gc_removeRoot; 
    297     pthis.gc_removeRange = &gc_removeRange; 
    298 } 
    299  
    300304extern (C) Proxy* gc_getProxy() 
    301305{ 
    302306    return &pthis; 
    303307} 
    304  
     308import core.stdc.stdio; 
    305309export extern (C) void gc_setProxy( Proxy* p ) 
    306310{ 
     
    310314    } 
    311315    proxy = p; 
    312     // TODO: Add known ranges and roots to the proxy. 
     316    foreach( r; _gc.rootIter ) 
     317        proxy.gc_addRoot( r ); 
     318    foreach( r; _gc.rangeIter ) 
     319        proxy.gc_addRange( r.pbot, r.ptop - r.pbot ); 
    313320} 
    314321 
    315322export extern (C) void gc_clrProxy() 
    316323{ 
    317     // TODO: Remove known ranges and roots from the proxy. 
     324    foreach( r; _gc.rangeIter ) 
     325        proxy.gc_removeRange( r.pbot ); 
     326    foreach( r; _gc.rootIter ) 
     327        proxy.gc_removeRoot( r ); 
    318328    proxy = null; 
    319329} 
  • branches/D1.0/src/gc/basic/gcx.d

    r38 r39  
    11671167 
    11681168    /** 
     1169     * 
     1170     */ 
     1171    int delegate(int delegate(inout void*)) rootIter() 
     1172    { 
     1173        if (!thread_needLock()) 
     1174        { 
     1175            return &gcx.rootIter; 
     1176        } 
     1177        else synchronized (gcLock) 
     1178        { 
     1179            return &gcx.rootIter; 
     1180        } 
     1181    } 
     1182    /** 
    11691183     * add range to scan for roots 
    11701184     */ 
     
    12101224 
    12111225 
     1226    /** 
     1227     * 
     1228     */ 
     1229    int delegate(int delegate(inout Range)) rangeIter() 
     1230    { 
     1231        if (!thread_needLock()) 
     1232        { 
     1233            return &gcx.rangeIter; 
     1234        } 
     1235        else synchronized (gcLock) 
     1236        { 
     1237            return &gcx.rangeIter; 
     1238        } 
     1239    } 
    12121240    /** 
    12131241     * do full garbage collection 
     
    15761604     * 
    15771605     */ 
     1606    int rootIter(int delegate(inout void*) dg) 
     1607    { 
     1608        int result = 0; 
     1609        for( size_t i = 0; i < nroots; ++i ) 
     1610        { 
     1611            result = dg(roots[i]); 
     1612            if (result) 
     1613                break; 
     1614        } 
     1615        return result; 
     1616    } 
     1617    /** 
     1618     * 
     1619     */ 
    15781620    void addRange(void *pbot, void *ptop) 
    15791621    { 
     
    16261668 
    16271669 
     1670    /** 
     1671     * 
     1672     */ 
     1673    int rangeIter(int delegate(inout Range) dg) 
     1674    { 
     1675        int result = 0; 
     1676        for( size_t i = 0; i < nranges; ++i ) 
     1677        { 
     1678            result = dg(ranges[i]); 
     1679            if (result) 
     1680                break; 
     1681        } 
     1682        return result; 
     1683    } 
    16281684    /** 
    16291685     * Find Pool that pointer is in. 
  • branches/D1.0/src/gc/stub/gc.d

    r38 r39  
    2121module gc.gc; 
    2222 
    23 private import core.stdc.stdlib; 
    24  
    2523private 
    2624{ 
     25   import core.stdc.stdlib; 
     26 
    2727   enum BlkAttr : uint 
    2828    { 
     
    4242    extern (C) void thread_init(); 
    4343    extern (C) void onOutOfMemoryError(); 
     44 
     45    struct Proxy 
     46    { 
     47        extern (C) void function() gc_enable; 
     48        extern (C) void function() gc_disable; 
     49        extern (C) void function() gc_collect; 
     50        extern (C) void function() gc_minimize; 
     51 
     52        extern (C) uint function(void*) gc_getAttr; 
     53        extern (C) uint function(void*, uint) gc_setAttr; 
     54        extern (C) uint function(void*, uint) gc_clrAttr; 
     55 
     56        extern (C) void*  function(size_t, uint) gc_malloc; 
     57        extern (C) void*  function(size_t, uint) gc_calloc; 
     58        extern (C) void*  function(void*, size_t, uint ba) gc_realloc; 
     59        extern (C) size_t function(void*, size_t, size_t) gc_extend; 
     60        extern (C) size_t function(size_t) gc_reserve; 
     61        extern (C) void   function(void*) gc_free; 
     62 
     63        extern (C) void*   function(void*) gc_addrOf; 
     64        extern (C) size_t  function(void*) gc_sizeOf; 
     65 
     66        extern (C) BlkInfo function(void*) gc_query; 
     67 
     68        extern (C) void function(void*) gc_addRoot; 
     69        extern (C) void function(void*, size_t) gc_addRange; 
     70 
     71        extern (C) void function(void*) gc_removeRoot; 
     72        extern (C) void function(void*) gc_removeRange; 
     73    } 
     74 
     75    Proxy  pthis; 
     76    Proxy* proxy; 
     77 
     78    void initProxy() 
     79    { 
     80        pthis.gc_enable = &gc_enable; 
     81        pthis.gc_disable = &gc_disable; 
     82        pthis.gc_collect = &gc_collect; 
     83        pthis.gc_minimize = &gc_minimize; 
     84 
     85        pthis.gc_getAttr = &gc_getAttr; 
     86        pthis.gc_setAttr = &gc_setAttr; 
     87        pthis.gc_clrAttr = &gc_clrAttr; 
     88 
     89        pthis.gc_malloc = &gc_malloc; 
     90        pthis.gc_calloc = &gc_calloc; 
     91        pthis.gc_realloc = &gc_realloc; 
     92        pthis.gc_extend = &gc_extend; 
     93        pthis.gc_reserve = &gc_reserve; 
     94        pthis.gc_free = &gc_free; 
     95 
     96        pthis.gc_addrOf = &gc_addrOf; 
     97        pthis.gc_sizeOf = &gc_sizeOf; 
     98 
     99        pthis.gc_query = &gc_query; 
     100 
     101        pthis.gc_addRoot = &gc_addRoot; 
     102        pthis.gc_addRange = &gc_addRange; 
     103 
     104        pthis.gc_removeRoot = &gc_removeRoot; 
     105        pthis.gc_removeRange = &gc_removeRange; 
     106    } 
     107 
     108    void** roots  = null; 
     109    size_t nroots = 0; 
     110 
     111    struct Range 
     112    { 
     113        void*  pos; 
     114        size_t len; 
     115    } 
     116 
     117    Range* ranges  = null; 
     118    size_t nranges = 0; 
    44119} 
    45120 
     
    49124    //       collection, and always before returning from gc_init(). 
    50125    thread_init(); 
     126    initProxy(); 
    51127} 
    52128 
    53129extern (C) void gc_term() 
    54130{ 
    55  
     131    free( roots ); 
     132    free( ranges ); 
    56133} 
    57134 
     
    186263} 
    187264 
    188 // TODO: Implement range storage. 
    189 // TODO: Implement root storage. 
    190  
    191265extern (C) void gc_addRoot( void* p ) 
    192266{ 
    193267    if( proxy is null ) 
    194         return; 
     268    { 
     269        void** r = cast(void**) realloc( roots, 
     270                                         (nroots+1) * roots[0].sizeof ); 
     271        if( r is null ) 
     272            onOutOfMemoryError(); 
     273        r[nroots++] = p; 
     274        roots = r; 
     275 
     276    } 
    195277    return proxy.gc_addRoot( p ); 
    196278} 
     
    199281{ 
    200282    if( proxy is null ) 
    201         return; 
     283    { 
     284        Range* r = cast(Range*) realloc( ranges, 
     285                                         (nranges+1) * ranges[0].sizeof ); 
     286        if( r is null ) 
     287            onOutOfMemoryError(); 
     288        r[nranges].pos = p; 
     289        r[nranges].len = sz; 
     290        ranges = r; 
     291        ++nranges; 
     292    } 
    202293    return proxy.gc_addRange( p, sz ); 
    203294} 
     
    206297{ 
    207298    if( proxy is null ) 
    208         return; 
     299    { 
     300        for( size_t i = 0; i < nroots; ++i ) 
     301        { 
     302            if( roots[i] is p ) 
     303            { 
     304                roots[i] = roots[--nroots]; 
     305                return; 
     306            } 
     307        } 
     308        assert( false ); 
     309    } 
    209310    return proxy.gc_removeRoot( p ); 
    210311} 
     
    213314{ 
    214315    if( proxy is null ) 
    215         return; 
     316    { 
     317        for( size_t i = 0; i < nranges; ++i ) 
     318        { 
     319            if( ranges[i].pos is p ) 
     320            { 
     321                ranges[i] = ranges[--nranges]; 
     322                return; 
     323            } 
     324        } 
     325        assert( false ); 
     326    } 
    216327    return proxy.gc_removeRange( p ); 
    217328} 
    218329 
    219 struct Proxy 
    220 { 
    221     extern (C) void function() gc_enable; 
    222     extern (C) void function() gc_disable; 
    223     extern (C) void function() gc_collect; 
    224     extern (C) void function() gc_minimize; 
    225  
    226     extern (C) uint function(void*) gc_getAttr; 
    227     extern (C) uint function(void*, uint) gc_setAttr; 
    228     extern (C) uint function(void*, uint) gc_clrAttr; 
    229  
    230     extern (C) void*  function(size_t, uint) gc_malloc; 
    231     extern (C) void*  function(size_t, uint) gc_calloc; 
    232     extern (C) void*  function(void*, size_t, uint ba) gc_realloc; 
    233     extern (C) size_t function(void*, size_t, size_t) gc_extend; 
    234     extern (C) size_t function(size_t) gc_reserve; 
    235     extern (C) void   function(void*) gc_free; 
    236  
    237     extern (C) void*   function(void*) gc_addrOf; 
    238     extern (C) size_t  function(void*) gc_sizeOf; 
    239  
    240     extern (C) BlkInfo function(void*) gc_query; 
    241  
    242     extern (C) void function(void*) gc_addRoot; 
    243     extern (C) void function(void*, size_t) gc_addRange; 
    244  
    245     extern (C) void function(void*) gc_removeRoot; 
    246     extern (C) void function(void*) gc_removeRange; 
    247 } 
    248  
    249 Proxy  pthis; 
    250 Proxy* proxy; 
    251  
    252 static this() 
    253 { 
    254     pthis.gc_enable = &gc_enable; 
    255     pthis.gc_disable = &gc_disable; 
    256     pthis.gc_collect = &gc_collect; 
    257     pthis.gc_minimize = &gc_minimize; 
    258  
    259     pthis.gc_getAttr = &gc_getAttr; 
    260     pthis.gc_setAttr = &gc_setAttr; 
    261     pthis.gc_clrAttr = &gc_clrAttr; 
    262  
    263     pthis.gc_malloc = &gc_malloc; 
    264     pthis.gc_calloc = &gc_calloc; 
    265     pthis.gc_realloc = &gc_realloc; 
    266     pthis.gc_extend = &gc_extend; 
    267     pthis.gc_reserve = &gc_reserve; 
    268     pthis.gc_free = &gc_free; 
    269  
    270     pthis.gc_addrOf = &gc_addrOf; 
    271     pthis.gc_sizeOf = &gc_sizeOf; 
    272  
    273     pthis.gc_query = &gc_query; 
    274  
    275     pthis.gc_addRoot = &gc_addRoot; 
    276     pthis.gc_addRange = &gc_addRange; 
    277  
    278     pthis.gc_removeRoot = &gc_removeRoot; 
    279     pthis.gc_removeRange = &gc_removeRange; 
    280 } 
    281  
    282330extern (C) Proxy* gc_getProxy() 
    283331{ 
     
    289337    if( proxy !is null ) 
    290338    { 
    291         // error? 
     339        // TODO: Decide if this is an error condition. 
    292340    } 
    293341    proxy = p; 
    294     ///foreach range 
    295     //proxy.addRange(); 
    296     //foreach root 
    297     //proxy.addRoot() 
     342    foreach( r; roots[0 .. nroots] ) 
     343        proxy.gc_addRoot( r ); 
     344    foreach( r; ranges[0 .. nranges] ) 
     345        proxy.gc_addRange( r.pos, r.len ); 
    298346} 
    299347 
    300348export extern (C) void gc_clrProxy() 
    301349{ 
    302     // foreach root 
    303     // proxy.removeRoot(); 
    304     // foreach range 
    305     // proxy.removeReange(); 
     350    foreach( r; ranges[0 .. nranges] ) 
     351        proxy.gc_removeRange( r.pos ); 
     352    foreach( r; roots[0 .. nroots] ) 
     353        proxy.gc_removeRoot( r ); 
    306354    proxy = null; 
    307355} 
  • trunk/src/gc/basic/gc.d

    r38 r39  
    2727module gc.gc; 
    2828 
    29 private import gcx; 
    30 private import gcstats; 
    31 private import core.stdc.stdlib; 
    32  
    33 version=GCCLASS; 
    34  
    35 version (GCCLASS) 
    36     alias GC gc_t; 
    37 else 
    38     alias GC* gc_t; 
    39  
    40 gc_t _gc; 
    41  
    42 extern (C) void thread_init(); 
     29private 
     30
     31    import gcx; 
     32    import gcstats; 
     33    import core.stdc.stdlib; 
     34 
     35    version = GCCLASS; 
     36 
     37    version( GCCLASS ) 
     38        alias GC gc_t; 
     39    else 
     40        alias GC* gc_t; 
     41 
     42    gc_t _gc; 
     43 
     44    extern (C) void thread_init(); 
     45 
     46    struct Proxy 
     47    { 
     48        extern (C) void function() gc_enable; 
     49        extern (C) void function() gc_disable; 
     50        extern (C) void function() gc_collect; 
     51        extern (C) void function() gc_minimize; 
     52 
     53        extern (C) uint function(void*) gc_getAttr; 
     54        extern (C) uint function(void*, uint) gc_setAttr; 
     55        extern (C) uint function(void*, uint) gc_clrAttr; 
     56 
     57        extern (C) void*  function(size_t, uint) gc_malloc; 
     58        extern (C) void*  function(size_t, uint) gc_calloc; 
     59        extern (C) void*  function(void*, size_t, uint ba) gc_realloc; 
     60        extern (C) size_t function(void*, size_t, size_t) gc_extend; 
     61        extern (C) size_t function(size_t) gc_reserve; 
     62        extern (C) void   function(void*) gc_free; 
     63 
     64        extern (C) void*   function(void*) gc_addrOf; 
     65        extern (C) size_t  function(void*) gc_sizeOf; 
     66 
     67        extern (C) BlkInfo function(void*) gc_query; 
     68 
     69        extern (C) void function(void*) gc_addRoot; 
     70        extern (C) void function(void*, size_t) gc_addRange; 
     71 
     72        extern (C) void function(void*) gc_removeRoot; 
     73        extern (C) void function(void*) gc_removeRange; 
     74    } 
     75 
     76    Proxy  pthis; 
     77    Proxy* proxy; 
     78 
     79    void initProxy() 
     80    { 
     81        pthis.gc_enable = &gc_enable; 
     82        pthis.gc_disable = &gc_disable; 
     83        pthis.gc_collect = &gc_collect; 
     84        pthis.gc_minimize = &gc_minimize; 
     85 
     86        pthis.gc_getAttr = &gc_getAttr; 
     87        pthis.gc_setAttr = &gc_setAttr; 
     88        pthis.gc_clrAttr = &gc_clrAttr; 
     89 
     90        pthis.gc_malloc = &gc_malloc; 
     91        pthis.gc_calloc = &gc_calloc; 
     92        pthis.gc_realloc = &gc_realloc; 
     93        pthis.gc_extend = &gc_extend; 
     94        pthis.gc_reserve = &gc_reserve; 
     95        pthis.gc_free = &gc_free; 
     96 
     97        pthis.gc_addrOf = &gc_addrOf; 
     98        pthis.gc_sizeOf = &gc_sizeOf; 
     99 
     100        pthis.gc_query = &gc_query; 
     101 
     102        pthis.gc_addRoot = &gc_addRoot; 
     103        pthis.gc_addRange = &gc_addRange; 
     104 
     105        pthis.gc_removeRoot = &gc_removeRoot; 
     106        pthis.gc_removeRange = &gc_removeRange; 
     107    } 
     108
    43109 
    44110extern (C) void gc_init() 
     
    60126    //       before its first collection. 
    61127    thread_init(); 
     128    initProxy(); 
    62129} 
    63130 
     
    235302} 
    236303 
    237 struct Proxy 
    238 { 
    239     extern (C) void function() gc_enable; 
    240     extern (C) void function() gc_disable; 
    241     extern (C) void function() gc_collect; 
    242     extern (C) void function() gc_minimize; 
    243  
    244     extern (C) uint function(void*) gc_getAttr; 
    245     extern (C) uint function(void*, uint) gc_setAttr; 
    246     extern (C) uint function(void*, uint) gc_clrAttr; 
    247  
    248     extern (C) void*  function(size_t, uint) gc_malloc; 
    249     extern (C) void*  function(size_t, uint) gc_calloc; 
    250     extern (C) void*  function(void*, size_t, uint ba) gc_realloc; 
    251     extern (C) size_t function(void*, size_t, size_t) gc_extend; 
    252     extern (C) size_t function(size_t) gc_reserve; 
    253     extern (C) void   function(void*) gc_free; 
    254  
    255     extern (C) void*   function(void*) gc_addrOf; 
    256     extern (C) size_t  function(void*) gc_sizeOf; 
    257  
    258     extern (C) BlkInfo function(void*) gc_query; 
    259  
    260     extern (C) void function(void*) gc_addRoot; 
    261     extern (C) void function(void*, size_t) gc_addRange; 
    262  
    263     extern (C) void function(void*) gc_removeRoot; 
    264     extern (C) void function(void*) gc_removeRange; 
    265 } 
    266  
    267 Proxy  pthis; 
    268 Proxy* proxy; 
    269  
    270 static this() 
    271 { 
    272     pthis.gc_enable = &gc_enable; 
    273     pthis.gc_disable = &gc_disable; 
    274     pthis.gc_collect = &gc_collect; 
    275     pthis.gc_minimize = &gc_minimize; 
    276  
    277     pthis.gc_getAttr = &gc_getAttr; 
    278     pthis.gc_setAttr = &gc_setAttr; 
    279     pthis.gc_clrAttr = &gc_clrAttr; 
    280  
    281     pthis.gc_malloc = &gc_malloc; 
    282     pthis.gc_calloc = &gc_calloc; 
    283     pthis.gc_realloc = &gc_realloc; 
    284     pthis.gc_extend = &gc_extend; 
    285     pthis.gc_reserve = &gc_reserve; 
    286     pthis.gc_free = &gc_free; 
    287  
    288     pthis.gc_addrOf = &gc_addrOf; 
    289     pthis.gc_sizeOf = &gc_sizeOf; 
    290  
    291     pthis.gc_query = &gc_query; 
    292  
    293     pthis.gc_addRoot = &gc_addRoot; 
    294     pthis.gc_addRange = &gc_addRange; 
    295  
    296     pthis.gc_removeRoot = &gc_removeRoot; 
    297     pthis.gc_removeRange = &gc_removeRange; 
    298 } 
    299  
    300304extern (C) Proxy* gc_getProxy() 
    301305{ 
    302306    return &pthis; 
    303307} 
    304  
     308import core.stdc.stdio; 
    305309export extern (C) void gc_setProxy( Proxy* p ) 
    306310{ 
     
    310314    } 
    311315    proxy = p; 
    312     // TODO: Add known ranges and roots to the proxy. 
     316    foreach( r; _gc.rootIter ) 
     317        proxy.gc_addRoot( r ); 
     318    foreach( r; _gc.rangeIter ) 
     319        proxy.gc_addRange( r.pbot, r.ptop - r.pbot ); 
    313320} 
    314321 
    315322export extern (C) void gc_clrProxy() 
    316323{ 
    317     // TODO: Remove known ranges and roots from the proxy. 
     324    foreach( r; _gc.rangeIter ) 
     325        proxy.gc_removeRange( r.pbot ); 
     326    foreach( r; _gc.rootIter ) 
     327        proxy.gc_removeRoot( r ); 
    318328    proxy = null; 
    319329} 
  • trunk/src/gc/basic/gcx.d

    r38 r39  
    11651165 
    11661166    /** 
     1167     * 
     1168     */ 
     1169    int delegate(int delegate(inout void*)) rootIter() 
     1170    { 
     1171        if (!thread_needLock()) 
     1172        { 
     1173            return &gcx.rootIter; 
     1174        } 
     1175        else synchronized (gcLock) 
     1176        { 
     1177            return &gcx.rootIter; 
     1178        } 
     1179    } 
     1180 
     1181 
     1182    /** 
    11671183     * add range to scan for roots 
    11681184     */ 
     
    12041220        { 
    12051221            gcx.removeRange(p); 
     1222        } 
     1223    } 
     1224 
     1225 
     1226    /** 
     1227     * 
     1228     */ 
     1229    int delegate(int delegate(inout Range)) rangeIter() 
     1230    { 
     1231        if (!thread_needLock()) 
     1232        { 
     1233            return &gcx.rangeIter; 
     1234        } 
     1235        else synchronized (gcLock) 
     1236        { 
     1237            return &gcx.rangeIter; 
    12061238        } 
    12071239    } 
     
    15741606     * 
    15751607     */ 
     1608    int rootIter(int delegate(inout void*) dg) 
     1609    { 
     1610        int result = 0; 
     1611        for( size_t i = 0; i < nroots; ++i ) 
     1612        { 
     1613            result = dg(roots[i]); 
     1614            if (result) 
     1615                break; 
     1616        } 
     1617        return result; 
     1618    } 
     1619 
     1620 
     1621    /** 
     1622     * 
     1623     */ 
    15761624    void addRange(void *pbot, void *ptop) 
    15771625    { 
     
    16211669        // other than the one the range was allocated on. 
    16221670        //assert(zero); 
     1671    } 
     1672 
     1673 
     1674    /** 
     1675     * 
     1676     */ 
     1677    int rangeIter(int delegate(inout Range) dg) 
     1678    { 
     1679        int result = 0; 
     1680        for( size_t i = 0; i < nranges; ++i ) 
     1681        { 
     1682            result = dg(ranges[i]); 
     1683            if (result) 
     1684                break; 
     1685        } 
     1686        return result; 
    16231687    } 
    16241688 
  • trunk/src/gc/stub/gc.d

    r38 r39  
    2121module gc.gc; 
    2222 
    23 private import core.stdc.stdlib; 
    24  
    2523private 
    2624{ 
     25   import core.stdc.stdlib; 
     26 
    2727   enum BlkAttr : uint 
    2828    { 
     
    4242    extern (C) void thread_init(); 
    4343    extern (C) void onOutOfMemoryError(); 
     44 
     45    struct Proxy 
     46    { 
     47        extern (C) void function() gc_enable; 
     48        extern (C) void function() gc_disable; 
     49        extern (C) void function() gc_collect; 
     50        extern (C) void function() gc_minimize; 
     51 
     52        extern (C) uint function(void*) gc_getAttr; 
     53        extern (C) uint function(void*, uint) gc_setAttr; 
     54        extern (C) uint function(void*, uint) gc_clrAttr; 
     55 
     56        extern (C) void*  function(size_t, uint) gc_malloc; 
     57        extern (C) void*  function(size_t, uint) gc_calloc; 
     58        extern (C) void*  function(void*, size_t, uint ba) gc_realloc; 
     59        extern (C) size_t function(void*, size_t, size_t) gc_extend; 
     60        extern (C) size_t function(size_t) gc_reserve; 
     61        extern (C) void   function(void*) gc_free; 
     62 
     63        extern (C) void*   function(void*) gc_addrOf; 
     64        extern (C) size_t  function(void*) gc_sizeOf; 
     65 
     66        extern (C) BlkInfo function(void*) gc_query; 
     67 
     68        extern (C) void function(void*) gc_addRoot; 
     69        extern (C) void function(void*, size_t) gc_addRange; 
     70 
     71        extern (C) void function(void*) gc_removeRoot; 
     72        extern (C) void function(void*) gc_removeRange; 
     73    } 
     74 
     75    Proxy  pthis; 
     76    Proxy* proxy; 
     77 
     78    void initProxy() 
     79    { 
     80        pthis.gc_enable = &gc_enable; 
     81        pthis.gc_disable = &gc_disable; 
     82        pthis.gc_collect = &gc_collect; 
     83        pthis.gc_minimize = &gc_minimize; 
     84 
     85        pthis.gc_getAttr = &gc_getAttr; 
     86        pthis.gc_setAttr = &gc_setAttr; 
     87        pthis.gc_clrAttr = &gc_clrAttr; 
     88 
     89        pthis.gc_malloc = &gc_malloc; 
     90        pthis.gc_calloc = &gc_calloc; 
     91        pthis.gc_realloc = &gc_realloc; 
     92        pthis.gc_extend = &gc_extend; 
     93        pthis.gc_reserve = &gc_reserve; 
     94        pthis.gc_free = &gc_free; 
     95 
     96        pthis.gc_addrOf = &gc_addrOf; 
     97        pthis.gc_sizeOf = &gc_sizeOf; 
     98 
     99        pthis.gc_query = &gc_query; 
     100 
     101        pthis.gc_addRoot = &gc_addRoot; 
     102        pthis.gc_addRange = &gc_addRange; 
     103 
     104        pthis.gc_removeRoot = &gc_removeRoot; 
     105        pthis.gc_removeRange = &gc_removeRange; 
     106    } 
     107 
     108    void** roots  = null; 
     109    size_t nroots = 0; 
     110 
     111    struct Range 
     112    { 
     113        void*  pos; 
     114        size_t len; 
     115    } 
     116 
     117    Range* ranges  = null; 
     118    size_t nranges = 0; 
    44119} 
    45120 
     
    49124    //       collection, and always before returning from gc_init(). 
    50125    thread_init(); 
     126    initProxy(); 
    51127} 
    52128 
    53129extern (C) void gc_term() 
    54130{ 
    55  
     131    free( roots ); 
     132    free( ranges ); 
    56133} 
    57134 
     
    186263} 
    187264 
    188 // TODO: Implement range storage. 
    189 // TODO: Implement root storage. 
    190  
    191265extern (C) void gc_addRoot( void* p ) 
    192266{ 
    193267    if( proxy is null ) 
    194         return; 
     268    { 
     269        void** r = cast(void**) realloc( roots, 
     270                                         (nroots+1) * roots[0].sizeof ); 
     271        if( r is null ) 
     272            onOutOfMemoryError(); 
     273        r[nroots++] = p; 
     274        roots = r; 
     275 
     276    } 
    195277    return proxy.gc_addRoot( p ); 
    196278} 
     
    199281{ 
    200282    if( proxy is null ) 
    201         return; 
     283    { 
     284        Range* r = cast(Range*) realloc( ranges, 
     285                                         (nranges+1) * ranges[0].sizeof ); 
     286        if( r is null ) 
     287            onOutOfMemoryError(); 
     288        r[nranges].pos = p; 
     289        r[nranges].len = sz; 
     290        ranges = r; 
     291        ++nranges; 
     292    } 
    202293    return proxy.gc_addRange( p, sz ); 
    203294} 
     
    206297{ 
    207298    if( proxy is null ) 
    208         return; 
     299    { 
     300        for( size_t i = 0; i < nroots; ++i ) 
     301        { 
     302            if( roots[i] is p ) 
     303            { 
     304                roots[i] = roots[--nroots]; 
     305                return; 
     306            } 
     307        } 
     308        assert( false ); 
     309    } 
    209310    return proxy.gc_removeRoot( p ); 
    210311} 
     
    213314{ 
    214315    if( proxy is null ) 
    215         return; 
     316    { 
     317        for( size_t i = 0; i < nranges; ++i ) 
     318        { 
     319            if( ranges[i].pos is p ) 
     320            { 
     321                ranges[i] = ranges[--nranges]; 
     322                return; 
     323            } 
     324        } 
     325        assert( false ); 
     326    } 
    216327    return proxy.gc_removeRange( p ); 
    217328} 
    218329 
    219 struct Proxy 
    220 { 
    221     extern (C) void function() gc_enable; 
    222     extern (C) void function() gc_disable; 
    223     extern (C) void function() gc_collect; 
    224     extern (C) void function() gc_minimize; 
    225  
    226     extern (C) uint function(void*) gc_getAttr; 
    227     extern (C) uint function(void*, uint) gc_setAttr; 
    228     extern (C) uint function(void*, uint) gc_clrAttr; 
    229  
    230     extern (C) void*  function(size_t, uint) gc_malloc; 
    231     extern (C) void*  function(size_t, uint) gc_calloc; 
    232     extern (C) void*  function(void*, size_t, uint ba) gc_realloc; 
    233     extern (C) size_t function(void*, size_t, size_t) gc_extend; 
    234     extern (C) size_t function(size_t) gc_reserve; 
    235     extern (C) void   function(void*) gc_free; 
    236  
    237     extern (C) void*   function(void*) gc_addrOf; 
    238     extern (C) size_t  function(void*) gc_sizeOf; 
    239  
    240     extern (C) BlkInfo function(void*) gc_query; 
    241  
    242     extern (C) void function(void*) gc_addRoot; 
    243     extern (C) void function(void*, size_t) gc_addRange; 
    244  
    245     extern (C) void function(void*) gc_removeRoot; 
    246     extern (C) void function(void*) gc_removeRange; 
    247 } 
    248  
    249 Proxy  pthis; 
    250 Proxy* proxy; 
    251  
    252 static this() 
    253 { 
    254     pthis.gc_enable = &gc_enable; 
    255     pthis.gc_disable = &gc_disable; 
    256     pthis.gc_collect = &gc_collect; 
    257     pthis.gc_minimize = &gc_minimize; 
    258  
    259     pthis.gc_getAttr = &gc_getAttr; 
    260     pthis.gc_setAttr = &gc_setAttr; 
    261     pthis.gc_clrAttr = &gc_clrAttr; 
    262  
    263     pthis.gc_malloc = &gc_malloc; 
    264     pthis.gc_calloc = &gc_calloc; 
    265     pthis.gc_realloc = &gc_realloc; 
    266     pthis.gc_extend = &gc_extend; 
    267     pthis.gc_reserve = &gc_reserve; 
    268     pthis.gc_free = &gc_free; 
    269  
    270     pthis.gc_addrOf = &gc_addrOf; 
    271     pthis.gc_sizeOf = &gc_sizeOf; 
    272  
    273     pthis.gc_query = &gc_query; 
    274  
    275     pthis.gc_addRoot = &gc_addRoot; 
    276     pthis.gc_addRange = &gc_addRange; 
    277  
    278     pthis.gc_removeRoot = &gc_removeRoot; 
    279     pthis.gc_removeRange = &gc_removeRange; 
    280 } 
    281  
    282330extern (C) Proxy* gc_getProxy() 
    283331{ 
     
    289337    if( proxy !is null ) 
    290338    { 
    291         // error? 
     339        // TODO: Decide if this is an error condition. 
    292340    } 
    293341    proxy = p; 
    294     ///foreach range 
    295     //proxy.addRange(); 
    296     //foreach root 
    297     //proxy.addRoot() 
     342    foreach( r; roots[0 .. nroots] ) 
     343        proxy.gc_addRoot( r ); 
     344    foreach( r; ranges[0 .. nranges] ) 
     345        proxy.gc_addRange( r.pos, r.len ); 
    298346} 
    299347 
    300348export extern (C) void gc_clrProxy() 
    301349{ 
    302     // foreach root 
    303     // proxy.removeRoot(); 
    304     // foreach range 
    305     // proxy.removeReange(); 
     350    foreach( r; ranges[0 .. nranges] ) 
     351        proxy.gc_removeRange( r.pos ); 
     352    foreach( r; roots[0 .. nroots] ) 
     353        proxy.gc_removeRoot( r ); 
    306354    proxy = null; 
    307355}