Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
/ druntime Public archive
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mak/SRCS
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ SRCS=\
src\gc\os.d \
src\gc\pooltable.d \
src\gc\proxy.d \
src\gc\stats.d \
src\gc\impl\conservative\gc.d \
src\gc\impl\manual\gc.d \
src\gc\impl\proto\gc.d \
Expand Down
56 changes: 28 additions & 28 deletions src/gc/impl/conservative/gc.d
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import gc.bits;
import gc.os;
import gc.config;
import gc.gcinterface;
import gc.stats;

import rt.util.container.treap;

Expand Down Expand Up @@ -110,6 +111,8 @@ __gshared Duration maxPauseTime;
__gshared size_t numCollections;
__gshared size_t maxPoolMemory;

__gshared GCStatsTracker statsTracker;

__gshared long numMallocs;
__gshared long numFrees;
__gshared long numReallocs;
Expand Down Expand Up @@ -596,7 +599,8 @@ class ConservativeGC : GC
{
if (!size)
{ if (p)
{ freeNoSync(p);
{
freeNoSync(p);
p = null;
}
alloc_size = 0;
Expand Down Expand Up @@ -693,6 +697,8 @@ class ConservativeGC : GC
pool.setBits(biti, bits);
}
alloc_size = newsz * PAGESIZE;
statsTracker.freed(psize);
statsTracker.allocated(alloc_size);
return p;
}

Expand Down Expand Up @@ -721,6 +727,9 @@ class ConservativeGC : GC
//debug(PRINTF) printf("\tcopying %d bytes\n",size);
memcpy(p2, p, size);
p = p2;

statsTracker.freed(psize);
statsTracker.allocated(size);
}
else
alloc_size = psize;
Expand Down Expand Up @@ -787,6 +796,7 @@ class ConservativeGC : GC
lpool.updateOffsets(pagenum);
lpool.freepages -= sz;
gcx.usedLargePages += sz;
statsTracker.allocated(sz * PAGESIZE);
return (psz + sz) * PAGESIZE;
}
}
Expand Down Expand Up @@ -873,6 +883,7 @@ class ConservativeGC : GC
size_t npages = lpool.bPageOffsets[pagenum];
debug (MEMSTOMP) memset(p, 0xF2, npages * PAGESIZE);
lpool.freePages(pagenum, npages);
statsTracker.freed(npages * PAGESIZE);
}
else
{ // Add to free list
Expand Down Expand Up @@ -1200,33 +1211,9 @@ class ConservativeGC : GC
return ret;
}


//
//
//
private void getStatsNoSync(out core.memory.GC.Stats stats) nothrow
{
foreach (pool; gcx.pooltable[0 .. gcx.npools])
{
foreach (bin; pool.pagetable[0 .. pool.npages])
{
if (bin == B_FREE)
stats.freeSize += PAGESIZE;
else
stats.usedSize += PAGESIZE;
}
}

size_t freeListSize;
foreach (n; 0 .. B_PAGE)
{
immutable sz = binsize[n];
for (List *list = gcx.bucket[n]; list; list = list.next)
freeListSize += sz;
}

stats.usedSize -= freeListSize;
stats.freeSize += freeListSize;
stats = statsTracker.stats;
}
}

Expand Down Expand Up @@ -1380,6 +1367,7 @@ struct Gcx
roots.removeAll();
ranges.removeAll();
toscan.reset();
statsTracker.reset();
}


Expand Down Expand Up @@ -1659,6 +1647,7 @@ struct Gcx
{
debug(PRINTF) printFreeInfo(pool);
mappedPages -= pool.npages;
statsTracker.removed(pool.npages * PAGESIZE);
pool.Dtor();
cstdlib.free(pool);
}
Expand All @@ -1673,8 +1662,12 @@ struct Gcx

void* alloc(size_t size, ref size_t alloc_size, uint bits) nothrow
{
return size <= 2048 ? smallAlloc(binTable[size], alloc_size, bits)
auto p = size <= 2048 ? smallAlloc(binTable[size], alloc_size, bits)
: bigAlloc(size, alloc_size, bits);

statsTracker.allocated(alloc_size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this function is performance critical, being about to turn this statement into a no-op is important.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean, pragma(inline)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By no-op I mean no code is generated for the statement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am afraid it is not possible - GC.stats is supposed to work for every program at any moment of time, it is not controlled by version or runtime flag.

Though considering how extremely expensive call to alloc is, I am not sure I understand concern about 2 extra integer additions either.


return p;
}

void* smallAlloc(Bins bin, ref size_t alloc_size, uint bits) nothrow
Expand Down Expand Up @@ -1859,6 +1852,7 @@ struct Gcx
}

mappedPages += npages;
statsTracker.added(npages * PAGESIZE);

if (config.profile)
{
Expand Down Expand Up @@ -2306,6 +2300,10 @@ struct Gcx
assert(freedLargePages <= usedLargePages);
usedLargePages -= freedLargePages;
debug(COLLECT_PRINTF) printf("\tfree'd %u bytes, %u pages from %u pools\n", freed, freedLargePages, npools);

statsTracker.freed(freed);
statsTracker.freed(freedLargePages);

return freedLargePages;
}

Expand Down Expand Up @@ -2456,7 +2454,8 @@ struct Gcx

updateCollectThresholds();

return freedLargePages + freedSmallPages;
size_t freed = freedLargePages + freedSmallPages;
return freed;
}

/**
Expand Down Expand Up @@ -3107,6 +3106,7 @@ struct LargeObjectPool
break;
debug (MEMSTOMP) memset(baseAddr + pn * PAGESIZE, 0xF3, n * PAGESIZE);
freePages(pn, n);
statsTracker.freed(n * PAGESIZE);
}
}
}
Expand Down
73 changes: 73 additions & 0 deletions src/gc/stats.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* Utility to simplify calculating `core.memory.GC.Stats`
*
* Copyright: D Language Foundation, 2018
* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Source: $(DRUNTIMESRC gc/stats.d)
*/
module gc.stats;

/**
Embeds `GC.Stats` instance and adds few simple wrapper methods
to maniplate it while doing some sanity checks.
*/
package(gc) struct GCStatsTracker
{
@nogc nothrow @safe pure:

import core.memory;
GC.Stats stats;

/**
Record new memory added to the GC pool from OS
Params:
bytes = amount of memory
*/
void added(size_t bytes)
{
this.stats.freeSize += bytes;
}

/**
Record memory returned from the GC pool to OS
Params:
bytes = amount of memory
*/
void removed(size_t bytes)
{
assert(this.stats.freeSize >= bytes);
this.stats.freeSize -= bytes;
}

/**
Record new chunk of allocations from the GC pool
Params:
bytes = amount of memory
*/
void allocated(size_t bytes)
{
assert(this.stats.freeSize >= bytes);
this.stats.freeSize -= bytes;
this.stats.usedSize += bytes;
}

/**
Record return of allocated memory to the GC pool
Params:
bytes = amount of memory
*/
void freed(size_t bytes)
{
assert(this.stats.usedSize >= bytes);
this.stats.freeSize += bytes;
this.stats.usedSize -= bytes;
}

/**
Reset stored GC stats
*/
void reset()
{
this.stats = this.stats.init;
}
}