1 /** 2 * Exception allocation, cloning, and release compiler support routines. 3 * 4 * Copyright: Copyright (c) 2017 by D Language Foundation 5 * License: Distributed under the 6 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). 7 * (See accompanying file LICENSE) 8 * Authors: Walter Bright 9 * Source: $(DRUNTIMESRC rt/_ehalloc.d) 10 */ 11 12 module rt.ehalloc; 13 14 //debug = PRINTF; 15 16 debug(PRINTF) 17 { 18 import core.stdc.stdio; 19 } 20 21 22 /******************************************** 23 * Delete exception instance `t` from the exception pool. 24 * Must have been allocated with `_d_newThrowable()`. 25 * This is meant to be called at the close of a catch block. 26 * It's nothrow because otherwise any function with a catch block could 27 * not be nothrow. 28 * Input: 29 * t = Throwable 30 */ 31 32 nothrow extern (C) void _d_delThrowable(Throwable t) 33 { 34 if (t) 35 { 36 debug(PRINTF) printf("_d_delThrowable(%p)\n", t); 37 38 /* If allocated by the GC, don't free it. 39 * Let the GC handle it. 40 * Supporting this is necessary while transitioning 41 * to this new scheme for allocating exceptions. 42 */ 43 auto refcount = t.refcount(); 44 if (refcount == 0) 45 return; // it was allocated by the GC 46 47 if (refcount == 1) 48 assert(0); // no zombie objects 49 50 t.refcount() = --refcount; 51 if (refcount > 1) 52 return; 53 54 TypeInfo_Class **pc = cast(TypeInfo_Class **)t; 55 if (*pc) 56 { 57 TypeInfo_Class ci = **pc; 58 59 if (!(ci.m_flags & TypeInfo_Class.ClassFlags.noPointers)) 60 { 61 // Inform the GC about the pointers in the object instance 62 import core.memory : GC; 63 GC.removeRange(cast(void*) t); 64 } 65 } 66 67 try 68 { 69 import rt.lifetime : rt_finalize; 70 rt_finalize(cast(void*) t); 71 } 72 catch (Throwable t) 73 { 74 assert(0); // should never happen since Throwable.~this() is nothrow 75 } 76 import core.stdc.stdlib : free; 77 debug(PRINTF) printf("free(%p)\n", t); 78 free(cast(void*) t); 79 } 80 }