summaryrefslogtreecommitdiff
path: root/gcc/ggc.h
diff options
context:
space:
mode:
authortbsaunde <tbsaunde@138bc75d-0d04-0410-961f-82ee72b054a4>2014-05-17 23:08:00 +0000
committertbsaunde <tbsaunde@138bc75d-0d04-0410-961f-82ee72b054a4>2014-05-17 23:08:00 +0000
commit92f06184bb548e33327e5c9895b5d00f9e6d0304 (patch)
tree10dcc038bf8bcfb0dd6268ffbf36527b525bfb4e /gcc/ggc.h
parent16f97f36c2d368ed6618b8ac65958c0232187b55 (diff)
downloadgcc-92f06184bb548e33327e5c9895b5d00f9e6d0304.tar.gz
add finalizers to ggc
This implements finalizers by keeping a list of registered finalizers and after every mark but before sweeping check to see if any of them are for unmarked blocks. gcc/ChangeLog: * ggc-common.c (ggc_internal_cleared_alloc): Adjust. * ggc-none.c (ggc_internal_alloc): Assert if a finalizer is passed. (ggc_internal_cleared_alloc): Likewise. * ggc-page.c (finalizer): New class. (vec_finalizer): Likewise. (globals::finalizers): New member. (globals::vec_finalizers): Likewise. (ggc_internal_alloc): Record the finalizer if any for the block being allocated. (ggc_handle_finalizers): New function. (ggc_collect): Call ggc_handle_finalizers. * ggc.h (ggc_internal_alloc): Add arguments to allow installing a finalizer. (ggc_internal_cleared_alloc): Likewise. (finalize): New function. (need_finalization_p): Likewise. (ggc_alloc): Install the type's destructor as the finalizer if it might do something. (ggc_cleared_alloc): Likewise. (ggc_vec_alloc): Likewise. (ggc_cleared_vec_alloc): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@210568 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ggc.h')
-rw-r--r--gcc/ggc.h71
1 files changed, 63 insertions, 8 deletions
diff --git a/gcc/ggc.h b/gcc/ggc.h
index 50fb1995bae..1279aeedc3a 100644
--- a/gcc/ggc.h
+++ b/gcc/ggc.h
@@ -136,13 +136,30 @@ extern void gt_pch_save (FILE *f);
/* Allocation. */
/* The internal primitive. */
-extern void *ggc_internal_alloc (size_t CXX_MEM_STAT_INFO) ATTRIBUTE_MALLOC;
+extern void *ggc_internal_alloc (size_t, void (*)(void *), size_t,
+ size_t CXX_MEM_STAT_INFO)
+ ATTRIBUTE_MALLOC;
+
+ static inline
+ void *
+ ggc_internal_alloc (size_t s CXX_MEM_STAT_INFO)
+{
+ return ggc_internal_alloc (s, NULL, 0, 1 PASS_MEM_STAT);
+}
extern size_t ggc_round_alloc_size (size_t requested_size);
/* Allocates cleared memory. */
-extern void *ggc_internal_cleared_alloc (size_t CXX_MEM_STAT_INFO)
- ATTRIBUTE_MALLOC;
+extern void *ggc_internal_cleared_alloc (size_t, void (*)(void *),
+ size_t, size_t
+ CXX_MEM_STAT_INFO) ATTRIBUTE_MALLOC;
+
+static inline
+void *
+ggc_internal_cleared_alloc (size_t s CXX_MEM_STAT_INFO)
+{
+ return ggc_internal_cleared_alloc (s, NULL, 0, 1 PASS_MEM_STAT);
+}
/* Resize a block. */
extern void *ggc_realloc (void *, size_t CXX_MEM_STAT_INFO);
@@ -157,25 +174,57 @@ extern void dump_ggc_loc_statistics (bool);
((T *) ggc_realloc ((P), (N) * sizeof (T) MEM_STAT_INFO))
template<typename T>
+void
+finalize (void *p)
+{
+ static_cast<T *> (p)->~T ();
+}
+
+template<typename T>
+static inline bool
+need_finalization_p ()
+{
+#if GCC_VERSION >= 4003
+ return !__has_trivial_destructor (T);
+#else
+ return true;
+#endif
+}
+
+template<typename T>
static inline T *
ggc_alloc (ALONE_CXX_MEM_STAT_INFO)
{
- return static_cast<T *> (ggc_internal_alloc (sizeof (T) PASS_MEM_STAT));
+ if (need_finalization_p<T> ())
+ return static_cast<T *> (ggc_internal_alloc (sizeof (T), finalize<T>, 0, 1
+ PASS_MEM_STAT));
+ else
+ return static_cast<T *> (ggc_internal_alloc (sizeof (T), NULL, 0, 1
+ PASS_MEM_STAT));
}
template<typename T>
static inline T *
ggc_cleared_alloc (ALONE_CXX_MEM_STAT_INFO)
{
- return static_cast<T *> (ggc_internal_cleared_alloc (sizeof (T)
- PASS_MEM_STAT));
+ if (need_finalization_p<T> ())
+ return static_cast<T *> (ggc_internal_cleared_alloc (sizeof (T),
+ finalize<T>, 0, 1
+ PASS_MEM_STAT));
+ else
+ return static_cast<T *> (ggc_internal_cleared_alloc (sizeof (T), NULL, 0, 1
+ PASS_MEM_STAT));
}
template<typename T>
static inline T *
ggc_vec_alloc (size_t c CXX_MEM_STAT_INFO)
{
- return static_cast<T *> (ggc_internal_alloc (c * sizeof (T)
+ if (need_finalization_p<T> ())
+ return static_cast<T *> (ggc_internal_alloc (c * sizeof (T), finalize<T>,
+ sizeof (T), c PASS_MEM_STAT));
+ else
+ return static_cast<T *> (ggc_internal_alloc (c * sizeof (T), NULL, 0, 0
PASS_MEM_STAT));
}
@@ -183,8 +232,14 @@ template<typename T>
static inline T *
ggc_cleared_vec_alloc (size_t c CXX_MEM_STAT_INFO)
{
- return static_cast<T *> (ggc_internal_cleared_alloc (c * sizeof (T)
+ if (need_finalization_p<T> ())
+ return static_cast<T *> (ggc_internal_cleared_alloc (c * sizeof (T),
+ finalize<T>,
+ sizeof (T), c
PASS_MEM_STAT));
+ else
+ return static_cast<T *> (ggc_internal_cleared_alloc (c * sizeof (T), NULL,
+ 0, 0 PASS_MEM_STAT));
}
static inline void *