From 3aa65efac3bd2ec577599b17062a8eec569eda9d Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Sun, 1 Jun 2014 18:53:55 +0200 Subject: [PATCH] add TypeInfo to GC calls --- src/core/memory.d | 49 +++++++++++++++++++++++++++++----------------- src/gc/gc.d | 34 ++++++++++++++++---------------- src/gc/proxy.d | 50 +++++++++++++++++++++++------------------------ src/gcstub/gc.d | 42 ++++++++++++++++++++------------------- src/rt/lifetime.d | 6 +++--- 5 files changed, 98 insertions(+), 83 deletions(-) diff --git a/src/core/memory.d b/src/core/memory.d index 0c2f6ddcf36..836183aa0f2 100644 --- a/src/core/memory.d +++ b/src/core/memory.d @@ -95,11 +95,11 @@ private extern (C) uint gc_setAttr( void* p, uint a ) pure nothrow; extern (C) uint gc_clrAttr( void* p, uint a ) pure nothrow; - extern (C) void* gc_malloc( size_t sz, uint ba = 0 ) pure nothrow; - extern (C) void* gc_calloc( size_t sz, uint ba = 0 ) pure nothrow; - extern (C) BlkInfo_ gc_qalloc( size_t sz, uint ba = 0 ) pure nothrow; - extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0 ) pure nothrow; - extern (C) size_t gc_extend( void* p, size_t mx, size_t sz ) pure nothrow; + extern (C) void* gc_malloc( size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow; + extern (C) void* gc_calloc( size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow; + extern (C) BlkInfo_ gc_qalloc( size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow; + extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo = null ) pure nothrow; + extern (C) size_t gc_extend( void* p, size_t mx, size_t sz, const TypeInfo = null ) pure nothrow; extern (C) size_t gc_reserve( size_t sz ) nothrow; extern (C) void gc_free( void* p ) pure nothrow; @@ -116,7 +116,7 @@ private extern (C) BlkInfo_ gc_query( void* p ) pure nothrow; extern (C) void gc_addRoot( in void* p ) nothrow; - extern (C) void gc_addRange( in void* p, size_t sz ) nothrow; + extern (C) void gc_addRange( in void* p, size_t sz, const TypeInfo ti = null ) nothrow; extern (C) void gc_removeRoot( in void* p ) nothrow; extern (C) void gc_removeRange( in void* p ) nothrow; @@ -325,6 +325,8 @@ struct GC * Params: * sz = The desired allocation size in bytes. * ba = A bitmask of the attributes to set on this block. + * ti = TypeInfo to describe the memory. The GC might use this information + * to improve scanning for pointers or to call finalizers. * * Returns: * A reference to the allocated memory or null if insufficient memory @@ -333,9 +335,9 @@ struct GC * Throws: * OutOfMemoryError on allocation failure. */ - static void* malloc( size_t sz, uint ba = 0 ) pure nothrow + static void* malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow { - return gc_malloc( sz, ba ); + return gc_malloc( sz, ba, ti ); } @@ -349,6 +351,8 @@ struct GC * Params: * sz = The desired allocation size in bytes. * ba = A bitmask of the attributes to set on this block. + * ti = TypeInfo to describe the memory. The GC might use this information + * to improve scanning for pointers or to call finalizers. * * Returns: * Information regarding the allocated memory block or BlkInfo.init on @@ -357,9 +361,9 @@ struct GC * Throws: * OutOfMemoryError on allocation failure. */ - static BlkInfo qalloc( size_t sz, uint ba = 0 ) pure nothrow + static BlkInfo qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow { - return gc_qalloc( sz, ba ); + return gc_qalloc( sz, ba, ti ); } @@ -374,6 +378,8 @@ struct GC * Params: * sz = The desired allocation size in bytes. * ba = A bitmask of the attributes to set on this block. + * ti = TypeInfo to describe the memory. The GC might use this information + * to improve scanning for pointers or to call finalizers. * * Returns: * A reference to the allocated memory or null if insufficient memory @@ -382,9 +388,9 @@ struct GC * Throws: * OutOfMemoryError on allocation failure. */ - static void* calloc( size_t sz, uint ba = 0 ) pure nothrow + static void* calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow { - return gc_calloc( sz, ba ); + return gc_calloc( sz, ba, ti ); } @@ -412,6 +418,8 @@ struct GC * p = A pointer to the root of a valid memory block or to null. * sz = The desired allocation size in bytes. * ba = A bitmask of the attributes to set on this block. + * ti = TypeInfo to describe the memory. The GC might use this information + * to improve scanning for pointers or to call finalizers. * * Returns: * A reference to the allocated memory on success or null if sz is @@ -420,9 +428,9 @@ struct GC * Throws: * OutOfMemoryError on allocation failure. */ - static void* realloc( void* p, size_t sz, uint ba = 0 ) pure nothrow + static void* realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow { - return gc_realloc( p, sz, ba ); + return gc_realloc( p, sz, ba, ti ); } @@ -437,6 +445,9 @@ struct GC * p = A pointer to the root of a valid memory block or to null. * mx = The minimum extension size in bytes. * sz = The desired extension size in bytes. + * ti = TypeInfo to describe the full memory block. The GC might use + * this information to improve scanning for pointers or to + * call finalizers. * * Returns: * The size in bytes of the extended memory block referenced by p or zero @@ -448,9 +459,9 @@ struct GC * as an indicator of success. $(LREF capacity) should be used to * retrieve actual useable slice capacity. */ - static size_t extend( void* p, size_t mx, size_t sz ) pure nothrow + static size_t extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) pure nothrow { - return gc_extend( p, mx, sz ); + return gc_extend( p, mx, sz, ti ); } /// Standard extending unittest @@ -685,6 +696,8 @@ struct GC * p = A pointer to a valid memory address or to null. * sz = The size in bytes of the block to add. If sz is zero then the * no operation will occur. If p is null then sz must be zero. + * ti = TypeInfo to describe the memory. The GC might use this information + * to improve scanning for pointers or to call finalizers * * Example: * --- @@ -699,9 +712,9 @@ struct GC * // rawMemory will be recognized on collection. * --- */ - static void addRange( in void* p, size_t sz ) nothrow /* FIXME pure */ + static void addRange( in void* p, size_t sz, const TypeInfo ti = null ) nothrow /* FIXME pure */ { - gc_addRange( p, sz ); + gc_addRange( p, sz, ti ); } diff --git a/src/gc/gc.d b/src/gc/gc.d index 501bb83e0e2..96e9b6210dd 100644 --- a/src/gc/gc.d +++ b/src/gc/gc.d @@ -394,7 +394,7 @@ class GC /** * */ - void *malloc(size_t size, uint bits = 0, size_t *alloc_size = null) nothrow + void *malloc(size_t size, uint bits = 0, size_t *alloc_size = null, const TypeInfo ti = null) nothrow { if (!size) { @@ -412,7 +412,7 @@ class GC // when allocating. { gcLock.lock(); - p = mallocNoSync(size, bits, alloc_size); + p = mallocNoSync(size, bits, alloc_size, ti); gcLock.unlock(); } @@ -428,7 +428,7 @@ class GC // // // - private void *mallocNoSync(size_t size, uint bits = 0, size_t *alloc_size = null) nothrow + private void *mallocNoSync(size_t size, uint bits = 0, size_t *alloc_size = null, const TypeInfo ti = null) nothrow { assert(size != 0); @@ -519,7 +519,7 @@ class GC /** * */ - void *calloc(size_t size, uint bits = 0, size_t *alloc_size = null) nothrow + void *calloc(size_t size, uint bits = 0, size_t *alloc_size = null, const TypeInfo ti = null) nothrow { if (!size) { @@ -537,7 +537,7 @@ class GC // when allocating. { gcLock.lock(); - p = mallocNoSync(size, bits, alloc_size); + p = mallocNoSync(size, bits, alloc_size, ti); gcLock.unlock(); } @@ -553,7 +553,7 @@ class GC /** * */ - void *realloc(void *p, size_t size, uint bits = 0, size_t *alloc_size = null) nothrow + void *realloc(void *p, size_t size, uint bits = 0, size_t *alloc_size = null, const TypeInfo ti = null) nothrow { size_t localAllocSize = void; auto oldp = p; @@ -564,7 +564,7 @@ class GC // when allocating. { gcLock.lock(); - p = reallocNoSync(p, size, bits, alloc_size); + p = reallocNoSync(p, size, bits, alloc_size, ti); gcLock.unlock(); } @@ -580,7 +580,7 @@ class GC // // // - private void *reallocNoSync(void *p, size_t size, uint bits = 0, size_t *alloc_size = null) nothrow + private void *reallocNoSync(void *p, size_t size, uint bits = 0, size_t *alloc_size = null, const TypeInfo ti = null) nothrow { if (gcx.running) onInvalidMemoryOperationError(); @@ -595,7 +595,7 @@ class GC } else if (!p) { - p = mallocNoSync(size, bits, alloc_size); + p = mallocNoSync(size, bits, alloc_size, ti); } else { void *p2; @@ -627,7 +627,7 @@ class GC } } } - p2 = mallocNoSync(size, bits, alloc_size); + p2 = mallocNoSync(size, bits, alloc_size, ti); if (psize < size) size = psize; //debug(PRINTF) printf("\tcopying %d bytes\n",size); @@ -694,7 +694,7 @@ class GC bits = gcx.getBits(pool, biti); } } - p2 = mallocNoSync(size, bits, alloc_size); + p2 = mallocNoSync(size, bits, alloc_size, ti); if (psize < size) size = psize; //debug(PRINTF) printf("\tcopying %d bytes\n",size); @@ -718,10 +718,10 @@ class GC * 0 if could not extend p, * total size of entire memory block if successful. */ - size_t extend(void* p, size_t minsize, size_t maxsize) nothrow + size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti = null) nothrow { gcLock.lock(); - auto rc = extendNoSync(p, minsize, maxsize); + auto rc = extendNoSync(p, minsize, maxsize, ti); gcLock.unlock(); return rc; } @@ -730,7 +730,7 @@ class GC // // // - private size_t extendNoSync(void* p, size_t minsize, size_t maxsize) nothrow + private size_t extendNoSync(void* p, size_t minsize, size_t maxsize, const TypeInfo ti = null) nothrow in { assert(minsize <= maxsize); @@ -1111,7 +1111,7 @@ class GC /** * add range to scan for roots */ - void addRange(void *p, size_t sz) nothrow + void addRange(void *p, size_t sz, const TypeInfo ti = null) nothrow { if (!p || !sz) { @@ -1121,7 +1121,7 @@ class GC //debug(PRINTF) printf("+GC.addRange(p = %p, sz = 0x%zx), p + sz = %p\n", p, sz, p + sz); gcLock.lock(); - gcx.addRange(p, p + sz); + gcx.addRange(p, p + sz, ti); gcLock.unlock(); //debug(PRINTF) printf("-GC.addRange()\n"); @@ -1494,7 +1494,7 @@ struct Gcx /** * */ - void addRange(void *pbot, void *ptop) nothrow + void addRange(void *pbot, void *ptop, const TypeInfo ti) nothrow { //debug(PRINTF) printf("Thread %x ", pthread_self()); debug(PRINTF) printf("%p.Gcx::addRange(%p, %p)\n", &this, pbot, ptop); diff --git a/src/gc/proxy.d b/src/gc/proxy.d index 1b477a4b178..f7919a83cc8 100644 --- a/src/gc/proxy.d +++ b/src/gc/proxy.d @@ -48,11 +48,11 @@ private uint function(void*, uint) gc_setAttr; uint function(void*, uint) gc_clrAttr; - void* function(size_t, uint) gc_malloc; - BlkInfo function(size_t, uint) gc_qalloc; - void* function(size_t, uint) gc_calloc; - void* function(void*, size_t, uint ba) gc_realloc; - size_t function(void*, size_t, size_t) gc_extend; + void* function(size_t, uint, const TypeInfo) gc_malloc; + BlkInfo function(size_t, uint, const TypeInfo) gc_qalloc; + void* function(size_t, uint, const TypeInfo) gc_calloc; + void* function(void*, size_t, uint ba, const TypeInfo) gc_realloc; + size_t function(void*, size_t, size_t, const TypeInfo) gc_extend; size_t function(size_t) gc_reserve; void function(void*) gc_free; @@ -62,7 +62,7 @@ private BlkInfo function(void*) gc_query; void function(void*) gc_addRoot; - void function(void*, size_t) gc_addRange; + void function(void*, size_t, const TypeInfo ti) gc_addRange; void function(void*) gc_removeRoot; void function(void*) gc_removeRange; @@ -202,44 +202,44 @@ extern (C) return proxy.gc_clrAttr( p, a ); } - void* gc_malloc( size_t sz, uint ba = 0 ) nothrow + void* gc_malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow { if( proxy is null ) - return _gc.malloc( sz, ba ); - return proxy.gc_malloc( sz, ba ); + return _gc.malloc( sz, ba, null, ti ); + return proxy.gc_malloc( sz, ba, ti ); } - BlkInfo gc_qalloc( size_t sz, uint ba = 0 ) nothrow + BlkInfo gc_qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow { if( proxy is null ) { BlkInfo retval; - retval.base = _gc.malloc( sz, ba, &retval.size ); + retval.base = _gc.malloc( sz, ba, &retval.size, ti ); retval.attr = ba; return retval; } - return proxy.gc_qalloc( sz, ba ); + return proxy.gc_qalloc( sz, ba, ti ); } - void* gc_calloc( size_t sz, uint ba = 0 ) nothrow + void* gc_calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow { if( proxy is null ) - return _gc.calloc( sz, ba ); - return proxy.gc_calloc( sz, ba ); + return _gc.calloc( sz, ba, null, ti ); + return proxy.gc_calloc( sz, ba, ti ); } - void* gc_realloc( void* p, size_t sz, uint ba = 0 ) nothrow + void* gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow { if( proxy is null ) - return _gc.realloc( p, sz, ba ); - return proxy.gc_realloc( p, sz, ba ); + return _gc.realloc( p, sz, ba, null, ti ); + return proxy.gc_realloc( p, sz, ba, ti ); } - size_t gc_extend( void* p, size_t mx, size_t sz ) nothrow + size_t gc_extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) nothrow { if( proxy is null ) - return _gc.extend( p, mx, sz ); - return proxy.gc_extend( p, mx, sz ); + return _gc.extend( p, mx, sz, ti ); + return proxy.gc_extend( p, mx, sz,ti ); } size_t gc_reserve( size_t sz ) nothrow @@ -300,11 +300,11 @@ extern (C) return proxy.gc_addRoot( p ); } - void gc_addRange( void* p, size_t sz ) nothrow + void gc_addRange( void* p, size_t sz, const TypeInfo ti = null ) nothrow { if( proxy is null ) - return _gc.addRange( p, sz ); - return proxy.gc_addRange( p, sz ); + return _gc.addRange( p, sz, ti ); + return proxy.gc_addRange( p, sz, ti ); } void gc_removeRoot( void* p ) nothrow @@ -346,7 +346,7 @@ extern (C) proxy.gc_addRoot( r ); foreach (r; _gc.rangeIter) - proxy.gc_addRange( r.pbot, r.ptop - r.pbot ); + proxy.gc_addRange( r.pbot, r.ptop - r.pbot, null ); } void gc_clrProxy() diff --git a/src/gcstub/gc.d b/src/gcstub/gc.d index f19721922bb..a4d52a4fc87 100644 --- a/src/gcstub/gc.d +++ b/src/gcstub/gc.d @@ -47,7 +47,7 @@ private } extern (C) void thread_init(); - extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow; /* dmd @@@BUG11461@@@ */ + extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow; /* dmd @@@BUG11461@@@ */ struct Proxy { @@ -60,11 +60,11 @@ private extern (C) uint function(void*, uint) gc_setAttr; extern (C) uint function(void*, uint) gc_clrAttr; - extern (C) void* function(size_t, uint) gc_malloc; - extern (C) BlkInfo function(size_t, uint) gc_qalloc; - extern (C) void* function(size_t, uint) gc_calloc; - extern (C) void* function(void*, size_t, uint ba) gc_realloc; - extern (C) size_t function(void*, size_t, size_t) gc_extend; + extern (C) void* function(size_t, uint, const TypeInfo) gc_malloc; + extern (C) BlkInfo function(size_t, uint, const TypeInfo) gc_qalloc; + extern (C) void* function(size_t, uint, const TypeInfo) gc_calloc; + extern (C) void* function(void*, size_t, uint ba, const TypeInfo) gc_realloc; + extern (C) size_t function(void*, size_t, size_t, const TypeInfo) gc_extend; extern (C) size_t function(size_t) gc_reserve; extern (C) void function(void*) gc_free; @@ -74,7 +74,7 @@ private extern (C) BlkInfo function(void*) gc_query; extern (C) void function(void*) gc_addRoot; - extern (C) void function(void*, size_t) gc_addRange; + extern (C) void function(void*, size_t, const TypeInfo ti) gc_addRange; extern (C) void function(void*) gc_removeRoot; extern (C) void function(void*) gc_removeRange; @@ -121,6 +121,7 @@ private { void* pos; size_t len; + TypeInfo ti; // should be tail const, but doesn't exist for references } __gshared Range* ranges = null; @@ -190,7 +191,7 @@ extern (C) uint gc_clrAttr( void* p, uint a ) return proxy.gc_clrAttr( p, a ); } -extern (C) void* gc_malloc( size_t sz, uint ba = 0 ) +extern (C) void* gc_malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) { if( proxy is null ) { @@ -200,10 +201,10 @@ extern (C) void* gc_malloc( size_t sz, uint ba = 0 ) onOutOfMemoryError(); return p; } - return proxy.gc_malloc( sz, ba ); + return proxy.gc_malloc( sz, ba, ti ); } -extern (C) BlkInfo gc_qalloc( size_t sz, uint ba = 0 ) +extern (C) BlkInfo gc_qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) { if( proxy is null ) { @@ -213,10 +214,10 @@ extern (C) BlkInfo gc_qalloc( size_t sz, uint ba = 0 ) retval.attr = ba; return retval; } - return proxy.gc_qalloc( sz, ba ); + return proxy.gc_qalloc( sz, ba, ti ); } -extern (C) void* gc_calloc( size_t sz, uint ba = 0 ) +extern (C) void* gc_calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) { if( proxy is null ) { @@ -226,10 +227,10 @@ extern (C) void* gc_calloc( size_t sz, uint ba = 0 ) onOutOfMemoryError(); return p; } - return proxy.gc_calloc( sz, ba ); + return proxy.gc_calloc( sz, ba, ti ); } -extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0 ) +extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) { if( proxy is null ) { @@ -239,14 +240,14 @@ extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0 ) onOutOfMemoryError(); return p; } - return proxy.gc_realloc( p, sz, ba ); + return proxy.gc_realloc( p, sz, ba, ti ); } -extern (C) size_t gc_extend( void* p, size_t mx, size_t sz ) +extern (C) size_t gc_extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) { if( proxy is null ) return 0; - return proxy.gc_extend( p, mx, sz ); + return proxy.gc_extend( p, mx, sz, ti ); } extern (C) size_t gc_reserve( size_t sz ) @@ -299,7 +300,7 @@ extern (C) void gc_addRoot( void* p ) return proxy.gc_addRoot( p ); } -extern (C) void gc_addRange( void* p, size_t sz ) +extern (C) void gc_addRange( void* p, size_t sz, const TypeInfo ti = null ) { //printf("gcstub::gc_addRange() proxy = %p\n", proxy); if( proxy is null ) @@ -310,11 +311,12 @@ extern (C) void gc_addRange( void* p, size_t sz ) onOutOfMemoryError(); r[nranges].pos = p; r[nranges].len = sz; + r[nranges].ti = cast()ti; ranges = r; ++nranges; return; } - return proxy.gc_addRange( p, sz ); + return proxy.gc_addRange( p, sz, ti ); } extern (C) void gc_removeRoot( void *p ) @@ -366,7 +368,7 @@ export extern (C) void gc_setProxy( Proxy* p ) foreach( r; roots[0 .. nroots] ) proxy.gc_addRoot( r ); foreach( r; ranges[0 .. nranges] ) - proxy.gc_addRange( r.pos, r.len ); + proxy.gc_addRange( r.pos, r.len, r.ti ); } export extern (C) void gc_clrProxy() diff --git a/src/rt/lifetime.d b/src/rt/lifetime.d index 699a5af91be..4402150d600 100644 --- a/src/rt/lifetime.d +++ b/src/rt/lifetime.d @@ -79,7 +79,7 @@ extern (C) Object _d_newclass(const ClassInfo ci) attr &= ~BlkAttr.FINALIZE; if (ci.m_flags & TypeInfo_Class.ClassFlags.noPointers) attr |= BlkAttr.NO_SCAN; - p = GC.malloc(ci.init.length, attr); + p = GC.malloc(ci.init.length, attr, ci); debug(PRINTF) printf(" p = %p\n", p); } @@ -1001,7 +1001,7 @@ extern (C) void* _d_newitemT(TypeInfo ti) else {*/ // allocate a block to hold this item - auto ptr = GC.malloc(size, !(ti.next.flags & 1) ? BlkAttr.NO_SCAN : 0); + auto ptr = GC.malloc(size, !(ti.next.flags & 1) ? BlkAttr.NO_SCAN : 0, ti); debug(PRINTF) printf(" p = %p\n", ptr); if(size == ubyte.sizeof) *cast(ubyte*)ptr = 0; @@ -1032,7 +1032,7 @@ extern (C) void* _d_newitemiT(TypeInfo ti) auto isize = initializer.length; auto q = initializer.ptr; - auto ptr = GC.malloc(size, !(ti.next.flags & 1) ? BlkAttr.NO_SCAN : 0); + auto ptr = GC.malloc(size, !(ti.next.flags & 1) ? BlkAttr.NO_SCAN : 0, ti); debug(PRINTF) printf(" p = %p\n", ptr); if (isize == 1) *cast(ubyte*)ptr = *cast(ubyte*)q;