@@ -156,7 +156,7 @@ debug (LOGGING)
156156
157157 void print () nothrow
158158 {
159- printf(" p = %p, size = %zd , parent = %p " , p, size, parent);
159+ printf(" p = %p, size = %lld , parent = %p " , p, cast ( ulong ) size, parent);
160160 if (file)
161161 {
162162 printf(" %s(%u)" , file, line);
@@ -172,14 +172,14 @@ debug (LOGGING)
172172 size_t allocdim;
173173 Log * data;
174174
175- void Dtor () nothrow
175+ void Dtor () nothrow @nogc
176176 {
177177 if (data)
178178 cstdlib.free(data);
179179 data = null ;
180180 }
181181
182- void reserve (size_t nentries) nothrow
182+ void reserve (size_t nentries) nothrow @nogc
183183 {
184184 assert (dim <= allocdim);
185185 if (allocdim - dim < nentries)
@@ -206,20 +206,20 @@ debug (LOGGING)
206206 }
207207
208208
209- void push (Log log) nothrow
209+ void push (Log log) nothrow @nogc
210210 {
211211 reserve (1 );
212212 data[dim++ ] = log;
213213 }
214214
215- void remove (size_t i) nothrow
215+ void remove (size_t i) nothrow @nogc
216216 {
217217 memmove(data + i, data + i + 1 , (dim - i) * Log .sizeof);
218218 dim-- ;
219219 }
220220
221221
222- size_t find (void * p) nothrow
222+ size_t find (void * p) nothrow @nogc
223223 {
224224 for (size_t i = 0 ; i < dim; i++ )
225225 {
@@ -230,9 +230,10 @@ debug (LOGGING)
230230 }
231231
232232
233- void copy (LogArray * from) nothrow
233+ void copy (LogArray * from) nothrow @nogc
234234 {
235- reserve (from.dim - dim);
235+ if (allocdim < from.dim)
236+ reserve (from.dim - dim);
236237 assert (from.dim <= allocdim);
237238 memcpy(data, from.data, from.dim * Log .sizeof);
238239 dim = from.dim;
@@ -652,12 +653,11 @@ class ConservativeGC : GC
652653 auto lpool = cast (LargeObjectPool* ) pool;
653654 auto paligned = cast (void * )(cast (size_t )p & ~ (PAGESIZE - 1 )); // abused by std.file.readImpl
654655 auto psz = lpool.getPages(paligned); // get allocated size
656+ psize = psz * PAGESIZE ;
655657
656658 if (size <= PAGESIZE / 2 )
657- {
658- psize = psz * PAGESIZE ;
659659 goto Lmalloc; // switching from large object pool to small object pool
660- }
660+
661661 auto newsz = lpool.numPages(size);
662662 if (newsz == psz)
663663 {
@@ -1323,8 +1323,8 @@ struct Gcx
13231323 Treap! Root roots;
13241324 Treap! Range ranges;
13251325
1326- bool log; // turn on logging
13271326 debug (INVARIANT ) bool initialized;
1327+ debug (INVARIANT ) bool inCollection;
13281328 uint disabled; // turn off collections if >0
13291329
13301330 import gc.pooltable;
@@ -1427,14 +1427,16 @@ struct Gcx
14271427 // printf("Gcx.invariant(): this = %p\n", &this);
14281428 pooltable.Invariant();
14291429
1430- rangesLock.lock();
1430+ if (! inCollection)
1431+ (cast ()rangesLock).lock();
14311432 foreach (range; ranges)
14321433 {
14331434 assert (range.pbot);
14341435 assert (range.ptop);
14351436 assert (range.pbot <= range.ptop);
14361437 }
1437- rangesLock.unlock();
1438+ if (! inCollection)
1439+ (cast ()rangesLock).unlock();
14381440
14391441 for (size_t i = 0 ; i < B_NUMSMALL ; i++ )
14401442 {
@@ -2404,8 +2406,10 @@ struct Gcx
24042406 // lock roots and ranges around suspending threads b/c they're not reentrant safe
24052407 rangesLock.lock();
24062408 rootsLock.lock();
2409+ debug (INVARIANT ) inCollection = true ;
24072410 scope (exit)
24082411 {
2412+ debug (INVARIANT ) inCollection = false ;
24092413 rangesLock.unlock();
24102414 rootsLock.unlock();
24112415 }
@@ -2996,15 +3000,6 @@ struct Pool
29963000 debug (INVARIANT )
29973001 invariant ()
29983002 {
2999- // mark.Invariant();
3000- // scan.Invariant();
3001- // freebits.Invariant();
3002- // finals.Invariant();
3003- // structFinals.Invariant();
3004- // noscan.Invariant();
3005- // appendable.Invariant();
3006- // nointerior.Invariant();
3007-
30083003 if (baseAddr)
30093004 {
30103005 // if (baseAddr + npages * PAGESIZE != topAddr)
@@ -3231,13 +3226,13 @@ struct LargeObjectPool
32313226 continue ;
32323227
32333228 auto p = sentinel_add(baseAddr + pn * PAGESIZE );
3234- size_t size = getSize(pn) - SENTINEL_EXTRA ;
3229+ size_t size = sentinel_size(p, getSize(pn)) ;
32353230 uint attr = getBits(biti);
32363231
32373232 if (! rt_hasFinalizerInSegment(p, size, attr, segment))
32383233 continue ;
32393234
3240- rt_finalizeFromGC(p, sentinel_size (p, size) , attr);
3235+ rt_finalizeFromGC(p, size, attr);
32413236
32423237 clrBits(biti, ~ BlkAttr.NONE );
32433238
@@ -3335,11 +3330,11 @@ struct SmallObjectPool
33353330
33363331 auto q = sentinel_add(p);
33373332 uint attr = getBits(biti);
3338-
3339- if (! rt_hasFinalizerInSegment(q, size , attr, segment))
3333+ const ssize = sentinel_size(q, size);
3334+ if (! rt_hasFinalizerInSegment(q, ssize , attr, segment))
33403335 continue ;
33413336
3342- rt_finalizeFromGC(q, sentinel_size (q, size) , attr);
3337+ rt_finalizeFromGC(q, ssize , attr);
33433338
33443339 freeBits = true ;
33453340 toFree.set(i);
@@ -3542,11 +3537,11 @@ debug (MEMSTOMP)
35423537unittest
35433538{
35443539 import core.memory ;
3545- auto p = cast (uint * )GC .malloc(uint .sizeof* 3 );
3540+ auto p = cast (uint * )GC .malloc(uint .sizeof* 5 );
35463541 assert (* p == 0xF0F0F0F0 );
35473542 p[2 ] = 0 ; // First two will be used for free list
35483543 GC .free(p);
3549- assert (p[2 ] == 0xF2F2F2F2 );
3544+ assert (p[4 ] == 0xF2F2F2F2 ); // skip List usage, for both 64-bit and 32-bit
35503545}
35513546
35523547debug (SENTINEL )
@@ -3619,6 +3614,7 @@ unittest
36193614
36203615// https://issues.dlang.org/show_bug.cgi?id=19281
36213616debug (SENTINEL ) {} else // cannot allow >= 4 GB with SENTINEL
3617+ debug (MEMSTOMP ) {} else // might take too long to actually touch the memory
36223618version (D_LP64 ) unittest
36233619{
36243620 static if (__traits(compiles, os_physical_mem))
0 commit comments