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

Changeset 1968

Show
Ignore:
Timestamp:
03/26/07 16:11:00 (2 years ago)
Author:
sean
Message:

Merged in DMD 1.010 changes. This includes:

  • Moved contents of lib/compiler/x/moduleinit into lib/compiler/x/genobj. This was necessary to support the new Object.factory() feature.
  • Added gc_extend() to extend page or larger sized blocks in place.
  • Changed lib/compiler/dmd/lifetime to use gc_extend.

Changes to GDC will wait until the next GDC release. There should be no gap in functionality aside from the lack of Object.factory(). The rest are just performance improvements.

Files:

Legend:

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

    r1856 r1968  
    1010 
    1111/* 
    12  *  Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com 
     12 *  Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com 
    1313 *  Written by Walter Bright 
    1414 * 
     
    4343    import tango.stdc.stdlib; // : calloc, realloc, free; 
    4444    import util.string; 
    45     debug import tango.stdc.stdio; // : printf; 
     45    debug(PRINTF) import tango.stdc.stdio; // : printf; 
    4646 
    4747    extern (C) void onOutOfMemoryError(); 
     48    extern (C) Object _d_newclass(ClassInfo ci); 
    4849} 
    4950 
     
    122123    int opEquals(Object o) 
    123124    { 
    124    return cast(int)(this is o); 
     125        return cast(int)(this is o); 
    125126    } 
    126127 
     
    137138    final void notifyRegister(void delegate(Object) dg) 
    138139    { 
    139         debug printf("notifyRegister(dg = %llx, o = %p)\n", dg, this); 
     140        debug(PRINTF) printf("notifyRegister(dg = %llx, o = %p)\n", dg, this); 
    140141        synchronized (this) 
    141142        { 
     
    191192    } 
    192193+/ 
     194 
     195    /** 
     196     * Create instance of class specified by classname. 
     197     * The class must either have no constructors or have 
     198     * a default constructor. 
     199     * Returns: 
     200     *  null if failed 
     201     */ 
     202    static Object factory(char[] classname) 
     203    { 
     204        auto ci = ClassInfo.find(classname); 
     205        if (ci) 
     206        { 
     207            return ci.create(); 
     208        } 
     209        return null; 
     210    } 
    193211} 
    194212 
    195213extern (C) void _d_notify_release(Object o) 
    196214{ 
    197     debug printf("_d_notify_release(o = %p)\n", o); 
     215    debug(PRINTF) printf("_d_notify_release(o = %p)\n", o); 
    198216    Monitor* m = cast(Monitor*)(cast(void**)o)[1]; 
    199217    if (m.delegates.length) 
     
    209227        { 
    210228            if (dg) 
    211             {   debug printf("calling dg = %llx (%p)\n", dg, o); 
     229            {   debug(PRINTF) printf("calling dg = %llx (%p)\n", dg, o); 
    212230                dg(o); 
    213231            } 
     
    250268    //  2:                      // has no possible pointers into GC memory 
    251269    //  4:                      // has offTi[] member 
     270    //  8:                      // has constructors 
    252271    void *deallocator; 
    253272    OffsetTypeInfo[] offTi; 
     273    void function(Object) defaultConstructor;   // default Constructor 
     274 
     275    /** 
     276     * Search all modules for ClassInfo corresponding to classname. 
     277     * Returns: null if not found 
     278     */ 
     279    static ClassInfo find(char[] classname) 
     280    { 
     281        foreach (m; ModuleInfo.modules()) 
     282        { 
     283            //writefln("module %s, %d", m.name, m.localClasses.length); 
     284            foreach (c; m.localClasses) 
     285            { 
     286                //writefln("\tclass %s", c.name); 
     287                if (c.name == classname) 
     288                    return c; 
     289            } 
     290        } 
     291        return null; 
     292    } 
     293 
     294    /** 
     295     * Create instance of Object represented by 'this'. 
     296     */ 
     297    Object create() 
     298    { 
     299        if (flags & 8 && !defaultConstructor) 
     300            return null; 
     301        Object o = _d_newclass(this); 
     302        if (flags & 8 && defaultConstructor) 
     303        { 
     304            defaultConstructor(o); 
     305        } 
     306        return o; 
     307    } 
    254308} 
    255309 
     
    427481    {   TypeInfo_Array c; 
    428482 
    429    return cast(int) 
    430           (this is o || 
     483        return cast(int) 
     484               (this is o || 
    431485                ((c = cast(TypeInfo_Array)o) !is null && 
    432         this.value == c.value)); 
     486                this.value == c.value)); 
    433487    } 
    434488 
     
    508562    {   TypeInfo_StaticArray c; 
    509563 
    510    return cast(int) 
    511           (this is o || 
     564        return cast(int) 
     565               (this is o || 
    512566                ((c = cast(TypeInfo_StaticArray)o) !is null && 
    513567                 this.len == c.len && 
    514         this.value == c.value)); 
     568                this.value == c.value)); 
    515569    } 
    516570 
     
    808862        assert(p); 
    809863        if (xtoHash) 
    810         {   debug printf("getHash() using xtoHash\n"); 
     864        {   debug(PRINTF) printf("getHash() using xtoHash\n"); 
    811865            h = (*xtoHash)(p); 
    812866        } 
    813867        else 
    814868        { 
    815             debug printf("getHash() using default hash\n"); 
     869            debug(PRINTF) printf("getHash() using default hash\n"); 
    816870            // A sorry hash algorithm. 
    817871            // Should use the one for strings. 
     
    9691023    } 
    9701024} 
     1025 
     1026 
     1027//////////////////////////////////////////////////////////////////////////////// 
     1028// ModuleInfo 
     1029//////////////////////////////////////////////////////////////////////////////// 
     1030 
     1031 
     1032enum 
     1033{ 
     1034    MIctorstart = 1,    // we've started constructing it 
     1035    MIctordone = 2,     // finished construction 
     1036    MIstandalone = 4,   // module ctor does not depend on other module 
     1037                        // ctors being done first 
     1038} 
     1039 
     1040 
     1041class ModuleInfo 
     1042{ 
     1043    char name[]; 
     1044    ModuleInfo importedModules[]; 
     1045    ClassInfo localClasses[]; 
     1046 
     1047    uint flags;         // initialization state 
     1048 
     1049    void (*ctor)(); 
     1050    void (*dtor)(); 
     1051    void (*unitTest)(); 
     1052 
     1053    static ModuleInfo[] modules() 
     1054    { 
     1055        return _moduleinfo_array; 
     1056    } 
     1057} 
     1058 
     1059 
     1060// Win32: this gets initialized by minit.asm 
     1061// linux: this gets initialized in _moduleCtor() 
     1062extern (C) ModuleInfo[] _moduleinfo_array; 
     1063 
     1064 
     1065version (linux) 
     1066{ 
     1067    // This linked list is created by a compiler generated function inserted 
     1068    // into the .ctor list by the compiler. 
     1069    struct ModuleReference 
     1070    { 
     1071        ModuleReference* next; 
     1072        ModuleInfo mod; 
     1073    } 
     1074 
     1075    extern (C) ModuleReference *_Dmodule_ref;   // start of linked list 
     1076} 
     1077 
     1078ModuleInfo[] _moduleinfo_dtors; 
     1079uint _moduleinfo_dtors_i; 
     1080 
     1081// Register termination function pointers 
     1082extern (C) int _fatexit(void *); 
     1083 
     1084/************************************* 
     1085 * Initialize the modules. 
     1086 */ 
     1087 
     1088extern (C) void _moduleCtor() 
     1089{ 
     1090    debug(PRINTF) printf("_moduleCtor()\n"); 
     1091    version (linux) 
     1092    { 
     1093        int len = 0; 
     1094        ModuleReference *mr; 
     1095 
     1096        for (mr = _Dmodule_ref; mr; mr = mr.next) 
     1097            len++; 
     1098        _moduleinfo_array = new ModuleInfo[len]; 
     1099        len = 0; 
     1100        for (mr = _Dmodule_ref; mr; mr = mr.next) 
     1101        {   _moduleinfo_array[len] = mr.mod; 
     1102            len++; 
     1103        } 
     1104    } 
     1105 
     1106    version (Win32) 
     1107    { 
     1108        // Ensure module destructors also get called on program termination 
     1109        //_fatexit(&_STD_moduleDtor); 
     1110    } 
     1111 
     1112    _moduleinfo_dtors = new ModuleInfo[_moduleinfo_array.length]; 
     1113    debug(PRINTF) printf("_moduleinfo_dtors = x%x\n", cast(void *)_moduleinfo_dtors); 
     1114    _moduleCtor2(_moduleinfo_array, 0); 
     1115} 
     1116 
     1117void _moduleCtor2(ModuleInfo[] mi, int skip) 
     1118{ 
     1119    debug(PRINTF) printf("_moduleCtor2(): %d modules\n", mi.length); 
     1120    for (uint i = 0; i < mi.length; i++) 
     1121    { 
     1122        ModuleInfo m = mi[i]; 
     1123 
     1124        debug(PRINTF) printf("\tmodule[%d] = '%p'\n", i, m); 
     1125        if (!m) 
     1126            continue; 
     1127        debug(PRINTF) printf("\tmodule[%d] = '%.*s'\n", i, m.name); 
     1128        if (m.flags & MIctordone) 
     1129            continue; 
     1130        debug(PRINTF) printf("\tmodule[%d] = '%.*s', m = x%x\n", i, m.name, m); 
     1131 
     1132        if (m.ctor || m.dtor) 
     1133        { 
     1134            if (m.flags & MIctorstart) 
     1135            {   if (skip || m.flags & MIstandalone) 
     1136                    continue; 
     1137                    throw new Exception( "Cyclic dependency in module " ~ m.name ); 
     1138            } 
     1139 
     1140            m.flags |= MIctorstart; 
     1141            _moduleCtor2(m.importedModules, 0); 
     1142            if (m.ctor) 
     1143                (*m.ctor)(); 
     1144            m.flags &= ~MIctorstart; 
     1145            m.flags |= MIctordone; 
     1146 
     1147            // Now that construction is done, register the destructor 
     1148            //printf("\tadding module dtor x%x\n", m); 
     1149            assert(_moduleinfo_dtors_i < _moduleinfo_dtors.length); 
     1150            _moduleinfo_dtors[_moduleinfo_dtors_i++] = m; 
     1151        } 
     1152        else 
     1153        { 
     1154            m.flags |= MIctordone; 
     1155            _moduleCtor2(m.importedModules, 1); 
     1156        } 
     1157    } 
     1158} 
     1159 
     1160 
     1161/********************************** 
     1162 * Destruct the modules. 
     1163 */ 
     1164 
     1165// Starting the name with "_STD" means under linux a pointer to the 
     1166// function gets put in the .dtors segment. 
     1167 
     1168extern (C) void _moduleDtor() 
     1169{ 
     1170    debug(PRINTF) printf("_moduleDtor(): %d modules\n", _moduleinfo_dtors_i); 
     1171    for (uint i = _moduleinfo_dtors_i; i-- != 0;) 
     1172    { 
     1173        ModuleInfo m = _moduleinfo_dtors[i]; 
     1174 
     1175        debug(PRINTF) printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m); 
     1176        if (m.dtor) 
     1177        { 
     1178            (*m.dtor)(); 
     1179        } 
     1180    } 
     1181    debug(PRINTF) printf("_moduleDtor() done\n"); 
     1182} 
     1183 
     1184/********************************** 
     1185 * Run unit tests. 
     1186 */ 
     1187 
     1188extern (C) void _moduleUnitTests() 
     1189{ 
     1190    debug(PRINTF) printf("_moduleUnitTests()\n"); 
     1191    for (uint i = 0; i < _moduleinfo_array.length; i++) 
     1192    { 
     1193        ModuleInfo m = _moduleinfo_array[i]; 
     1194 
     1195        if (!m) 
     1196            continue; 
     1197 
     1198        debug(PRINTF) printf("\tmodule[%d] = '%.*s'\n", i, m.name); 
     1199        if (m.unitTest) 
     1200        { 
     1201            (*m.unitTest)(); 
     1202        } 
     1203    } 
     1204} 
  • trunk/lib/compiler/dmd/lifetime.d

    r1862 r1968  
    3333    import tango.stdc.string; 
    3434    import tango.stdc.stdarg; 
    35     debug import tango.stdc.stdio; 
     35    debug(PRINTF) import tango.stdc.stdio; 
    3636} 
    3737 
     
    5151    extern (C) uint gc_clrAttr( void* p, uint a ); 
    5252 
    53     extern (C) void* gc_malloc( size_t sz, uint ba = 0 ); 
    54     extern (C) void* gc_calloc( size_t sz, uint ba = 0 ); 
    55     extern (C) void  gc_free( void* p ); 
     53    extern (C) void*  gc_malloc( size_t sz, uint ba = 0 ); 
     54    extern (C) void*  gc_calloc( size_t sz, uint ba = 0 ); 
     55    extern (C) size_t gc_extend( void* p, size_t minsz, size_t maxsz ); 
     56    extern (C) void   gc_free( void* p ); 
    5657 
    5758    extern (C) size_t gc_sizeOf( void* p ); 
     
    7273    void* p; 
    7374 
    74     debug printf("_d_newclass(ci = %p, %s)\n", ci, cast(char *)ci.name); 
     75    debug(PRINTF) printf("_d_newclass(ci = %p, %s)\n", ci, cast(char *)ci.name); 
    7576    if (ci.flags & 1) // if COM object 
    7677    { 
     
    8384        p = gc_malloc(ci.init.length, 
    8485                      BlkAttr.FINALIZE | (ci.flags & 2 ? BlkAttr.NO_SCAN : 0)); 
    85         debug printf(" p = %p\n", p); 
    86     } 
    87  
    88     debug 
     86        debug(PRINTF) printf(" p = %p\n", p); 
     87    } 
     88 
     89    debug(PRINTF) 
    8990    { 
    9091        printf("p = %p\n", p); 
     
    103104    (cast(byte*) p)[0 .. ci.init.length] = ci.init[]; 
    104105 
    105     debug printf("initialization done\n"); 
     106    debug(PRINTF) printf("initialization done\n"); 
    106107    return cast(Object) p; 
    107108} 
     
    135136    if (*p) 
    136137    { 
    137         debug printf("_d_delclass(%p)\n", *p); 
     138        debug(PRINTF) printf("_d_delclass(%p)\n", *p); 
    138139 
    139140        cr_finalize(cast(void*) *p); 
     
    169170    auto size = ti.next.tsize();                // array element size 
    170171 
    171     debug printf("_d_newT(length = %d, size = %d)\n", length, size); 
     172    debug(PRINTF) printf("_d_newT(length = %d, size = %d)\n", length, size); 
    172173    if (length == 0 || size == 0) 
    173174        result = 0; 
     
    176177        size *= length; 
    177178        p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
    178         debug printf(" p = %p\n", p); 
     179        debug(PRINTF) printf(" p = %p\n", p); 
    179180        memset(p, 0, size); 
    180181        result = cast(ulong)length + (cast(ulong)cast(uint)p << 32); 
     
    192193    auto size = ti.next.tsize();                // array element size 
    193194 
    194     debug printf("_d_newarrayii(length = %d, size = %d)\n", length, size); 
     195    debug(PRINTF) printf("_d_newarrayii(length = %d, size = %d)\n", length, size); 
    195196 
    196197    if (length == 0 || size == 0) 
     
    203204        size *= length; 
    204205        auto p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
    205         debug printf(" p = %p\n", p); 
     206        debug(PRINTF) printf(" p = %p\n", p); 
    206207        if (isize == 1) 
    207208            memset(p, *cast(ubyte*)q, size); 
     
    236237    ulong result; 
    237238 
    238     debug printf("_d_newarraymT(ndims = %d)\n", ndims); 
     239    debug(PRINTF) printf("_d_newarraymT(ndims = %d)\n", ndims); 
    239240    if (ndims == 0) 
    240241        result = 0; 
     
    248249            void[] p; 
    249250 
    250             debug printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims); 
     251            debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims); 
    251252            if (ndims == 1) 
    252253            { 
     
    267268        size_t* pdim = cast(size_t *)q; 
    268269        result = cast(ulong)foo(ti, pdim, ndims); 
    269         debug printf("result = %llx\n", result); 
     270        debug(PRINTF) printf("result = %llx\n", result); 
    270271 
    271272        version (none) 
     
    289290    ulong result; 
    290291 
    291     debug printf("_d_newarraymi(ndims = %d)\n", ndims); 
     292    debug(PRINTF) printf("_d_newarraymi(ndims = %d)\n", ndims); 
    292293    if (ndims == 0) 
    293294        result = 0; 
     
    320321        size_t* pdim = cast(size_t *)q; 
    321322        result = cast(ulong)foo(ti, pdim, ndims); 
    322         debug printf("result = %llx\n", result); 
     323        debug(PRINTF) printf("result = %llx\n", result); 
    323324 
    324325        version (none) 
     
    390391extern (C) void cr_finalize(void* p, bool det = true) 
    391392{ 
    392     debug printf("cr_finalize(p = %p)\n", p); 
     393    debug(PRINTF) printf("cr_finalize(p = %p)\n", p); 
    393394 
    394395    if (p) // not necessary if called from gc 
     
    444445    size_t sizeelem = ti.next.tsize(); 
    445446 
    446     debug 
     447    debug(PRINTF) 
    447448    { 
    448449        printf("_d_arraysetlengthT(p = %p, sizeelem = %d, newlength = %d)\n", p, sizeelem, newlength); 
     
    473474        } 
    474475 
    475         debug printf("newsize = %x, newlength = %x\n", newsize, newlength); 
     476        debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength); 
    476477 
    477478        if (p.data) 
     
    485486                if (cap <= newsize) 
    486487                { 
     488                    if (cap >= 4096) 
     489                    {   // Try to extend in-place 
     490                        auto u = gc_extend(p.data, (newsize + 1) - cap, (newsize + 1) - cap); 
     491                        if (u) 
     492                        { 
     493                            goto L1; 
     494                        } 
     495                    } 
    487496                    newdata = cast(byte *)gc_malloc(newsize + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
    488497                    newdata[0 .. size] = p.data[0 .. size]; 
    489498                } 
     499             L1: 
    490500                newdata[size .. newsize] = 0; 
    491501            } 
     
    535545    assert((sizeelem / initsize) * initsize == sizeelem); 
    536546 
    537     debug 
     547    debug(PRINTF) 
    538548    { 
    539549        printf("_d_arraysetlengthiT(p = %p, sizeelem = %d, newlength = %d, initsize = %d)\n", p, sizeelem, newlength, initsize); 
     
    563573                goto Loverflow; 
    564574        } 
    565         debug printf("newsize = %x, newlength = %x\n", newsize, newlength); 
     575        debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength); 
    566576 
    567577        size_t size = p.length * sizeelem; 
     
    576586                if (cap <= newsize) 
    577587                { 
     588                    if (cap >= 4096) 
     589                    {   // Try to extend in-place 
     590                        auto u = gc_extend(p.data, (newsize + 1) - cap, (newsize + 1) - cap); 
     591                        if (u) 
     592                        { 
     593                            goto L1; 
     594                        } 
     595                    } 
    578596                    newdata = cast(byte *)gc_malloc(newsize + 1); 
    579597                    newdata[0 .. size] = p.data[0 .. size]; 
     598                L1: ; 
    580599                } 
    581600            } 
     
    592611            if (initsize == 1) 
    593612            { 
    594                 debug printf("newdata = %p, size = %d, newsize = %d, *q = %d\n", newdata, size, newsize, *cast(byte*)q); 
     613                debug(PRINTF) printf("newdata = %p, size = %d, newsize = %d, *q = %d\n", newdata, size, newsize, *cast(byte*)q); 
    595614                newdata[size .. newsize] = *(cast(byte*)q); 
    596615            } 
     
    624643extern (C) long _d_arrayappendT(TypeInfo ti, Array *px, byte[] y) 
    625644{ 
    626     auto size = ti.next.tsize();                // array element size 
    627     size_t cap = gc_sizeOf(px.data); 
    628     size_t length    = px.length; 
    629     size_t newlength = length + y.length; 
    630  
    631     if (newlength * size > cap) 
     645    auto sizeelem = ti.next.tsize();            // array element size 
     646    auto cap = gc_sizeOf(px.data); 
     647    auto length = px.length; 
     648    auto newlength = length + y.length; 
     649    auto newsize = newlength * sizeelem; 
     650 
     651    if (newsize > cap) 
    632652    {   byte* newdata; 
    633653 
    634         newdata = cast(byte *)gc_malloc(newCapacity(newlength, size) + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
    635         memcpy(newdata, px.data, length * size); 
     654        if (cap >= 4096) 
     655        {   // Try to extend in-place 
     656            auto u = gc_extend(px.data, (newsize + 1) - cap, (newsize + 1) - cap); 
     657            if (u) 
     658            { 
     659                goto L1; 
     660            } 
     661        } 
     662        newdata = cast(byte *)gc_malloc(newCapacity(newlength, sizeelem) + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
     663        memcpy(newdata, px.data, length * sizeelem); 
    636664        px.data = newdata; 
    637665    } 
     666  L1: 
    638667    px.length = newlength; 
    639     memcpy(px.data + length * size, y.ptr, y.length * size); 
     668    memcpy(px.data + length * sizeelem, y.ptr, y.length * sizeelem); 
    640669    return *cast(long*)px; 
    641670} 
     
    659688         * - Arrays smaller than 4096 bytes are left as-is, so for the most 
    660689         * common cases, memory allocation is 1 to 1. The small overhead added 
    661          * doesn't effect small array perf. (it's virutally the same as 
     690         * doesn't affect small array perf. (it's virtually the same as 
    662691         * current). 
    663692         * - Larger arrays have some space pre-allocated. 
     
    705734            newext = cast(size_t)((newcap * mult) / 100); 
    706735            newext -= newext % size; 
    707             debug printf("mult: %2.2f, alloc: %2.2f\n",mult/100.0,newext / cast(double)size); 
     736            debug(PRINTF) printf("mult: %2.2f, alloc: %2.2f\n",mult/100.0,newext / cast(double)size); 
    708737        } 
    709738        newcap = newext > newcap ? newext : newcap; 
    710         debug printf("newcap = %d, newlength = %d, size = %d\n", newcap, newlength, size); 
     739        debug(PRINTF) printf("newcap = %d, newlength = %d, size = %d\n", newcap, newlength, size); 
    711740    } 
    712741    return newcap; 
     
    719748extern (C) byte[] _d_arrayappendcT(TypeInfo ti, inout byte[] x, ...) 
    720749{ 
    721     auto size = ti.next.tsize();                // array element size 
    722     size_t cap = gc_sizeOf(x.ptr); 
    723     size_t length    = x.length; 
    724     size_t newlength = length + 1; 
    725  
    726     assert(cap == 0 || length * size <= cap); 
    727  
    728     debug printf("_d_arrayappendc(size = %d, ptr = %p, length = %d, cap = %d)\n", size, x.ptr, x.length, cap); 
    729  
    730     if (newlength * size >= cap) 
     750    auto sizeelem = ti.next.tsize();            // array element size 
     751    auto cap = gc_sizeOf(x.ptr); 
     752    auto length = x.length; 
     753    auto newlength = length + 1; 
     754    auto newsize = newlength * sizeelem; 
     755 
     756    assert(cap == 0 || length * sizeelem <= cap); 
     757 
     758    debug(PRINTF) printf("_d_arrayappendc(sizeelem = %d, ptr = %p, length = %d, cap = %d)\n", sizeelem, x.ptr, x.length, cap); 
     759 
     760    if (newsize >= cap) 
    731761    {   byte* newdata; 
    732762 
    733         debug printf("_d_arrayappendc(size = %d, newlength = %d, cap = %d)\n", size, newlength, cap); 
    734         cap = newCapacity(newlength, size); 
    735         assert(cap >= newlength * size); 
     763        if (cap >= 4096) 
     764        {   // Try to extend in-place 
     765            auto u = gc_extend(x.ptr, (newsize + 1) - cap, (newsize + 1) - cap); 
     766            if (u) 
     767            { 
     768                goto L1; 
     769            } 
     770        } 
     771        debug(PRINTF) printf("_d_arrayappendc(size = %d, newlength = %d, cap = %d)\n", size, newlength, cap); 
     772        cap = newCapacity(newlength, sizeelem); 
     773        assert(cap >= newlength * sizeelem); 
    736774        newdata = cast(byte *)gc_malloc(cap + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
    737         memcpy(newdata, x.ptr, length * size); 
     775        memcpy(newdata, x.ptr, length * sizeelem); 
    738776        (cast(void**)(&x))[1] = newdata; 
    739777    } 
     778  L1: 
    740779    byte *argp = cast(byte *)(&ti + 2); 
    741780 
    742781    *cast(size_t *)&x = newlength; 
    743     (cast(byte *)x)[length * size .. newlength * size] = argp[0 .. size]; 
     782    (cast(byte *)x)[length * sizeelem .. newsize] = argp[0 .. sizeelem]; 
    744783    assert((cast(size_t)x.ptr & 15) == 0); 
    745     assert(gc_sizeOf(x.ptr) > x.length * size); 
     784    assert(gc_sizeOf(x.ptr) > x.length * sizeelem); 
    746785    return x; 
    747786} 
     
    754793out (result) 
    755794{ 
    756     auto size = ti.next.tsize();                // array element size 
    757     debug printf("_d_arraycatT(%d,%p ~ %d,%p size = %d => %d,%p)\n", x.length, x.ptr, y.length, y.ptr, size, result.length, result.ptr); 
     795    auto sizeelem = ti.next.tsize();            // array element size 
     796    debug(PRINTF) printf("_d_arraycatT(%d,%p ~ %d,%p sizeelem = %d => %d,%p)\n", x.length, x.ptr, y.length, y.ptr, sizeelem, result.length, result.ptr); 
    758797    assert(result.length == x.length + y.length); 
    759     for (size_t i = 0; i < x.length * size; i++) 
     798    for (size_t i = 0; i < x.length * sizeelem; i++) 
    760799        assert((cast(byte*)result)[i] == (cast(byte*)x)[i]); 
    761     for (size_t i = 0; i < y.length * size; i++) 
    762         assert((cast(byte*)result)[x.length * size + i] == (cast(byte*)y)[i]); 
     800    for (size_t i = 0; i < y.length * sizeelem; i++) 
     801        assert((cast(byte*)result)[x.length * sizeelem + i] == (cast(byte*)y)[i]); 
    763802 
    764803    size_t cap = gc_sizeOf(result.ptr); 
    765     assert(!cap || cap > result.length * size); 
     804    assert(!cap || cap > result.length * sizeelem); 
    766805} 
    767806body 
     
    782821    } 
    783822 
    784     debug printf("_d_arraycatT(%d,%p ~ %d,%p)\n", x.length, x.ptr, y.length, y.ptr); 
    785     auto size = ti.next.tsize();                // array element size 
    786     debug printf("_d_arraycatT(%d,%p ~ %d,%p size = %d)\n", x.length, x.ptr, y.length, y.ptr, size); 
    787     size_t xlen = x.length * size
    788     size_t ylen = y.length * size
     823    debug(PRINTF) printf("_d_arraycatT(%d,%p ~ %d,%p)\n", x.length, x.ptr, y.length, y.ptr); 
     824    auto sizeelem = ti.next.tsize();            // array element size 
     825    debug(PRINTF) printf("_d_arraycatT(%d,%p ~ %d,%p sizeelem = %d)\n", x.length, x.ptr, y.length, y.ptr, sizeelem); 
     826    size_t xlen = x.length * sizeelem
     827    size_t ylen = y.length * sizeelem
    789828    size_t len  = xlen + ylen; 
    790829 
     
    804843 */ 
    805844extern (C) byte[] _d_arraycatnT(TypeInfo ti, uint n, ...) 
    806 {   byte[] a; 
     845{   void* a; 
    807846    size_t length; 
    808847    byte[]* p; 
    809848    uint i; 
    810849    byte[] b; 
    811     auto size = ti.next.tsize(); // array element size 
     850    auto sizeelem = ti.next.tsize();            // array element size 
    812851 
    813852    p = cast(byte[]*)(&n + 1); 
     
    821860        return null; 
    822861 
    823     a = new byte[length * size]; 
    824     if (!(ti.next.flags() & 1)) 
    825         gc_setAttr(a.ptr, BlkAttr.NO_SCAN); 
     862    a = gc_malloc(length * sizeelem, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
    826863    p = cast(byte[]*)(&n + 1); 
    827864 
     
    832869        if (b.length) 
    833870        { 
    834             memcpy(&a[j], b.ptr, b.length * size); 
    835             j += b.length * size; 
    836         } 
    837     } 
    838  
    839     *cast(size_t *)&a = length; // jam length 
    840     //a.length = length; 
    841     return a; 
     871            memcpy(a + j, b.ptr, b.length * sizeelem); 
     872            j += b.length * sizeelem; 
     873        } 
     874    } 
     875 
     876    byte[] result; 
     877    *cast(int *)&result = length;       // jam length 
     878    (cast(void **)&result)[1] = a;      // jam ptr 
     879    return result; 
    842880} 
    843881 
     
    848886extern (C) void* _d_arrayliteralT(TypeInfo ti, size_t length, ...) 
    849887{ 
    850     auto size = ti.next.tsize(); // array element size 
    851     void[] result; 
    852  
    853     debug printf("_d_arrayliteralT(size = %d, length = %d)\n", size, length); 
    854     if (length == 0 || size == 0) 
     888    auto sizeelem = ti.next.tsize();            // array element size 
     889    void* result; 
     890 
     891    debug(PRINTF) printf("_d_arrayliteralT(sizeelem = %d, length = %d)\n", sizeelem, length); 
     892    if (length == 0 || sizeelem == 0) 
    855893        result = null; 
    856894    else 
    857895    { 
    858         result = new void[length * size]; 
    859         if (!(ti.next.flags() & 1)) 
    860             gc_setAttr(result.ptr, BlkAttr.NO_SCAN); 
    861         *cast(size_t *)&result = length; // jam length 
     896        result = gc_malloc(length * sizeelem, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
    862897 
    863898        va_list q; 
    864899        va_start!(size_t)(q, length); 
    865900 
    866         size_t stacksize = (size + int.sizeof - 1) & ~(int.sizeof - 1); 
    867  
    868         if (stacksize == size
    869         { 
    870             memcpy(result.ptr, q, length * size); 
     901        size_t stacksize = (sizeelem + int.sizeof - 1) & ~(int.sizeof - 1); 
     902 
     903        if (stacksize == sizeelem
     904        { 
     905            memcpy(result, q, length * sizeelem); 
    871906        } 
    872907        else 
     
    874909            for (size_t i = 0; i < length; i++) 
    875910            { 
    876                 memcpy(result.ptr + i * size, q, size); 
     911                memcpy(result + i * sizeelem, q, sizeelem); 
    877912                q += stacksize; 
    878        
    879    
     913           
     914       
    880915 
    881916        va_end(q); 
    882917    } 
    883     return result.ptr
     918    return result
    884919} 
    885920 
     
    901936out (result) 
    902937{ 
    903     auto szelem = ti.next.tsize();          // array element size 
    904     assert(memcmp((*cast(Array2*)&result).ptr, a.ptr, a.length * szelem) == 0); 
     938    auto sizeelem = ti.next.tsize();            // array element size 
     939    assert(memcmp((*cast(Array2*)&result).ptr, a.ptr, a.length * sizeelem) == 0); 
    905940} 
    906941body 
     
    910945    if (a.length) 
    911946    { 
    912         auto szelem = ti.next.tsize();              // array element size 
    913         auto size = a.length * szelem; 
     947        auto sizeelem = ti.next.tsize();                // array element size 
     948        auto size = a.length * sizeelem; 
    914949        r.ptr = gc_malloc(size, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0); 
    915950        r.length = a.length; 
  • trunk/lib/compiler/dmd/posix.mak

    r1859 r1968  
    8787    qsort.o \ 
    8888    switch.o \ 
    89     moduleinit.o \ 
    9089    trace.o 
    9190# NOTE: trace.obj and cover.obj are not necessary for a successful build 
  • trunk/lib/compiler/dmd/win32.mak

    r1859 r1968  
    7878    qsort.obj \ 
    7979    switch.obj \ 
    80     moduleinit.obj \ 
    8180    trace.obj 
    8281# NOTE: trace.obj and cover.obj are not necessary for a successful build 
  • trunk/lib/compiler/gdc/Makefile.am

    r1908 r1968  
    9090    qsortg.o \ 
    9191    rundmain.o \ 
    92     switch.o \ 
    93     moduleinit.o 
     92    switch.o 
    9493 
    9594OBJ_UTIL= \ 
  • trunk/lib/compiler/gdc/Makefile.in

    r1909 r1968  
    262262    qsortg.o \ 
    263263    rundmain.o \ 
    264     switch.o \ 
    265     moduleinit.o 
     264    switch.o 
    266265 
    267266OBJ_UTIL = \ 
     
    277276 
    278277# This should not be linked into a shared library. 
    279 CMAIN_OBJS =  
    280 ZLIB_OBJS =  
    281 GC_OBJS =  
     278CMAIN_OBJS = 
     279ZLIB_OBJS = 
     280GC_OBJS = 
    282281 
    283282# Removed threadsem for Tango 
     
    285284 
    286285# std.c.linux.linux, std.loader, gcc.cbridge* 
    287 WINDOWS_OBJS =  
     286WINDOWS_OBJS = 
    288287CONFIG_D_FRAGMENTS = config/config-head frag-ac frag-gen frag-math config/config-mid config/config-tail 
    289288CONFIG_UNIX_FRAGMENTS = config/unix-head frag-unix config/unix-mid 
     
    384383    @rm -f stamp-h1 
    385384    cd $(top_builddir) && $(SHELL) ./config.status config.h 
    386 $(srcdir)/config.h.in:  $(am__configure_deps)  
     385$(srcdir)/config.h.in:  $(am__configure_deps) 
    387386    cd $(top_srcdir) && $(AUTOHEADER) 
    388387    rm -f stamp-h1 
     
    398397clean-noinstPROGRAMS: 
    399398    -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) 
    400 minimal$(EXEEXT): $(minimal_OBJECTS) $(minimal_DEPENDENCIES)  
     399minimal$(EXEEXT): $(minimal_OBJECTS) $(minimal_DEPENDENCIES) 
    401400    @rm -f minimal$(EXEEXT) 
    402401    $(LINK) $(minimal_LDFLAGS) $(minimal_OBJECTS) $(minimal_LDADD) $(LIBS) 
  • trunk/lib/compiler/gdc/genobj.d

    r1856 r1968  
    981981    } 
    982982} 
     983 
     984 
     985 
     986enum 
     987{ 
     988    MIctorstart = 1,    // we've started constructing it 
     989    MIctordone = 2,     // finished construction 
     990    MIstandalone = 4,   // module ctor does not depend on other module 
     991                        // ctors being done first 
     992} 
     993 
     994class ModuleInfo 
     995{ 
     996    char name[]; 
     997    ModuleInfo importedModules[]; 
     998    ClassInfo localClasses[]; 
     999 
     1000    uint flags;         // initialization state 
     1001 
     1002    void (*ctor)(); 
     1003    void (*dtor)(); 
     1004    void (*unitTest)(); 
     1005 
     1006    static ModuleInfo[] modules() 
     1007    { 
     1008        return _moduleinfo_array; 
     1009    } 
     1010} 
     1011 
     1012 
     1013// Win32: this gets initialized by minit.asm 
     1014// linux: this gets initialized in _moduleCtor() 
     1015extern (C) ModuleInfo[] _moduleinfo_array; 
     1016 
     1017version (GNU) 
     1018{ 
     1019    version = ModRefStyle; 
     1020} 
     1021version (linux) 
     1022{ 
     1023    version = ModRefStyle; 
     1024} 
     1025version (ModRefStyle) 
     1026{ 
     1027    // This linked list is created by a compiler generated function inserted 
     1028    // into the .ctor list by the compiler. 
     1029    struct ModuleReference 
     1030    { 
     1031        ModuleReference* next; 
     1032        ModuleInfo mod; 
     1033    } 
     1034 
     1035    extern (C) ModuleReference *_Dmodule_ref;   // start of linked list 
     1036} 
     1037 
     1038ModuleInfo[] _moduleinfo_dtors; 
     1039uint _moduleinfo_dtors_i; 
     1040 
     1041// Register termination function pointers 
     1042extern (C) int _fatexit(void *); 
     1043 
     1044/************************************* 
     1045 * Initialize the modules. 
     1046 */ 
     1047 
     1048extern (C) void _moduleCtor() 
     1049{ 
     1050    debug printf("_moduleCtor()\n"); 
     1051    version (ModRefStyle) 
     1052    { 
     1053        int len = 0; 
     1054        ModuleReference *mr; 
     1055 
     1056        for (mr = _Dmodule_ref; mr; mr = mr.next) 
     1057            len++; 
     1058        _moduleinfo_array = new ModuleInfo[len]; 
     1059        len = 0; 
     1060        for (mr = _Dmodule_ref; mr; mr = mr.next) 
     1061        {   _moduleinfo_array[len] = mr.mod; 
     1062            len++; 
     1063        } 
     1064    } 
     1065 
     1066    version (Win32) 
     1067    { 
     1068        // Ensure module destructors also get called on program termination 
     1069        //_fatexit(&_STD_moduleDtor);