From e637f6ab757ec031eefc2e07af254a4198f5da7a Mon Sep 17 00:00:00 2001 From: hboehm Date: Tue, 28 Oct 2008 00:42:29 +0000 Subject: [PATCH] 2008-10-27 Hans Boehm * win32_threads.c (GC_get_stack_min, GC_may_be_in_stack): Add one entry VirtualQuery cache, I_HOLD_LOCK assertions. (GC_push_stack_for, GC_get_next_stack) : Hopefully fix WINCE support. 2008-10-27 Hans Boehm (Thanks to Klaus Treichel.) * finalize.c (GC_general_register_disappearing_link): Add assertion. * malloc.c (GC_generic_malloc): Round lb to granules, not words. * mallocx.c (GC_generic_malloc_ignore_off_page): Round lb to granules, not words. --- ChangeLog | 14 +++++++++++- finalize.c | 1 + malloc.c | 7 +++--- mallocx.c | 7 +++--- win32_threads.c | 61 +++++++++++++++++++++++++++++++++---------------- 5 files changed, 63 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index dc87a01c..fae49da7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,16 @@ -2008-10-25 Hans Boehm (Really Rex Dieter and +2008-10-27 Hans Boehm + * win32_threads.c (GC_get_stack_min, GC_may_be_in_stack): + Add one entry VirtualQuery cache, I_HOLD_LOCK assertions. + (GC_push_stack_for, GC_get_next_stack) : Hopefully fix WINCE support. + +2008-10-27 Hans Boehm (Thanks to Klaus Treichel.) + * finalize.c (GC_general_register_disappearing_link): Add + assertion. + * malloc.c (GC_generic_malloc): Round lb to granules, not words. + * mallocx.c (GC_generic_malloc_ignore_off_page): Round lb to + granules, not words. + +2008-10-27 Hans Boehm (Really Rex Dieter and Petr Krajca) * mach_dep.c (NO_GETCONTEXT): Define for sparc linux. * configure.ac: Define mach_dep for sparc-linux. diff --git a/finalize.c b/finalize.c index 693389a2..7a4ada27 100644 --- a/finalize.c +++ b/finalize.c @@ -160,6 +160,7 @@ GC_API int GC_CALL GC_general_register_disappearing_link(void * * link, # ifdef THREADS LOCK(); # endif + GC_ASSERT(GC_base(obj) == obj); if (log_dl_table_size == -1 || GC_dl_entries > ((word)1 << log_dl_table_size)) { GC_grow_table((struct hash_chain_entry ***)(&dl_head), diff --git a/malloc.c b/malloc.c index 9928ea21..88d5619d 100644 --- a/malloc.c +++ b/malloc.c @@ -159,12 +159,13 @@ void * GC_generic_malloc(size_t lb, int k) result = GC_generic_malloc_inner((word)lb, k); UNLOCK(); } else { - size_t lw; + size_t lg, lw; size_t lb_rounded; word n_blocks; GC_bool init; - lw = ROUNDED_UP_WORDS(lb); - lb_rounded = WORDS_TO_BYTES(lw); + lg = ROUNDED_UP_GRANULES(lb); + lw = GRANULES_TO_WORDS(lg); + lb_rounded = GRANULES_TO_BYTES(lg); n_blocks = OBJ_SZ_TO_BLOCKS(lb_rounded); init = GC_obj_kinds[k].ok_init; LOCK(); diff --git a/mallocx.c b/mallocx.c index a289ade0..b010bccb 100644 --- a/mallocx.c +++ b/mallocx.c @@ -167,7 +167,7 @@ void * realloc(void * p, size_t lb) void * GC_generic_malloc_ignore_off_page(size_t lb, int k) { void *result; - size_t lw; + size_t lg, lw; size_t lb_rounded; word n_blocks; GC_bool init; @@ -175,8 +175,9 @@ void * GC_generic_malloc_ignore_off_page(size_t lb, int k) if (SMALL_OBJ(lb)) return(GC_generic_malloc((word)lb, k)); - lw = ROUNDED_UP_WORDS(lb); - lb_rounded = WORDS_TO_BYTES(lw); + lg = ROUNDED_UP_GRANULES(lb); + lw = GRANULES_TO_WORDS(lg); + lb_rounded = GRANULES_TO_BYTES(lg); n_blocks = OBJ_SZ_TO_BLOCKS(lb_rounded); init = GC_obj_kinds[k].ok_init; if (GC_have_errors) GC_print_all_errors(); diff --git a/win32_threads.c b/win32_threads.c index 8ced3506..df174aa5 100644 --- a/win32_threads.c +++ b/win32_threads.c @@ -814,6 +814,12 @@ void GC_start_world(void) # define GC_get_stack_min(s) \ ((ptr_t)(((DWORD)(s) - 1) & 0xFFFF0000)) # else + + /* A cache holding the results of the last VirtualQuery call. */ + /* Protected by the allocation lock. */ + static ptr_t last_address = 0; + static MEMORY_BASIC_INFORMATION last_info; + /* Probe stack memory region (starting at "s") to find out its */ /* lowest address (i.e. stack top). */ /* S must be a mapped address inside the region, NOT the first */ @@ -821,13 +827,18 @@ void GC_start_world(void) static ptr_t GC_get_stack_min(ptr_t s) { ptr_t bottom; - MEMORY_BASIC_INFORMATION info; - VirtualQuery(s, &info, sizeof(info)); + + GC_ASSERT(I_HOLD_LOCK()); + if (s != last_address) { + VirtualQuery(s, &last_info, sizeof(last_info)); + last_address = s; + } do { - bottom = info.BaseAddress; - VirtualQuery(bottom - 1, &info, sizeof(info)); - } while ((info.Protect & PAGE_READWRITE) - && !(info.Protect & PAGE_GUARD)); + bottom = last_info.BaseAddress; + VirtualQuery(bottom - 1, &last_info, sizeof(last_info)); + last_address = bottom - 1; + } while ((last_info.Protect & PAGE_READWRITE) + && !(last_info.Protect & PAGE_GUARD)); return(bottom); } @@ -835,9 +846,13 @@ void GC_start_world(void) /* for a stack page. */ static GC_bool GC_may_be_in_stack(ptr_t s) { - MEMORY_BASIC_INFORMATION info; - VirtualQuery(s, &info, sizeof(info)); - return (info.Protect & PAGE_READWRITE) && !(info.Protect & PAGE_GUARD); + GC_ASSERT(I_HOLD_LOCK()); + if (s != last_address) { + VirtualQuery(s, &last_info, sizeof(last_info)); + last_address = s; + } + return (last_info.Protect & PAGE_READWRITE) + && !(last_info.Protect & PAGE_GUARD); } # endif @@ -908,11 +923,15 @@ STATIC void GC_push_stack_for(GC_thread thread) if (thread -> last_stack_min == ADDR_LIMIT) { stack_min = GC_get_stack_min(thread -> stack_base); } else { - if (GC_may_be_in_stack(thread -> last_stack_min)) { - stack_min = GC_get_stack_min(thread -> last_stack_min); - } else { +# ifdef MSWINCE stack_min = GC_get_stack_min(thread -> stack_base); - } +# else + if (GC_may_be_in_stack(thread -> last_stack_min)) { + stack_min = GC_get_stack_min(thread -> last_stack_min); + } else { + stack_min = GC_get_stack_min(thread -> stack_base); + } +# endif } thread -> last_stack_min = stack_min; @@ -1032,13 +1051,15 @@ void GC_get_next_stack(char *start, char *limit, GC_ASSERT(current_min > start); - if (current_min > limit && !GC_may_be_in_stack(limit)) { - /* Skip the rest since the memory region at limit address is not */ - /* a stack (so the lowest address of the found stack would be */ - /* above the limit value anyway). */ - *lo = ADDR_LIMIT; - return; - } +# ifndef MSWINCE + if (current_min > limit && !GC_may_be_in_stack(limit)) { + /* Skip the rest since the memory region at limit address is */ + /* not a stack (so the lowest address of the found stack would */ + /* be above the limit value anyway). */ + *lo = ADDR_LIMIT; + return; + } +# endif /* Get the minimum address of the found stack by probing its memory */ /* region starting from the last known minimum (if set). */ -- 2.40.0