-2008-10-25 Hans Boehm <Hans.Boehm@hp.com> (Really Rex Dieter and
+2008-10-27 Hans Boehm <Hans.Boehm@hp.com>
+ * 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 <Hans.Boehm@hp.com> (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 <Hans.Boehm@hp.com> (Really Rex Dieter and
Petr Krajca)
* mach_dep.c (NO_GETCONTEXT): Define for sparc linux.
* configure.ac: Define mach_dep for sparc-linux.
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;
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();
# 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 */
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);
}
/* 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
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;
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). */