Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 497

Show
Ignore:
Timestamp:
01/10/11 19:44:10 (14 years ago)
Author:
walter
Message:

new functions to replace varargs ones

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/rt/lifetime.d

    r496 r497  
    14891489    p.length = newlength; 
    14901490    return newdata[0 .. newlength]; 
    14911491 
    14921492Loverflow: 
    14931493    onOutOfMemoryError(); 
    14941494    assert(0); 
    14951495} 
    14961496 
    14971497 
    14981498/** 
    1499  * Append y[] to array pointed to by px 
    1500  * size is size of each array element. 
    1501  */ 
    1502 extern (C) void[] _d_arrayappendT(TypeInfo ti, Array *px, byte[] y) 
    1503 
    1504     // only optimize array append where ti is not a shared type 
     1499 * Append y[] to array x[] 
     1500 */ 
     1501extern (C) void[] _d_arrayappendT(TypeInfo ti, ref byte[] x, byte[] y) 
     1502
     1503    auto length = x.length; 
    15051504    auto sizeelem = ti.next.tsize();            // array element size 
    1506     auto isshared = ti.classinfo is TypeInfo_Shared.classinfo; 
    1507     auto bic = !isshared ? __getBlkInfo(px.data) : null; 
    1508     auto info = bic ? *bic : gc_query(px.data); 
    1509     auto length = px.length; 
    1510     auto newlength = length + y.length; 
    1511     auto newsize = newlength * sizeelem; 
    1512     auto size = length * sizeelem; 
    1513  
    1514     // calculate the extent of the array given the base. 
    1515     size_t offset = px.data - __arrayStart(info); 
    1516     if(info.attr & BlkAttr.APPENDABLE) 
    1517     { 
    1518         if(info.size >= PAGESIZE) 
    1519         { 
    1520             // size of array is at the front of the block 
    1521             if(!__setArrayAllocLength(info, newsize + offset, isshared, size + offset)) 
    1522             { 
    1523                 // check to see if it failed because there is not 
    1524                 // enough space 
    1525                 auto newcap = newCapacity(newlength, sizeelem); 
    1526                 if(*(cast(size_t*)info.base) == size + offset) 
    1527                 { 
    1528                     // not enough space, try extending 
    1529                     auto extendoffset = offset + LARGEPAD - info.size; 
    1530                     auto u = gc_extend(px.data, newsize + extendoffset, newcap + extendoffset); 
    1531                     if(u) 
    1532                     { 
    1533                         // extend worked, now try setting the length 
    1534                         // again. 
    1535                         info.size = u; 
    1536                         if(__setArrayAllocLength(info, newsize + offset, isshared, size + offset)) 
    1537                         { 
    1538                             if(!isshared) 
    1539                                 __insertBlkInfoCache(info, bic); 
    1540                             goto L1; 
    1541                         } 
    1542                     } 
    1543                 } 
    1544  
    1545                 // couldn't do it, reallocate 
    1546                 info = gc_qalloc(newcap + LARGEPAD, info.attr); 
    1547                 __setArrayAllocLength(info, newsize, isshared); 
    1548                 if(!isshared) 
    1549                     __insertBlkInfoCache(info, bic); 
    1550                 auto newdata = cast(byte *)info.base + LARGEPREFIX; 
    1551                 memcpy(newdata, px.data, length * sizeelem); 
    1552                 px.data = newdata; 
    1553             } 
    1554             else if(!isshared && !bic) 
    1555             { 
    1556                 __insertBlkInfoCache(info, null); 
    1557             } 
    1558         } 
    1559         else if(!__setArrayAllocLength(info, newsize + offset, isshared, size + offset)) 
    1560         { 
    1561             // could not resize in place 
    1562             auto allocsize = newCapacity(newlength, sizeelem); 
    1563             info = gc_qalloc(allocsize + __arrayPad(allocsize), info.attr); 
    1564             goto L2; 
    1565         } 
    1566         else if(!isshared && !bic) 
    1567         { 
    1568             __insertBlkInfoCache(info, null); 
    1569         } 
    1570     } 
    1571     else 
    1572     { 
    1573         // not appendable or is null 
    1574         auto allocsize = newCapacity(newlength, sizeelem); 
    1575         info = gc_qalloc(allocsize + __arrayPad(allocsize), (info.base ? info.attr : !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0) | BlkAttr.APPENDABLE); 
    1576     L2: 
    1577         __setArrayAllocLength(info, newsize, isshared); 
    1578         if(!isshared) 
    1579             __insertBlkInfoCache(info, bic); 
    1580         auto newdata = cast(byte *)__arrayStart(info); 
    1581         memcpy(newdata, px.data, length * sizeelem); 
    1582         px.data = newdata; 
    1583     } 
    1584  
    1585  
    1586   L1: 
    1587     px.length = newlength; 
    1588     memcpy(px.data + length * sizeelem, y.ptr, y.length * sizeelem); 
    1589     return *cast(void[]*)px; 
     1505    _d_arrayappendcTX(ti, x, y.length); 
     1506    memcpy(x.ptr + length * sizeelem, y.ptr, y.length * sizeelem); 
     1507    return x; 
    15901508} 
    15911509 
    15921510 
    15931511/** 
    15941512 * 
    15951513 */ 
    15961514size_t newCapacity(size_t newlength, size_t size) 
    15971515{ 
    15981516    version(none) 
    15991517    { 
     
    16651583            debug(PRINTF) printf("mult: %2.2f, alloc: %2.2f\n",mult/100.0,newext / cast(double)size); 
    16661584        } 
    16671585        newcap = newext > newcap ? newext : newcap; 
    16681586        debug(PRINTF) printf("newcap = %d, newlength = %d, size = %d\n", newcap, newlength, size); 
    16691587    } 
    16701588    return newcap; 
    16711589} 
    16721590 
    16731591 
    16741592/** 
    1675  * 
    1676  */ 
    1677 extern (C) void[] _d_arrayappendcT(TypeInfo ti, Array *x, ...) 
     1593 * Obsolete, replaced with _d_arrayappendcTX() 
     1594 */ 
     1595extern (C) void[] _d_arrayappendcT(TypeInfo ti, ref byte[] x, ...) 
    16781596{ 
    16791597    version(X86) 
    16801598    {   
    16811599        byte *argp = cast(byte*)(&ti + 2); 
    16821600        return _d_arrayappendT(ti, x, argp[0..1]); 
    16831601    } 
    16841602    else version(X86_64) 
    16851603    { 
    16861604        // This code copies the element twice, which is annoying 
    16871605        //   #1 is from va_arg copying from the varargs to b 
     
    17031621        // 1 * ti.next.tsize bytes. 
    17041622        return _d_arrayappendT(ti, x, b[0..1]); 
    17051623    } 
    17061624    else 
    17071625    { 
    17081626        static assert(false, "platform not supported"); 
    17091627    } 
    17101628} 
    17111629 
    17121630 
     1631/************************************** 
     1632 * Extend an array by n elements. 
     1633 * Caller must initialize those elements. 
     1634 */ 
     1635extern (C) 
     1636byte[] _d_arrayappendcTX(TypeInfo ti, ref byte[] px, size_t n) 
     1637{ 
     1638    // This is a cut&paste job from _d_arrayappendT(). Should be refactored. 
     1639 
     1640    // only optimize array append where ti is not a shared type 
     1641    auto sizeelem = ti.next.tsize();            // array element size 
     1642    auto isshared = ti.classinfo is TypeInfo_Shared.classinfo; 
     1643    auto bic = !isshared ? __getBlkInfo(px.ptr) : null; 
     1644    auto info = bic ? *bic : gc_query(px.ptr); 
     1645    auto length = px.length; 
     1646    auto newlength = length + n; 
     1647    auto newsize = newlength * sizeelem; 
     1648    auto size = length * sizeelem; 
     1649 
     1650    // calculate the extent of the array given the base. 
     1651    size_t offset = px.ptr - __arrayStart(info); 
     1652    if(info.attr & BlkAttr.APPENDABLE) 
     1653    { 
     1654        if(info.size >= PAGESIZE) 
     1655        { 
     1656            // size of array is at the front of the block 
     1657            if(!__setArrayAllocLength(info, newsize + offset, isshared, size + offset)) 
     1658            { 
     1659                // check to see if it failed because there is not 
     1660                // enough space 
     1661                auto newcap = newCapacity(newlength, sizeelem); 
     1662                if(*(cast(size_t*)info.base) == size + offset) 
     1663                { 
     1664                    // not enough space, try extending 
     1665                    auto extendoffset = offset + LARGEPAD - info.size; 
     1666                    auto u = gc_extend(px.ptr, newsize + extendoffset, newcap + extendoffset); 
     1667                    if(u) 
     1668                    { 
     1669                        // extend worked, now try setting the length 
     1670                        // again. 
     1671                        info.size = u; 
     1672                        if(__setArrayAllocLength(info, newsize + offset, isshared, size + offset)) 
     1673                        { 
     1674                            if(!isshared) 
     1675                                __insertBlkInfoCache(info, bic); 
     1676                            goto L1; 
     1677                        } 
     1678                    } 
     1679                } 
     1680 
     1681                // couldn't do it, reallocate 
     1682                info = gc_qalloc(newcap + LARGEPAD, info.attr); 
     1683                __setArrayAllocLength(info, newsize, isshared); 
     1684                if(!isshared) 
     1685                    __insertBlkInfoCache(info, bic); 
     1686                auto newdata = cast(byte *)info.base + LARGEPREFIX; 
     1687                memcpy(newdata, px.ptr, length * sizeelem); 
     1688            (cast(void **)(&px))[1] = newdata; 
     1689            } 
     1690            else if(!isshared && !bic) 
     1691            { 
     1692                __insertBlkInfoCache(info, null); 
     1693            } 
     1694        } 
     1695        else if(!__setArrayAllocLength(info, newsize + offset, isshared, size + offset)) 
     1696        { 
     1697            // could not resize in place 
     1698            auto allocsize = newCapacity(newlength, sizeelem); 
     1699            info = gc_qalloc(allocsize + __arrayPad(allocsize), info.attr); 
     1700            goto L2; 
     1701        } 
     1702        else if(!isshared && !bic) 
     1703        { 
     1704            __insertBlkInfoCache(info, null); 
     1705        } 
     1706    } 
     1707    else 
     1708    { 
     1709        // not appendable or is null 
     1710        auto allocsize = newCapacity(newlength, sizeelem); 
     1711        info = gc_qalloc(allocsize + __arrayPad(allocsize), (info.base ? info.attr : !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0) | BlkAttr.APPENDABLE); 
     1712    L2: 
     1713        __setArrayAllocLength(info, newsize, isshared); 
     1714        if(!isshared) 
     1715            __insertBlkInfoCache(info, bic); 
     1716        auto newdata = cast(byte *)__arrayStart(info); 
     1717        memcpy(newdata, px.ptr, length * sizeelem); 
     1718        (cast(void **)(&px))[1] = newdata; 
     1719    } 
     1720 
     1721  L1: 
     1722    *cast(size_t *)&px = newlength; 
     1723    return px; 
     1724} 
     1725 
     1726 
    17131727/** 
    17141728 * Append dchar to char[] 
    17151729 */ 
    1716 extern (C) void[] _d_arrayappendcd(ref char[] x, dchar c) 
     1730extern (C) void[] _d_arrayappendcd(ref byte[] x, dchar c) 
    17171731{ 
    17181732    // c could encode into from 1 to 4 characters 
    17191733    char[4] buf = void; 
    17201734    byte[] appendthis; // passed to appendT 
    17211735    if (c <= 0x7F) 
    17221736    { 
    17231737        buf.ptr[0] = cast(char)c; 
    17241738        appendthis = (cast(byte *)buf.ptr)[0..1]; 
    17251739    } 
    17261740    else if (c <= 0x7FF) 
     
    17451759        appendthis = (cast(byte *)buf.ptr)[0..4]; 
    17461760    } 
    17471761    else 
    17481762        assert(0);      // invalid utf character - should we throw an exception instead? 
    17491763 
    17501764    // 
    17511765    // TODO: This always assumes the array type is shared, because we do not 
    17521766    // get a typeinfo from the compiler.  Assuming shared is the safest option. 
    17531767    // Once the compiler is fixed, the proper typeinfo should be forwarded. 
    17541768    // 
    1755     return _d_arrayappendT(typeid(shared char[]), cast(Array *)&x, appendthis); 
     1769    return _d_arrayappendT(typeid(shared char[]), x, appendthis); 
    17561770} 
    17571771 
    17581772 
    17591773/** 
    17601774 * Append dchar to wchar[] 
    17611775 */ 
    1762 extern (C) void[] _d_arrayappendwd(ref wchar[] x, dchar c) 
     1776extern (C) void[] _d_arrayappendwd(ref byte[] x, dchar c) 
    17631777{ 
    17641778    // c could encode into from 1 to 2 w characters 
    17651779    wchar[2] buf = void; 
    17661780    byte[] appendthis; // passed to appendT 
    17671781    if (c <= 0xFFFF) 
    17681782    { 
    17691783        buf.ptr[0] = cast(wchar) c; 
    17701784        // note that although we are passing only 1 byte here, appendT 
    17711785        // interprets this as being an array of wchar, making the necessary 
    17721786        // casts. 
     
    17781792        buf.ptr[1] = cast(wchar) (((c - 0x10000) & 0x3FF) + 0xDC00); 
    17791793        // ditto from above. 
    17801794        appendthis = (cast(byte *)buf.ptr)[0..2]; 
    17811795    } 
    17821796 
    17831797    // 
    17841798    // TODO: This always assumes the array type is shared, because we do not 
    17851799    // get a typeinfo from the compiler.  Assuming shared is the safest option. 
    17861800    // Once the compiler is fixed, the proper typeinfo should be forwarded. 
    17871801    // 
    1788     return _d_arrayappendT(typeid(shared wchar[]), cast(Array *)&x, appendthis); 
     1802    return _d_arrayappendT(typeid(shared wchar[]), x, appendthis); 
    17891803} 
    17901804 
    17911805 
    17921806/** 
    17931807 * 
    17941808 */ 
    17951809extern (C) byte[] _d_arraycatT(TypeInfo ti, byte[] x, byte[] y) 
    17961810out (result) 
    17971811{ 
    17981812    auto sizeelem = ti.next.tsize();            // array element size 
     
    19161930    } 
    19171931 
    19181932    Array2 result; 
    19191933    result.length = length; 
    19201934    result.ptr = a; 
    19211935    return *cast(byte[]*)&result; 
    19221936} 
    19231937 
    19241938 
    19251939/** 
    1926  * 
     1940 * Allocate the array, rely on the caller to do the initialization of the array. 
     1941 */ 
     1942extern (C) 
     1943void* _d_arrayliteralTX(TypeInfo ti, size_t length) 
     1944
     1945    auto sizeelem = ti.next.tsize();            // array element size 
     1946    void* result; 
     1947 
     1948    //printf("_d_arrayliteralTX(sizeelem = %d, length = %d)\n", sizeelem, length); 
     1949    if (length == 0 || sizeelem == 0) 
     1950        result = null; 
     1951    else 
     1952    { 
     1953        auto allocsize = length * sizeelem; 
     1954        auto info = gc_qalloc(allocsize + __arrayPad(allocsize), !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN | BlkAttr.APPENDABLE : BlkAttr.APPENDABLE); 
     1955        auto isshared = ti.classinfo is TypeInfo_Shared.classinfo; 
     1956        __setArrayAllocLength(info, allocsize, isshared); 
     1957        result = __arrayStart(info); 
     1958    } 
     1959    return result; 
     1960
     1961 
     1962/** 
     1963 * The old way, obsolete. 
    19271964 */ 
    19281965extern (C) void* _d_arrayliteralT(TypeInfo ti, size_t length, ...) 
    19291966{ 
    19301967    auto sizeelem = ti.next.tsize();            // array element size 
    19311968    void* result; 
    19321969 
    19331970    debug(PRINTF) printf("_d_arrayliteralT(sizeelem = %d, length = %d)\n", sizeelem, length); 
    19341971    if (length == 0 || sizeelem == 0) 
    19351972        result = null; 
    19361973    else