// Copyright (C) 2001-2006 by Digital Mars // All Rights Reserved // Written by Walter Bright // www.digitalmars.com // GC tester program import std.c.stdio; import std.c.stdlib; import std.c.string; import std.string; import gcstats; import std.gc; import gcx; import std.random; alias GC gc_t; //alias GC* gc_t; gc_t newGC() { version (all) { void* p; ClassInfo ci = GC.classinfo; p = std.c.stdlib.malloc(ci.init.length); (cast(byte*)p)[0 .. ci.init.length] = ci.init[]; return cast(GC)p; } else { return cast(gc_t)std.c.stdlib.calloc(1, GC.sizeof); } } void deleteGC(gc_t gc) { gc.Dtor(); std.c.stdlib.free(cast(void*)gc); } void printStats(gc_t gc) { GCStats stats; //gc.getStats(stats); printf("poolsize = x%x, usedsize = x%x, freelistsize = x%x, freeblocks = %d, pageblocks = %d\n", stats.poolsize, stats.usedsize, stats.freelistsize, stats.freeblocks, stats.pageblocks); } uint PERMUTE(uint key) { return key + 1; } void fill(void *p, uint key, uint size) { uint i; byte *q = cast(byte *)p; for (i = 0; i < size; i++) { key = PERMUTE(key); q[i] = cast(byte)key; } } void verify(void *p, uint key, uint size) { uint i; byte *q = cast(byte *)p; for (i = 0; i < size; i++) { key = PERMUTE(key); assert(q[i] == cast(byte)key); } } long desregs() { return strlen("foo"); } /* ---------------------------- */ void smoke() { gc_t gc; printf("--------------------------smoke()\n"); gc = newGC(); deleteGC(gc); printf("smoke.1\n"); gc = newGC(); gc.initialize(); deleteGC(gc); printf("smoke.2\n"); gc = newGC(); gc.initialize(); char *p = cast(char *)gc.malloc(10); assert(p); strcpy(p, "Hello!"); // char *p2 = gc.strdup(p); // printf("p2 = %x, '%s'\n", p2, p2); // int result = strcmp(p, p2); // assert(result == 0); // gc.strdup(p); printf("p = %x\n", p); p = null; gc.fullCollect(); printStats(gc); deleteGC(gc); } /* ---------------------------- */ void finalizer(void *p, bool dummy) { } void smoke2() { gc_t gc; int *p; int i; const int SMOKE2_SIZE = 100; int *foo[SMOKE2_SIZE]; printf("--------------------------smoke2()\n"); gc = newGC(); gc.initialize(); for (i = 0; i < SMOKE2_SIZE; i++) { p = cast(int *)gc.calloc(i + 1, 500); p[0] = i * 3; foo[i] = p; gc.setFinalizer(cast(void *)p, &finalizer); } for (i = 0; i < SMOKE2_SIZE; i += 2) { p = foo[i]; if (p[0] != i * 3) { printf("p = %x, i = %d, p[0] = %d\n", p, i, p[0]); //c.stdio.fflush(stdout); } assert(p[0] == i * 3); gc.free(p); } p = null; foo[] = null; gc.fullCollect(); printStats(gc); deleteGC(gc); } /* ---------------------------- */ void smoke3() { gc_t gc; int *p; int i; printf("--------------------------smoke3()\n"); gc = newGC(); gc.initialize(); // for (i = 0; i < 1000000; i++) for (i = 0; i < 1000; i++) { uint size = std.random.rand() % 2048; p = cast(int *)gc.malloc(size); memset(p, i, size); size = std.random.rand() % 2048; p = cast(int *)gc.realloc(p, size); memset(p, i + 1, size); } p = null; desregs(); gc.fullCollect(); printStats(gc); deleteGC(gc); } /* ---------------------------- */ void smoke4() { gc_t gc; int *p; int i; printf("--------------------------smoke4()\n"); gc = newGC(); gc.initialize(); for (i = 0; i < 80000; i++) { uint size = i; p = cast(int *)gc.malloc(size); memset(p, i, size); size = std.random.rand() % 2048; gc.check(p); p = cast(int *)gc.realloc(p, size); memset(p, i + 1, size); } p = null; desregs(); gc.fullCollect(); printStats(gc); deleteGC(gc); } /* ---------------------------- */ void smoke5(gc_t gc) { byte *p; int i; int j; const int SMOKE5_SIZE = 1000; byte *array[SMOKE5_SIZE]; uint offset[SMOKE5_SIZE]; printf("--------------------------smoke5()\n"); //printf("gc = %p\n", gc); //printf("gc = %p, gcx = %p, self = %x\n", gc, gc.gcx, gc.gcx.self); for (j = 0; j < 20; j++) { for (i = 0; i < 2000 /*4000*/; i++) { uint size = (std.random.rand() % 2048) + 1; uint index = std.random.rand() % SMOKE5_SIZE; //printf("index = %d, size = %d\n", index, size); p = array[index] - offset[index]; p = cast(byte *)gc.realloc(p, size); if (array[index]) { uint s; //printf("\tverify = %d\n", p[0]); s = offset[index]; if (size < s) s = size; verify(p, index, s); } array[index] = p; fill(p, index, size); offset[index] = std.random.rand() % size; array[index] += offset[index]; //printf("p[0] = %d\n", p[0]); } gc.fullCollect(); } p = null; array[] = null; gc.fullCollect(); printStats(gc); } /* ---------------------------- */ void test1() { printf("test1()\n"); char[] a=new char[0]; uint c = 200000; while (c--) a ~= 'x'; //printf("a = '%.*s'\n", a); printf("test1() done\n"); } /* ---------------------------- */ void test2() { char[] str; for (int i = 0; i < 10_000; i++) str = str ~ "ABCDEFGHIJKLMNOPQRST"; } /* ---------------------------- */ /* The Great Computer Language Shootout http://shootout.alioth.debian.org/ http://www.bagley.org/~doug/shootout/ converted to D by Dave Fladebo compile: dmd -O -inline -release hash.d */ void test3() { int n = 1000; char[32] str; int[char[]] X; for(int i = 1; i <= n; i++) { int len = sprintf(str.ptr,"%x",i); X[str[0..len].dup] = i; } int c; for(int i = n; i > 0; i--) { int len = sprintf(str.ptr,"%d",i); if(str[0..len] in X) c++; } printf("%d\n", c); } /* ---------------------------- */ void test4() { const int iters = 1_000_000; C[] c = new C[iters]; int i; for(i = 0; i < iters; i++) { c[i] = new C; delete c[i]; } printf("%d\n", i); } class C { int i, j, k; real l, m, n; } /* ---------------------------- */ /* The Computer Language Shootout Benchmarks http://shootout.alioth.debian.org/ contributed by Dave Fladebo compile: dmd -O -inline -release binarytrees.d */ int test5() { TreeNode* stretchTree, longLivedTree, tempTree; int depth, minDepth, maxDepth, stretchDepth, N = 1; minDepth = 4; maxDepth = (minDepth + 2) > N ? minDepth + 2 : N; stretchDepth = maxDepth + 1; stretchTree = TreeNode.BottomUpTree(0, stretchDepth); printf("stretch tree of depth %d\t check: %d\n", stretchDepth, stretchTree.ItemCheck); //TreeNode.DeleteTree(stretchTree); longLivedTree = TreeNode.BottomUpTree(0, maxDepth); for(depth = minDepth; depth <= maxDepth; depth += 2) { int check, iterations = 1 << (maxDepth - depth + minDepth); for(int i = 0; i < iterations; i++) { tempTree = TreeNode.BottomUpTree(i, depth); check += tempTree.ItemCheck; //TreeNode.DeleteTree(tempTree); tempTree = TreeNode.BottomUpTree(-i, depth); check += tempTree.ItemCheck; //TreeNode.DeleteTree(tempTree); } //printf(iterations * 2,"\t trees of depth ",depth,"\t check: ",check); } //writefln("long lived tree of depth ",maxDepth,"\t check: ",longLivedTree.ItemCheck); return 0; } struct TreeNode { public: static TreeNode* BottomUpTree(int item, int depth) { if(depth > 0) return TreeNode(item ,BottomUpTree(2 * item - 1, depth - 1) ,BottomUpTree(2 * item, depth - 1)); return TreeNode(item); } int ItemCheck() { if(left) return item + left.ItemCheck() - right.ItemCheck(); return item; } static void DeleteTree(TreeNode* tree) { if(tree.left) { DeleteTree(tree.left); DeleteTree(tree.right); } delete tree; } private: TreeNode* left, right; int item; static TreeNode* opCall(int item, TreeNode* left = null, TreeNode* right = null) { TreeNode* t = new TreeNode; t.left = left; t.right = right; t.item = item; return t; } //new(uint sz) //{ // return std.c.stdlib.malloc(sz); //} //delete(void* p) //{ // free(p); //} } /* ---------------------------- */ void test6() { printf("test6\n"); gc_t gc; gc = newGC(); gc.initialize(); auto p = gc.malloc(4096); assert(gc.capacity(p) == 4096); memset(p, 3, 4096); auto q = gc.realloc(p, 4096*4); assert(q == p); assert(gc.capacity(p) == 4096*4); memset(p, 4, 4096*4); q = gc.realloc(p, 4096*2); assert(q == p); assert(gc.capacity(p) == 4096*2); memset(p, 5, 4096*2); q = gc.realloc(p, 4096*2 + 1000); assert(q == p); assert(gc.capacity(p) == 4096*3); memset(p, 6, 4096*2 + 1000); q = gc.realloc(p, 4096*4); assert(q == p); assert(gc.capacity(p) == 4096*4); memset(p, 7, 4096*4); q = gc.realloc(p, 0); assert(q == null); assert(gc.capacity(p) == 0); gc.fullCollect(); deleteGC(gc); } /* ---------------------------- */ void test7() { printf("test7\n"); gc_t gc; gc = newGC(); gc.initialize(); auto p = gc.malloc(4096); assert(gc.capacity(p) == 4096); memset(p, 3, 4096); auto q = gc.extend(p, 4096, 4096*2); assert(q == 4096*2 || q == 4096*3); auto s = gc.malloc(4096); q = gc.extend(p, 4096, 4096); assert(q == 0); gc.fullCollect(); deleteGC(gc); } /* ---------------------------- */ int main(char[][] args) { test1(); test2(); test3(); test4(); test5(); test6(); test7(); gc_t gc; printf("GC test start\n"); gc = newGC(); printf("gc = %p\n", gc); gc.initialize(); smoke(); smoke2(); smoke3(); smoke4(); printf("gc = %p\n", gc); smoke5(gc); deleteGC(gc); printf("GC test success\n"); return EXIT_SUCCESS; }