diff options
author | tbsaunde <tbsaunde@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-05-17 23:08:00 +0000 |
---|---|---|
committer | tbsaunde <tbsaunde@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-05-17 23:08:00 +0000 |
commit | 92f06184bb548e33327e5c9895b5d00f9e6d0304 (patch) | |
tree | 10dcc038bf8bcfb0dd6268ffbf36527b525bfb4e /gcc/ggc.h | |
parent | 16f97f36c2d368ed6618b8ac65958c0232187b55 (diff) | |
download | gcc-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.h | 71 |
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 * |