Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Changeset 2649

Show
Ignore:
Timestamp:
10/13/07 11:41:43 (1 year ago)
Author:
sean
Message:

Fix for ticket #557.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lib/compiler/dmd/lifetime.d

    r2577 r2649  
    4747    } 
    4848 
     49    struct BlkInfo 
     50    { 
     51        void*  base; 
     52        size_t size; 
     53        uint   attr; 
     54    } 
     55 
    4956    extern (C) uint gc_getAttr( void* p ); 
    5057    extern (C) uint gc_setAttr( void* p, uint a ); 
     
    5663    extern (C) void   gc_free( void* p ); 
    5764 
    58     extern (C) size_t gc_sizeOf( void* p ); 
     65    extern (C) void*   gc_addrOf( void* p ); 
     66    extern (C) size_t  gc_sizeOf( void* p ); 
     67    extern (C) BlkInfo gc_query( void* p ); 
    5968 
    6069    extern (C) bool onCollectResource( Object o ); 
     
    517526            { 
    518527                size_t size = p.length * sizeelem; 
    519                 size_t cap  = gc_sizeOf(p.data); 
    520  
    521                 if (cap <= newsize) 
     528                auto   info = gc_query(p.data); 
     529 
     530                if (info.size <= newsize) 
    522531                { 
    523                     if (cap >= PAGESIZE
     532                    if (info.size >= PAGESIZE && info.base == p.data
    524533                    {   // Try to extend in-place 
    525                         auto u = gc_extend(p.data, (newsize + 1) - cap, (newsize + 1) - cap); 
     534                        auto u = gc_extend(p.data, (newsize + 1) - info.size, (newsize + 1) - info.size); 
    526535                        if (u) 
    527536                        { 
     
    529538                        } 
    530539                    } 
    531                     newdata = cast(byte *)gc_malloc(newsize + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
     540                    newdata = cast(byte *)gc_malloc(newsize + 1, info.attr); 
    532541                    newdata[0 .. size] = p.data[0 .. size]; 
    533542                } 
     
    617626            if (newlength > p.length) 
    618627            { 
    619                 size_t cap = gc_sizeOf(p.data); 
    620  
    621                 if (cap <= newsize) 
     628                auto info = gc_query(p.data); 
     629 
     630                if (info.size <= newsize) 
    622631                { 
    623                     if (cap >= PAGESIZE
     632                    if (info.size >= PAGESIZE && info.base == p.data
    624633                    {   // Try to extend in-place 
    625                         auto u = gc_extend(p.data, (newsize + 1) - cap, (newsize + 1) - cap); 
     634                        auto u = gc_extend(p.data, (newsize + 1) - info.size, (newsize + 1) - info.size); 
    626635                        if (u) 
    627636                        { 
     
    629638                        } 
    630639                    } 
    631                     newdata = cast(byte *)gc_malloc(newsize + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
     640                    newdata = cast(byte *)gc_malloc(newsize + 1, info.attr); 
    632641                    newdata[0 .. size] = p.data[0 .. size]; 
    633642                L1: ; 
     
    679688{ 
    680689    auto sizeelem = ti.next.tsize();            // array element size 
    681     auto cap = gc_sizeOf(px.data); 
     690    auto info = gc_query(px.data); 
    682691    auto length = px.length; 
    683692    auto newlength = length + y.length; 
    684693    auto newsize = newlength * sizeelem; 
    685694 
    686     if (newsize > cap
     695    if (info.size < newsize
    687696    {   byte* newdata; 
    688697 
    689         if (cap >= PAGESIZE
     698        if (info.size >= PAGESIZE && info.base == px.data
    690699        {   // Try to extend in-place 
    691             auto u = gc_extend(px.data, (newsize + 1) - cap, (newsize + 1) - cap); 
     700            auto u = gc_extend(px.data, (newsize + 1) - info.size, (newsize + 1) - info.size); 
    692701            if (u) 
    693702            { 
     
    695704            } 
    696705        } 
    697         newdata = cast(byte *)gc_malloc(newCapacity(newlength, sizeelem) + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
     706        newdata = cast(byte *)gc_malloc(newCapacity(newlength, sizeelem) + 1, info.attr); 
    698707        memcpy(newdata, px.data, length * sizeelem); 
    699708        px.data = newdata; 
     
    784793{ 
    785794    auto sizeelem = ti.next.tsize();            // array element size 
    786     auto cap = gc_sizeOf(x.ptr); 
     795    auto info = gc_query(x.ptr); 
    787796    auto length = x.length; 
    788797    auto newlength = length + 1; 
    789798    auto newsize = newlength * sizeelem; 
    790799 
    791     assert(cap == 0 || length * sizeelem <= cap); 
    792  
    793     debug(PRINTF) printf("_d_arrayappendc(sizeelem = %d, ptr = %p, length = %d, cap = %d)\n", sizeelem, x.ptr, x.length, cap); 
    794  
    795     if (newsize >= cap
     800    assert(info.size == 0 || length * sizeelem <= info.size); 
     801 
     802    debug(PRINTF) printf("_d_arrayappendc(sizeelem = %d, ptr = %p, length = %d, cap = %d)\n", sizeelem, x.ptr, x.length, info.size); 
     803 
     804    if (info.size <= newsize
    796805    {   byte* newdata; 
    797806 
    798         if (cap >= PAGESIZE
     807        if (info.size >= PAGESIZE && info.base == x.ptr
    799808        {   // Try to extend in-place 
    800             auto u = gc_extend(x.ptr, (newsize + 1) - cap, (newsize + 1) - cap); 
     809            auto u = gc_extend(x.ptr, (newsize + 1) - info.size, (newsize + 1) - info.size); 
    801810            if (u) 
    802811            { 
     
    804813            } 
    805814        } 
    806         debug(PRINTF) printf("_d_arrayappendc(size = %d, newlength = %d, cap = %d)\n", size, newlength, cap); 
    807         cap = newCapacity(newlength, sizeelem); 
    808         assert(cap >= newlength * sizeelem); 
    809         newdata = cast(byte *)gc_malloc(cap + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
     815        debug(PRINTF) printf("_d_arrayappendc(size = %d, newlength = %d, cap = %d)\n", size, newlength, info.size); 
     816        auto newcap = newCapacity(newlength, sizeelem); 
     817        assert(newcap >= newlength * sizeelem); 
     818        newdata = cast(byte *)gc_malloc(newcap + 1, info.attr); 
    810819        memcpy(newdata, x.ptr, length * sizeelem); 
    811820        (cast(void**)(&x))[1] = newdata; 
  • trunk/lib/compiler/gdc/lifetime.d

    r2577 r2649  
    4747    } 
    4848 
     49    struct BlkInfo 
     50    { 
     51        void*  base; 
     52        size_t size; 
     53        uint   attr; 
     54    } 
     55 
    4956    extern (C) uint gc_getAttr( void* p ); 
    5057    extern (C) uint gc_setAttr( void* p, uint a ); 
     
    5663    extern (C) void   gc_free( void* p ); 
    5764 
    58     extern (C) size_t gc_sizeOf( void* p ); 
     65    extern (C) void*   gc_addrOf( void* p ); 
     66    extern (C) size_t  gc_sizeOf( void* p ); 
     67    extern (C) BlkInfo gc_query( void* p ); 
    5968 
    6069    extern (C) bool onCollectResource( Object o ); 
     
    517526            { 
    518527                size_t size = p.length * sizeelem; 
    519                 size_t cap  = gc_sizeOf(p.data); 
    520  
    521                 if (cap <= newsize) 
     528                auto   info = gc_query(p.data); 
     529 
     530                if (info.size <= newsize) 
    522531                { 
    523                     if (cap >= PAGESIZE
     532                    if (info.size >= PAGESIZE && info.base == p.data
    524533                    {   // Try to extend in-place 
    525                         auto u = gc_extend(p.data, (newsize + 1) - cap, (newsize + 1) - cap); 
     534                        auto u = gc_extend(p.data, (newsize + 1) - info.size, (newsize + 1) - info.size); 
    526535                        if (u) 
    527536                        { 
     
    529538                        } 
    530539                    } 
    531                     newdata = cast(byte *)gc_malloc(newsize + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
     540                    newdata = cast(byte *)gc_malloc(newsize + 1, info.attr); 
    532541                    newdata[0 .. size] = p.data[0 .. size]; 
    533542                } 
     
    624633            if (newlength > p.length) 
    625634            { 
    626                 size_t cap = gc_sizeOf(p.data); 
    627  
    628                 if (cap <= newsize) 
     635                auto info = gc_query(p.data); 
     636 
     637                if (info.size <= newsize) 
    629638                { 
    630                     if (cap >= PAGESIZE
     639                    if (info.size >= PAGESIZE && info.base == p.data
    631640                    {   // Try to extend in-place 
    632                         auto u = gc_extend(p.data, (newsize + 1) - cap, (newsize + 1) - cap); 
     641                        auto u = gc_extend(p.data, (newsize + 1) - info.size, (newsize + 1) - info.size); 
    633642                        if (u) 
    634643                        { 
     
    636645                        } 
    637646                    } 
    638                     newdata = cast(byte *)gc_malloc(newsize + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
     647                    newdata = cast(byte *)gc_malloc(newsize + 1, info.attr); 
    639648                    newdata[0 .. size] = p.data[0 .. size]; 
    640649                L1: ; 
     
    686695{ 
    687696    auto sizeelem = ti.next.tsize();            // array element size 
    688     auto cap = gc_sizeOf(px.data); 
     697    auto info = gc_query(px.data); 
    689698    auto length = px.length; 
    690699    auto newlength = length + y.length; 
    691700    auto newsize = newlength * sizeelem; 
    692701 
    693     if (newsize > cap
     702    if (info.size < newsize
    694703    {   byte* newdata; 
    695704 
    696         if (cap >= PAGESIZE
     705        if (info.size >= PAGESIZE && info.base == px.data
    697706        {   // Try to extend in-place 
    698             auto u = gc_extend(px.data, (newsize + 1) - cap, (newsize + 1) - cap); 
     707            auto u = gc_extend(px.data, (newsize + 1) - info.size, (newsize + 1) - info.size); 
    699708            if (u) 
    700709            { 
     
    702711            } 
    703712        } 
    704         newdata = cast(byte *)gc_malloc(newCapacity(newlength, sizeelem) + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
     713        newdata = cast(byte *)gc_malloc(newCapacity(newlength, sizeelem) + 1, info.attr); 
    705714        memcpy(newdata, px.data, length * sizeelem); 
    706715        px.data = newdata; 
     
    791800{ 
    792801    auto sizeelem = ti.next.tsize();            // array element size 
    793     auto cap = gc_sizeOf(x.ptr); 
     802    auto info = gc_query(x.ptr); 
    794803    auto length = x.length; 
    795804    auto newlength = length + 1; 
    796805    auto newsize = newlength * sizeelem; 
    797806 
    798     assert(cap == 0 || length * sizeelem <= cap); 
    799  
    800     debug(PRINTF) printf("_d_arrayappendc(sizeelem = %d, ptr = %p, length = %d, cap = %d)\n", sizeelem, x.ptr, x.length, cap); 
    801  
    802     if (newsize >= cap
     807    assert(info.size == 0 || length * sizeelem <= info.size); 
     808 
     809    debug(PRINTF) printf("_d_arrayappendc(sizeelem = %d, ptr = %p, length = %d, cap = %d)\n", sizeelem, x.ptr, x.length, info.size); 
     810 
     811    if (info.size <= newsize
    803812    {   byte* newdata; 
    804813 
    805         if (cap >= PAGESIZE
     814        if (info.size >= PAGESIZE && info.base == x.ptr
    806815        {   // Try to extend in-place 
    807             auto u = gc_extend(x.ptr, (newsize + 1) - cap, (newsize + 1) - cap); 
     816            auto u = gc_extend(x.ptr, (newsize + 1) - info.size, (newsize + 1) - info.size); 
    808817            if (u) 
    809818            { 
     
    811820            } 
    812821        } 
    813         debug(PRINTF) printf("_d_arrayappendc(size = %d, newlength = %d, cap = %d)\n", size, newlength, cap); 
    814         cap = newCapacity(newlength, sizeelem); 
    815         assert(cap >= newlength * sizeelem); 
    816         newdata = cast(byte *)gc_malloc(cap + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
     822        debug(PRINTF) printf("_d_arrayappendc(size = %d, newlength = %d, cap = %d)\n", size, newlength, info.size); 
     823        auto newcap = newCapacity(newlength, sizeelem); 
     824        assert(newcap >= newlength * sizeelem); 
     825        newdata = cast(byte *)gc_malloc(newcap + 1, info.attr); 
    817826        memcpy(newdata, x.ptr, length * sizeelem); 
    818827        (cast(void**)(&x))[1] = newdata; 
  • trunk/lib/gc/stub/gc.d

    r2648 r2649  
    132132extern (C) BlkInfo gc_query( void* p ) 
    133133{ 
    134     return BlkInfo.init 
     134    return BlkInfo.init; 
    135135} 
    136136