summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2023-05-13 11:41:19 +0300
committerIvan Maidanski <ivmai@mail.ru>2023-05-13 11:41:19 +0300
commit1c2d6cf5439a052e06369c36746d3c1f07900e22 (patch)
tree33450802ad3a87e8abed0bd7ca93c4c303076024
parenta0a416a8a9c5ad98678207ef8fa3a9b8e1262318 (diff)
downloadbdwgc-1c2d6cf5439a052e06369c36746d3c1f07900e22.tar.gz
Fix comparisons to heap boundary in GC_get_back_ptr_info and GC_mark_from
The region delimited by GC_least_plausible_heap_addr and GC_greatest_plausible_heap_addr might contain part of static data roots or stacks (in addition to potential heap expansion areas). Certain comparisons in GC_get_back_ptr_info (when ALIGNMENT is 1) and in GC_mark_from (in assertions) expect the real heap boundaries. * alloc.c [SET_REAL_HEAP_BOUNDS] (GC_add_to_heap): Update GC_least_real_heap_addr and GC_greatest_real_heap_addr variables. * dbg_mlc.c [KEEP_BACK_PTRS && ALIGNMENT == 1] (GC_get_back_ptr_info): Compare alternate_target and target to GC_least_real_heap_addr and GC_greatest_real_heap_addr (instead of GC_least_plausible_heap_addr and GC_greatest_plausible_heap_addr). * include/gc/gc_mark.h (GC_greatest_plausible_heap_addr): Refine comment. * include/private/gc_priv.h [GC_ASSERTIONS || KEEP_BACK_PTRS && ALIGNMENT == 1] (SET_REAL_HEAP_BOUNDS): Define macro. * include/private/gc_priv.h [GC_ASSERTIONS || KEEP_BACK_PTRS && ALIGNMENT == 1] (GC_least_real_heap_addr, GC_greatest_real_heap_addr): Define (as macro). * include/private/gc_priv.h [GC_ASSERTIONS || KEEP_BACK_PTRS && ALIGNMENT == 1] (_GC_arrays._least_real_heap_addr, _GC_arrays._greatest_real_heap_addr): New field; add comment. * mark.c (GC_mark_from): Use GC_greatest_real_heap_addr and GC_least_real_heap_addr instead of GC_least_plausible_heap_addr and GC_greatest_plausible_heap_addr, respectively, in assertions.
-rw-r--r--alloc.c8
-rw-r--r--dbg_mlc.c8
-rw-r--r--include/gc/gc_mark.h4
-rw-r--r--include/private/gc_priv.h10
-rw-r--r--mark.c19
5 files changed, 32 insertions, 17 deletions
diff --git a/alloc.c b/alloc.c
index 611701e4..57a84807 100644
--- a/alloc.c
+++ b/alloc.c
@@ -1434,7 +1434,13 @@ STATIC void GC_add_to_heap(struct hblk *p, size_t bytes)
if (endp > (word)GC_greatest_plausible_heap_addr) {
GC_greatest_plausible_heap_addr = (void *)endp;
}
-
+# ifdef SET_REAL_HEAP_BOUNDS
+ if ((word)p < GC_least_real_heap_addr
+ || EXPECT(0 == GC_least_real_heap_addr, FALSE))
+ GC_least_real_heap_addr = (word)p - sizeof(word);
+ if (endp > GC_greatest_real_heap_addr)
+ GC_greatest_real_heap_addr = endp;
+# endif
if (EXPECT(old_capacity > 0, FALSE)) {
# ifndef GWW_VDB
/* Recycling may call GC_add_to_heap() again but should not */
diff --git a/dbg_mlc.c b/dbg_mlc.c
index 7c528739..01fd0022 100644
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -133,10 +133,10 @@
ptr_t target = *(ptr_t *)bp;
ptr_t alternate_target = *(ptr_t *)alternate_ptr;
- if ((word)alternate_target >= (word)GC_least_plausible_heap_addr
- && (word)alternate_target < (word)GC_greatest_plausible_heap_addr
- && ((word)target < (word)GC_least_plausible_heap_addr
- || (word)target >= (word)GC_greatest_plausible_heap_addr)) {
+ if ((word)alternate_target > GC_least_real_heap_addr
+ && (word)alternate_target < GC_greatest_real_heap_addr
+ && ((word)target <= GC_least_real_heap_addr
+ || (word)target >= GC_greatest_real_heap_addr)) {
bp = alternate_ptr;
}
}
diff --git a/include/gc/gc_mark.h b/include/gc/gc_mark.h
index 6142e750..acec052b 100644
--- a/include/gc/gc_mark.h
+++ b/include/gc/gc_mark.h
@@ -128,7 +128,9 @@ GC_API void * GC_greatest_plausible_heap_addr;
/* Bounds on the heap. Guaranteed to be valid. */
/* Likely to include future heap expansion. */
/* Hence usually includes not-yet-mapped */
- /* memory. The address of any heap object is */
+ /* memory, or might overlap with other data */
+ /* roots. The address of any heap object is */
+ /* larger than GC_least_plausible_heap_addr and */
/* less than GC_greatest_plausible_heap_addr. */
/* Handle nested references in a custom mark procedure. */
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h
index 8091b7f3..84bcc14c 100644
--- a/include/private/gc_priv.h
+++ b/include/private/gc_priv.h
@@ -1448,6 +1448,16 @@ struct _GC_arrays {
/* obtained scratch area. */
/* Used by GC_register_dynamic_libraries(). */
# endif
+# if defined(GC_ASSERTIONS) || (defined(KEEP_BACK_PTRS) && ALIGNMENT == 1)
+# define SET_REAL_HEAP_BOUNDS
+# define GC_least_real_heap_addr GC_arrays._least_real_heap_addr
+# define GC_greatest_real_heap_addr GC_arrays._greatest_real_heap_addr
+ word _least_real_heap_addr;
+ word _greatest_real_heap_addr;
+ /* Similar to GC_least/greatest_plausible_heap_addr but */
+ /* do not include future (potential) heap expansion. */
+ /* Both variables are zero initially. */
+# endif
mse *_mark_stack;
/* Limits of stack for GC_mark routine. All ranges */
/* between GC_mark_stack (incl.) and GC_mark_stack_top */
diff --git a/mark.c b/mark.c
index b0fe1802..ffc66956 100644
--- a/mark.c
+++ b/mark.c
@@ -618,11 +618,10 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack,
/* too much on the stack. */
/* Either it is a heap object or a region outside the heap. */
- GC_ASSERT(descr <= (word)GC_greatest_plausible_heap_addr
- - (word)GC_least_plausible_heap_addr
- || (word)(current_p + descr)
- <= (word)GC_least_plausible_heap_addr
- || (word)current_p >= (word)GC_greatest_plausible_heap_addr);
+ GC_ASSERT(descr < GC_greatest_real_heap_addr-GC_least_real_heap_addr
+ || (word)current_p + descr
+ <= GC_least_real_heap_addr + sizeof(word)
+ || (word)current_p >= GC_greatest_real_heap_addr);
# ifdef PARALLEL_MARK
# define SHARE_BYTES 2048
if (descr > SHARE_BYTES && GC_parallel
@@ -930,12 +929,10 @@ STATIC mse * GC_steal_mark_stack(mse * low, mse * high, mse * local,
top -> mse_descr.w = descr;
top -> mse_start = p -> mse_start;
GC_ASSERT((descr & GC_DS_TAGS) != GC_DS_LENGTH /* 0 */
- || descr <= (word)GC_greatest_plausible_heap_addr
- - (word)GC_least_plausible_heap_addr
- || (word)(p -> mse_start + descr)
- <= (word)GC_least_plausible_heap_addr
- || (word)p -> mse_start
- >= (word)GC_greatest_plausible_heap_addr);
+ || descr < GC_greatest_real_heap_addr-GC_least_real_heap_addr
+ || (word)(p -> mse_start + descr)
+ <= GC_least_real_heap_addr + sizeof(word)
+ || (word)(p -> mse_start) >= GC_greatest_real_heap_addr);
/* If this is a big object, count it as size/256 + 1 objects. */
++i;
if ((descr & GC_DS_TAGS) == GC_DS_LENGTH) i += (int)(descr >> 8);