2 * Exception allocation, cloning, and release compiler support routines.
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)
18 import core.stdc.stdio;
21 /**********************************************
22 * Allocate an exception of type `ci` from the exception pool.
23 * It has the same interface as `rt.lifetime._d_newclass()`.
24 * The class type must be Throwable or derived from it,
25 * and cannot be a COM or C++ class. The compiler must enforce
28 * default initialized instance of the type
31 extern (C) Throwable _d_newThrowable(const TypeInfo_Class ci)
33 debug(PRINTF) printf("_d_newThrowable(ci = %p, %s)\n", ci, cast(char *)ci.name);
35 assert(!(ci.m_flags & TypeInfo_Class.ClassFlags.isCOMclass));
36 assert(!(ci.m_flags & TypeInfo_Class.ClassFlags.isCPPclass));
38 import core.stdc.stdlib : malloc;
39 auto init = ci.initializer;
40 void* p = malloc(init.length);
43 import core.exception : onOutOfMemoryError;
47 debug(PRINTF) printf(" p = %p\n", p);
50 p[0 .. init.length] = init[];
52 if (!(ci.m_flags & TypeInfo_Class.ClassFlags.noPointers))
54 // Inform the GC about the pointers in the object instance
55 import core.memory : GC;
57 GC.addRange(p, init.length, ci);
60 debug(PRINTF) printf("initialization done\n");
61 Throwable t = cast(Throwable)p;
67 /********************************************
68 * Delete exception instance `t` from the exception pool.
69 * Must have been allocated with `_d_newThrowable()`.
70 * This is meant to be called at the close of a catch block.
71 * It's nothrow because otherwise any function with a catch block could
77 nothrow extern (C) void _d_delThrowable(Throwable t)
81 debug(PRINTF) printf("_d_delThrowable(%p)\n", t);
83 /* If allocated by the GC, don't free it.
84 * Let the GC handle it.
85 * Supporting this is necessary while transitioning
86 * to this new scheme for allocating exceptions.
88 auto refcount = t.refcount();
90 return; // it was allocated by the GC
93 assert(0); // no zombie objects
95 t.refcount() = --refcount;
99 TypeInfo_Class **pc = cast(TypeInfo_Class **)t;
102 TypeInfo_Class ci = **pc;
104 if (!(ci.m_flags & TypeInfo_Class.ClassFlags.noPointers))
106 // Inform the GC about the pointers in the object instance
107 import core.memory : GC;
108 GC.removeRange(cast(void*) t);
114 import rt.lifetime : rt_finalize;
115 rt_finalize(cast(void*) t);
119 assert(0); // should never happen since Throwable.~this() is nothrow
121 import core.stdc.stdlib : free;
122 debug(PRINTF) printf("free(%p)\n", t);