| /** |
| * 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; |
| } |
| |
| |
| /******************************************** |
| * 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); |
| } |
| } |