/** * Exception allocation, cloning, and release compiler support routines. * * Copyright: Copyright (c) 2017 by D Language Foundation * License: Distributed under the * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). * (See accompanying file LICENSE) * Authors: Walter Bright * Source: $(DRUNTIMESRC rt/_ehalloc.d) */module rt.ehalloc;//debug = PRINTF;debug (PRINTF) import core.stdc.stdio : printf;/******************************************** * Delete exception instance `t` from the exception pool. * Must have been allocated with `_d_newThrowable()`. * This is meant to be called at the close of a catch block. * It's nothrow because otherwise any function with a catch block could * not be nothrow. * Input: * t = Throwable */nothrow extern (C) void _d_delThrowable(Throwable t){ if (t) { debug(PRINTF) printf("_d_delThrowable(%p)\n", t); /* If allocated by the GC, don't free it. * Let the GC handle it. * Supporting this is necessary while transitioning * to this new scheme for allocating exceptions. */ auto refcount = t.refcount(); if (refcount == 0) return; // it was allocated by the GC if (refcount == 1) assert(0); // no zombie objects t.refcount() = --refcount; if (refcount > 1) return; TypeInfo_Class **pc = cast(TypeInfo_Class **)t; if (*pc) { TypeInfo_Class ci = **pc; if (!(ci.m_flags & TypeInfo_Class.ClassFlags.noPointers)) { // Inform the GC about the pointers in the object instance import core.memory : GC; GC.removeRange(cast(void*) t); } } try { import rt.lifetime : rt_finalize; rt_finalize(cast(void*) t); } catch (Throwable t) { assert(0); // should never happen since Throwable.~this() is nothrow } import core.stdc.stdlib : free; debug(PRINTF) printf("free(%p)\n", t); free(cast(void*) t); }}
/**
* Exception allocation, cloning, and release compiler support routines.
*
* Copyright: Copyright (c) 2017 by D Language Foundation
* License: Distributed under the
* $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
* (See accompanying file LICENSE)
* Authors: Walter Bright
* Source: $(DRUNTIMESRC rt/_ehalloc.d)
*/
module rt.ehalloc;
//debug = PRINTF;
debug (PRINTF) import core.stdc.stdio : printf;
/********************************************
* Delete exception instance `t` from the exception pool.
* Must have been allocated with `_d_newThrowable()`.
* This is meant to be called at the close of a catch block.
* It's nothrow because otherwise any function with a catch block could
* not be nothrow.
* Input:
* t = Throwable
*/
nothrow extern (C) void _d_delThrowable(Throwable t)
{
if (t)
{
debug(PRINTF) printf("_d_delThrowable(%p)\n", t);
/* If allocated by the GC, don't free it.
* Let the GC handle it.
* Supporting this is necessary while transitioning
* to this new scheme for allocating exceptions.
*/
auto refcount = t.refcount();
if (refcount == 0)
return; // it was allocated by the GC
if (refcount == 1)
assert(0); // no zombie objects
t.refcount() = --refcount;
if (refcount > 1)
return;
TypeInfo_Class **pc = cast(TypeInfo_Class **)t;
if (*pc)
{
TypeInfo_Class ci = **pc;
if (!(ci.m_flags & TypeInfo_Class.ClassFlags.noPointers))
{
// Inform the GC about the pointers in the object instance
import core.memory : GC;
GC.removeRange(cast(void*) t);
}
}
try
{
import rt.lifetime : rt_finalize;
rt_finalize(cast(void*) t);
}
catch (Throwable t)
{
assert(0); // should never happen since Throwable.~this() is nothrow
}
import core.stdc.stdlib : free;
debug(PRINTF) printf("free(%p)\n", t);
free(cast(void*) t);
}
}