summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backgraph.c24
-rw-r--r--dyn_load.c2
-rw-r--r--include/private/gc_priv.h8
-rw-r--r--mark.c33
-rw-r--r--os_dep.c2
5 files changed, 50 insertions, 19 deletions
diff --git a/backgraph.c b/backgraph.c
index 6e7a6bb8..743f2660 100644
--- a/backgraph.c
+++ b/backgraph.c
@@ -129,26 +129,32 @@ static size_t n_in_progress = 0;
static void push_in_progress(ptr_t p)
{
if (n_in_progress >= in_progress_size) {
- if (in_progress_size == 0) {
+ ptr_t * new_in_progress_space;
+
+ if (NULL == in_progress_space) {
in_progress_size = ROUNDUP_PAGESIZE_IF_MMAP(INITIAL_IN_PROGRESS
* sizeof(ptr_t))
/ sizeof(ptr_t);
- in_progress_space = (ptr_t *)GET_MEM(in_progress_size * sizeof(ptr_t));
- GC_add_to_our_memory((ptr_t)in_progress_space,
- in_progress_size * sizeof(ptr_t));
+ new_in_progress_space =
+ (ptr_t *)GET_MEM(in_progress_size * sizeof(ptr_t));
} else {
- ptr_t * new_in_progress_space;
in_progress_size *= 2;
new_in_progress_space = (ptr_t *)
GET_MEM(in_progress_size * sizeof(ptr_t));
- GC_add_to_our_memory((ptr_t)new_in_progress_space,
- in_progress_size * sizeof(ptr_t));
if (new_in_progress_space != NULL)
BCOPY(in_progress_space, new_in_progress_space,
n_in_progress * sizeof(ptr_t));
- in_progress_space = new_in_progress_space;
- /* FIXME: This just drops the old space. */
}
+ GC_add_to_our_memory((ptr_t)new_in_progress_space,
+ in_progress_size * sizeof(ptr_t));
+# ifndef GWW_VDB
+ GC_scratch_recycle_no_gww(in_progress_space,
+ n_in_progress * sizeof(ptr_t));
+# elif defined(LINT2)
+ /* TODO: implement GWW-aware recycling as in alloc_mark_stack */
+ GC_noop1((word)in_progress_space);
+# endif
+ in_progress_space = new_in_progress_space;
}
if (in_progress_space == 0)
ABORT("MAKE_BACK_GRAPH: Out of in-progress space: "
diff --git a/dyn_load.c b/dyn_load.c
index dbc145dc..beda2b8d 100644
--- a/dyn_load.c
+++ b/dyn_load.c
@@ -816,6 +816,8 @@ GC_INNER void GC_register_dynamic_libraries(void)
": fd = %d, errno = %d", fd, errno);
}
if (needed_sz >= current_sz) {
+ GC_scratch_recycle_no_gww(addr_map,
+ (size_t)current_sz * sizeof(prmap_t));
current_sz = needed_sz * 2 + 1;
/* Expansion, plus room for 0 record */
addr_map = (prmap_t *)GC_scratch_alloc(
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h
index 6be33a2e..71c8a200 100644
--- a/include/private/gc_priv.h
+++ b/include/private/gc_priv.h
@@ -1807,6 +1807,14 @@ GC_INNER ptr_t GC_scratch_alloc(size_t bytes);
/* small objects. Deallocation is not */
/* possible. May return NULL. */
+#ifdef GWW_VDB
+ /* GC_scratch_recycle_no_gww() not used. */
+#else
+# define GC_scratch_recycle_no_gww GC_scratch_recycle_inner
+#endif
+GC_INNER void GC_scratch_recycle_inner(void *ptr, size_t bytes);
+ /* Reuse the memory region by the heap. */
+
/* Heap block layout maps: */
GC_INNER GC_bool GC_add_map_entry(size_t sz);
/* Add a heap block map for objects of */
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;
diff --git a/os_dep.c b/os_dep.c
index 6cbd3f17..987158ab 100644
--- a/os_dep.c
+++ b/os_dep.c
@@ -201,6 +201,7 @@ GC_INNER char * GC_get_maps(void)
int f;
while (maps_size >= maps_buf_sz) {
+ GC_scratch_recycle_no_gww(maps_buf, maps_buf_sz);
/* Grow only by powers of 2, since we leak "too small" buffers.*/
while (maps_size >= maps_buf_sz) maps_buf_sz *= 2;
maps_buf = GC_scratch_alloc(maps_buf_sz);
@@ -3603,6 +3604,7 @@ GC_INNER void GC_read_dirty(GC_bool output_unneeded)
(signed_word)GC_proc_buf_size);
new_buf = GC_scratch_alloc(new_size);
if (new_buf != 0) {
+ GC_scratch_recycle_no_gww(bufp, GC_proc_buf_size);
GC_proc_buf = bufp = new_buf;
GC_proc_buf_size = new_size;
}