Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
- remove StructFinalizers, preallocate FinalizeError
Browse files Browse the repository at this point in the history
- remove TypeInfo from gc.setAttr/setBita
- assumeSafeAppend now calls struct destructors, checks whether the array is really shrinked
- remove rt_ prefix from internal functions
- add tests
  • Loading branch information
rainers authored and Orvid committed Jan 13, 2015
1 parent afc057b commit 0b72987
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 143 deletions.
108 changes: 15 additions & 93 deletions src/core/exception.d
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,22 @@ unittest
*/
class FinalizeError : Error
{
ClassInfo info;
TypeInfo info;

@safe pure nothrow this( ClassInfo ci, Throwable next, string file = __FILE__, size_t line = __LINE__ )
@safe pure nothrow this( TypeInfo ci, Throwable next, string file = __FILE__, size_t line = __LINE__ )
{
this(ci, file, line, next);
}

@safe pure nothrow this( ClassInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
@safe pure nothrow this( TypeInfo ci, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
{
super( "Finalization error", file, line, next );
info = ci;
}

@safe override string toString() const
{
return "An exception was thrown while finalizing an instance of class " ~ info.name;
return "An exception was thrown while finalizing an instance of " ~ info.toString();
}
}

Expand Down Expand Up @@ -181,72 +181,6 @@ unittest
}
}

/**
* Thrown on struct finalize error.
*/
class StructFinalizeError : Error
{
TypeInfo_Struct info;

@safe pure nothrow this( TypeInfo_Struct si, Throwable next, string file = __FILE__, size_t line = __LINE__ )
{
this(si, file, line, next);
}

@safe pure nothrow this( TypeInfo_Struct si, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
{
super( "Struct finalization error", file, line, next );
info = si;
}

@safe override const string toString()
{
return "An exception was thrown while finalizing an instance of struct " ~ info.name;
}
}

unittest
{
TypeInfo_Struct info = new TypeInfo_Struct;
info.name = "testInfo";

{
auto fe = new StructFinalizeError(info);
assert(fe.file == __FILE__);
assert(fe.line == __LINE__ - 2);
assert(fe.next is null);
assert(fe.msg == "Struct finalization error");
assert(fe.info == info);
}

{
auto fe = new StructFinalizeError(info, new Exception("It's an Exception!"));
assert(fe.file == __FILE__);
assert(fe.line == __LINE__ - 2);
assert(fe.next !is null);
assert(fe.msg == "Struct finalization error");
assert(fe.info == info);
}

{
auto fe = new StructFinalizeError(info, "hello", 42);
assert(fe.file == "hello");
assert(fe.line == 42);
assert(fe.next is null);
assert(fe.msg == "Struct finalization error");
assert(fe.info == info);
}

{
auto fe = new StructFinalizeError(info, "hello", 42, new Exception("It's an Exception!"));
assert(fe.file == "hello");
assert(fe.line == 42);
assert(fe.next !is null);
assert(fe.msg == "Struct finalization error");
assert(fe.info == info);
}
}

/**
* Thrown on hidden function error.
*/
Expand Down Expand Up @@ -518,7 +452,6 @@ extern (C) void onUnittestErrorMsg( string file, size_t line, string msg ) nothr
// Internal Error Callbacks
///////////////////////////////////////////////////////////////////////////////


/**
* A callback for array bounds errors in D. A $(LREF RangeError) will be thrown.
*
Expand All @@ -539,35 +472,24 @@ extern (C) void onRangeError( string file = __FILE__, size_t line = __LINE__ ) @
* A callback for finalize errors in D. A $(LREF FinalizeError) will be thrown.
*
* Params:
* info = The ClassInfo instance for the object that failed finalization.
* info = The TypeInfo instance for the object that failed finalization.
* e = The exception thrown during finalization.
* file = The name of the file that signaled this error.
* line = The line number on which this error occurred.
*
* Throws:
* $(LREF FinalizeError).
*/
extern (C) void onFinalizeError( ClassInfo info, Throwable e, string file = __FILE__, size_t line = __LINE__ ) @safe pure nothrow
{
throw new FinalizeError( info, file, line, e );
}


/**
* A callback for struct finalize errors in D. A StructFinalizeError will be thrown.
*
* Params:
* info = The TypeInfo_Struct instance for the object that failed finalization.
* e = The exception thrown during finalization.
* file = The name of the file that signaled this error.
* line = The line number on which this error occurred.
*
* Throws:
* FinalizeError.
*/
extern (C) void onStructFinalizeError( TypeInfo_Struct info, Throwable e, string file = __FILE__, size_t line = __LINE__ ) @safe pure nothrow
{
throw new StructFinalizeError( info, file, line, e );
extern (C) void onFinalizeError( TypeInfo info, Throwable e, string file = __FILE__, size_t line = __LINE__ ) @trusted nothrow
{
// This error is thrown during a garbage collection, so no allocation must occur while
// generating this object. So we use a preallocated instance
__gshared FinalizeError err = new FinalizeError( null );
err.info = info;
err.next = e;
err.file = file;
err.line = line;
throw err;
}


Expand Down
32 changes: 10 additions & 22 deletions src/gc/gc.d
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ private
{
// to allow compilation of this module without access to the rt package,
// make these functions available from rt.lifetime
void rt_finalizeFromGC(void* p, size_t size, uint attr) nothrow;
int rt_hasFinalizerInSegment(void* p, size_t size, uint attr, in void[] segment) nothrow;
void rt_finalizeFromGC(void* p, size_t size, uint attr) nothrow;
int rt_hasFinalizerInSegment(void* p, size_t size, uint attr, in void[] segment) nothrow;

// Declared as an extern instead of importing core.exception
// to avoid inlining - see issue 13725.
Expand Down Expand Up @@ -471,7 +471,7 @@ class GC
//
//
//
private void *mallocNoSync(size_t size, uint bits, ref size_t alloc_size, const TypeInfo ti = null) nothrow
private void *mallocNoSync(size_t size, uint bits, ref size_t alloc_size) nothrow
{
assert(size != 0);

Expand All @@ -482,7 +482,7 @@ class GC
if (gcx.running)
onInvalidMemoryOperationError();

auto p = gcx.alloc(size + SENTINEL_EXTRA, alloc_size, bits, ti);
auto p = gcx.alloc(size + SENTINEL_EXTRA, alloc_size, bits);
if (!p)
onOutOfMemoryError();

Expand Down Expand Up @@ -2075,14 +2075,14 @@ struct Gcx
}


void* alloc(size_t size, ref size_t alloc_size, uint bits, const TypeInfo ti = null) nothrow
void* alloc(size_t size, ref size_t alloc_size, uint bits) nothrow
{
immutable bin = findBin(size);
return bin < B_PAGE ? smallAlloc(bin, alloc_size, bits, ti) :
bigAlloc(size, alloc_size, bits, ti);
return bin < B_PAGE ? smallAlloc(bin, alloc_size, bits) :
bigAlloc(size, alloc_size, bits);
}

void* smallAlloc(Bins bin, ref size_t alloc_size, uint bits, const TypeInfo ti = null) nothrow
void* smallAlloc(Bins bin, ref size_t alloc_size, uint bits) nothrow
{
alloc_size = binsize[bin];

Expand Down Expand Up @@ -2121,13 +2121,7 @@ struct Gcx
// Return next item from free list
bucket[bin] = (cast(List*)p).next;
auto pool = (cast(List*)p).pool;
if (bits)
{
if (ti)
setBits(pool, (p - pool.baseAddr) >> pool.shiftBy, bits, cast(TypeInfo_Struct)ti.next);
else
setBits(pool, (p - pool.baseAddr) >> pool.shiftBy, bits);
}
if (bits) setBits(pool, (p - pool.baseAddr) >> pool.shiftBy, bits);
//debug(PRINTF) printf("\tmalloc => %p\n", p);
debug (MEMSTOMP) memset(p, 0xF0, size);
return p;
Expand Down Expand Up @@ -2208,13 +2202,7 @@ struct Gcx
alloc_size = npages * PAGESIZE;
//debug(PRINTF) printf("\tp = %p\n", p);

if (bits)
{
if (ti)
setBits(pool, pn * PAGESIZE >> pool.shiftBy, bits, cast(TypeInfo_Struct)ti.next);
else
setBits(pool, pn * PAGESIZE >> pool.shiftBy, bits);
}
if (bits) setBits(pool, pn * PAGESIZE >> pool.shiftBy, bits);
return p;
}

Expand Down
Loading

0 comments on commit 0b72987

Please sign in to comment.