summaryrefslogtreecommitdiff
path: root/mark.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2016-12-22 11:05:41 +0300
committerIvan Maidanski <ivmai@mail.ru>2016-12-22 11:05:41 +0300
commitfde97b79c8681ef27bd731ef42766589ce892e66 (patch)
tree7e0d7fc176c4104f4116e7618ceb2b9f2e4d8f75 /mark.c
parent495b4fe5c2ee1767f20c8db7ec42a2c1ad04737c (diff)
downloadbdwgc-fde97b79c8681ef27bd731ef42766589ce892e66.tar.gz
Eliminate 'memory leak' code defect for scratch-allocated memory
Reuse memory allocated by GC_scratch_alloc and GET_MEM in GC heap if possible. * backgraph.c (push_in_progress): Replace in_progress_size==0 with in_progress_space==NULL (to ensure BCOPY argument is non-NULL); eliminate code duplication regarding GC_add_to_our_memory call; call GC_scratch_recycle_no_gww (for old in_progress_space value) unless GWW_VDB (and remove corresponding FIXME). * dyn_load.c [IRIX5 || USE_PROC_FOR_LIBRARIES && !LINUX] (GC_register_dynamic_libraries): Call GC_scratch_recycle_no_gww (for old addr_map and current_sz values). * include/private/gc_priv.h [!GWW_VDB] (GC_scratch_recycle_no_gww): New internal macro. * include/private/gc_priv.h (GC_scratch_recycle_inner): New prototype. * mark.c (GC_scratch_recycle_inner): New function (move code portion from alloc_mark_stack). * mark.c (alloc_mark_stack): Call GC_scratch_recycle_inner (if recycle_old). * os_dep.c [NEED_PROC_MAPS] (GC_get_maps): Call GC_scratch_recycle_no_gww (for old maps_buf and maps_buf_sz values). * os_dep.c [PROC_VDB] (GC_read_dirty): Call GC_scratch_recycle_no_gww (for old GC_proc_buf and GC_proc_buf_size values).
Diffstat (limited to 'mark.c')
-rw-r--r--mark.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/mark.c b/mark.c
index f5b9dc49..e5c89218 100644
--- a/mark.c
+++ b/mark.c
@@ -1260,6 +1260,27 @@ GC_INNER void GC_help_marker(word my_mark_no)
#endif /* PARALLEL_MARK */
+GC_INNER void GC_scratch_recycle_inner(void *ptr, size_t bytes)
+{
+ if (ptr != NULL) {
+ size_t page_offset = (word)ptr & (GC_page_size - 1);
+ size_t displ = 0;
+ size_t recycled_bytes;
+
+ GC_ASSERT(bytes != 0);
+ GC_ASSERT(GC_page_size != 0);
+ /* TODO: Assert correct memory flags if GWW_VDB */
+ if (page_offset != 0)
+ displ = GC_page_size - page_offset;
+ recycled_bytes = (bytes - displ) & ~(GC_page_size - 1);
+ GC_COND_LOG_PRINTF("Recycle %lu/%lu scratch-allocated bytes at %p\n",
+ (unsigned long)recycled_bytes, (unsigned long)bytes,
+ ptr);
+ if (recycled_bytes > 0)
+ GC_add_to_heap((struct hblk *)((word)ptr + displ), recycled_bytes);
+ }
+}
+
/* Allocate or reallocate space for mark stack of size n entries. */
/* May silently fail. */
static void alloc_mark_stack(size_t n)
@@ -1281,16 +1302,8 @@ static void alloc_mark_stack(size_t n)
if (new_stack != 0) {
if (recycle_old) {
/* Recycle old space */
- size_t page_offset = (word)GC_mark_stack & (GC_page_size - 1);
- size_t size = GC_mark_stack_size * sizeof(struct GC_ms_entry);
- size_t displ = 0;
-
- if (0 != page_offset) displ = GC_page_size - page_offset;
- size = (size - displ) & ~(GC_page_size - 1);
- if (size > 0) {
- GC_add_to_heap((struct hblk *)
- ((word)GC_mark_stack + displ), (word)size);
- }
+ GC_scratch_recycle_inner(GC_mark_stack,
+ GC_mark_stack_size * sizeof(struct GC_ms_entry));
}
GC_mark_stack = new_stack;
GC_mark_stack_size = n;