version 1.5, 2002/07/24 07:46:19 |
version 1.6, 2002/07/24 08:00:10 |
Line 264 static void alloc_mark_stack(); |
|
Line 264 static void alloc_mark_stack(); |
|
GC_bool GC_mark_some(cold_gc_frame) |
GC_bool GC_mark_some(cold_gc_frame) |
ptr_t cold_gc_frame; |
ptr_t cold_gc_frame; |
{ |
{ |
#ifdef MSWIN32 |
#if defined(MSWIN32) && !defined(__GNUC__) |
/* Windows 98 appears to asynchronously create and remove writable */ |
/* Windows 98 appears to asynchronously create and remove writable */ |
/* memory mappings, for reasons we haven't yet understood. Since */ |
/* memory mappings, for reasons we haven't yet understood. Since */ |
/* we look for writable regions to determine the root set, we may */ |
/* we look for writable regions to determine the root set, we may */ |
Line 274 ptr_t cold_gc_frame; |
|
Line 274 ptr_t cold_gc_frame; |
|
/* Note that this code should never generate an incremental GC write */ |
/* Note that this code should never generate an incremental GC write */ |
/* fault. */ |
/* fault. */ |
__try { |
__try { |
#endif |
#endif /* defined(MSWIN32) && !defined(__GNUC__) */ |
switch(GC_mark_state) { |
switch(GC_mark_state) { |
case MS_NONE: |
case MS_NONE: |
return(FALSE); |
return(FALSE); |
Line 395 ptr_t cold_gc_frame; |
|
Line 395 ptr_t cold_gc_frame; |
|
ABORT("GC_mark_some: bad state"); |
ABORT("GC_mark_some: bad state"); |
return(FALSE); |
return(FALSE); |
} |
} |
#ifdef MSWIN32 |
#if defined(MSWIN32) && !defined(__GNUC__) |
} __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? |
} __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? |
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { |
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { |
# ifdef CONDPRINT |
# ifdef CONDPRINT |
Line 410 ptr_t cold_gc_frame; |
|
Line 410 ptr_t cold_gc_frame; |
|
scan_ptr = 0; |
scan_ptr = 0; |
return FALSE; |
return FALSE; |
} |
} |
#endif /* MSWIN32 */ |
#endif /* defined(MSWIN32) && !defined(__GNUC__) */ |
} |
} |
|
|
|
|
Line 427 GC_bool GC_mark_stack_empty() |
|
Line 427 GC_bool GC_mark_stack_empty() |
|
#endif |
#endif |
|
|
/* Given a pointer to someplace other than a small object page or the */ |
/* Given a pointer to someplace other than a small object page or the */ |
/* first page of a large object, return a pointer either to the */ |
/* first page of a large object, either: */ |
/* start of the large object or NIL. */ |
/* - return a pointer to somewhere in the first page of the large */ |
/* In the latter case black list the address current. */ |
/* object, if current points to a large object. */ |
/* Returns NIL without black listing if current points to a block */ |
/* In this case *hhdr is replaced with a pointer to the header */ |
/* with IGNORE_OFF_PAGE set. */ |
/* for the large object. */ |
|
/* - just return current if it does not point to a large object. */ |
/*ARGSUSED*/ |
/*ARGSUSED*/ |
# ifdef PRINT_BLACK_LIST |
ptr_t GC_find_start(current, hhdr, new_hdr_p) |
ptr_t GC_find_start(current, hhdr, source) |
|
word source; |
|
# else |
|
ptr_t GC_find_start(current, hhdr) |
|
# define source 0 |
|
# endif |
|
register ptr_t current; |
register ptr_t current; |
register hdr * hhdr; |
register hdr *hhdr, **new_hdr_p; |
{ |
{ |
if (GC_all_interior_pointers) { |
if (GC_all_interior_pointers) { |
if (hhdr != 0) { |
if (hhdr != 0) { |
Line 457 register hdr * hhdr; |
|
Line 452 register hdr * hhdr; |
|
if ((word *)orig - (word *)current |
if ((word *)orig - (word *)current |
>= (ptrdiff_t)(hhdr->hb_sz)) { |
>= (ptrdiff_t)(hhdr->hb_sz)) { |
/* Pointer past the end of the block */ |
/* Pointer past the end of the block */ |
GC_ADD_TO_BLACK_LIST_NORMAL((word)orig, source); |
return(orig); |
return(0); |
|
} |
} |
|
*new_hdr_p = hhdr; |
return(current); |
return(current); |
} else { |
} else { |
GC_ADD_TO_BLACK_LIST_NORMAL((word)current, source); |
return(current); |
return(0); |
|
} |
} |
} else { |
} else { |
GC_ADD_TO_BLACK_LIST_NORMAL((word)current, source); |
return(current); |
return(0); |
|
} |
} |
# undef source |
|
} |
} |
|
|
void GC_invalidate_mark_state() |
void GC_invalidate_mark_state() |
Line 547 mse * mark_stack_limit; |
|
Line 539 mse * mark_stack_limit; |
|
/* Large length. */ |
/* Large length. */ |
/* Process part of the range to avoid pushing too much on the */ |
/* Process part of the range to avoid pushing too much on the */ |
/* stack. */ |
/* stack. */ |
|
GC_ASSERT(descr < GC_greatest_plausible_heap_addr |
|
- GC_least_plausible_heap_addr); |
# ifdef PARALLEL_MARK |
# ifdef PARALLEL_MARK |
# define SHARE_BYTES 2048 |
# define SHARE_BYTES 2048 |
if (descr > SHARE_BYTES && GC_parallel |
if (descr > SHARE_BYTES && GC_parallel |
&& mark_stack_top < mark_stack_limit - 1) { |
&& mark_stack_top < mark_stack_limit - 1) { |
int new_size = (descr/2) & ~(sizeof(word)-1); |
int new_size = (descr/2) & ~(sizeof(word)-1); |
GC_ASSERT(descr < GC_greatest_plausible_heap_addr |
|
- GC_least_plausible_heap_addr); |
|
mark_stack_top -> mse_start = current_p; |
mark_stack_top -> mse_start = current_p; |
mark_stack_top -> mse_descr = new_size + sizeof(word); |
mark_stack_top -> mse_descr = new_size + sizeof(word); |
/* makes sure we handle */ |
/* makes sure we handle */ |
Line 839 long GC_markers = 2; /* Normally changed by thread-li |
|
Line 831 long GC_markers = 2; /* Normally changed by thread-li |
|
/* -specific code. */ |
/* -specific code. */ |
|
|
/* Mark using the local mark stack until the global mark stack is empty */ |
/* Mark using the local mark stack until the global mark stack is empty */ |
/* and ther are no active workers. Update GC_first_nonempty to reflect */ |
/* and there are no active workers. Update GC_first_nonempty to reflect */ |
/* progress. */ |
/* progress. */ |
/* Caller does not hold mark lock. */ |
/* Caller does not hold mark lock. */ |
/* Caller has already incremented GC_helper_count. We decrement it, */ |
/* Caller has already incremented GC_helper_count. We decrement it, */ |
Line 919 void GC_mark_local(mse *local_mark_stack, int id) |
|
Line 911 void GC_mark_local(mse *local_mark_stack, int id) |
|
return; |
return; |
} |
} |
/* else there's something on the stack again, or */ |
/* else there's something on the stack again, or */ |
/* another help may push something. */ |
/* another helper may push something. */ |
GC_active_count++; |
GC_active_count++; |
GC_ASSERT(GC_active_count > 0); |
GC_ASSERT(GC_active_count > 0); |
GC_release_mark_lock(); |
GC_release_mark_lock(); |
Line 951 void GC_do_parallel_mark() |
|
Line 943 void GC_do_parallel_mark() |
|
|
|
GC_acquire_mark_lock(); |
GC_acquire_mark_lock(); |
GC_ASSERT(I_HOLD_LOCK()); |
GC_ASSERT(I_HOLD_LOCK()); |
GC_ASSERT(!GC_help_wanted); |
/* This could be a GC_ASSERT, but it seems safer to keep it on */ |
GC_ASSERT(GC_active_count == 0); |
/* all the time, especially since it's cheap. */ |
|
if (GC_help_wanted || GC_active_count != 0 || GC_helper_count != 0) |
|
ABORT("Tried to start parallel mark in bad state"); |
# ifdef PRINTSTATS |
# ifdef PRINTSTATS |
GC_printf1("Starting marking for mark phase number %lu\n", |
GC_printf1("Starting marking for mark phase number %lu\n", |
(unsigned long)GC_mark_no); |
(unsigned long)GC_mark_no); |
Line 1375 ptr_t cold_gc_frame; |
|
Line 1369 ptr_t cold_gc_frame; |
|
return; |
return; |
} |
} |
# ifdef STACK_GROWS_DOWN |
# ifdef STACK_GROWS_DOWN |
GC_push_all_eager(bottom, cold_gc_frame); |
|
GC_push_all(cold_gc_frame - sizeof(ptr_t), top); |
GC_push_all(cold_gc_frame - sizeof(ptr_t), top); |
|
GC_push_all_eager(bottom, cold_gc_frame); |
# else /* STACK_GROWS_UP */ |
# else /* STACK_GROWS_UP */ |
GC_push_all_eager(cold_gc_frame, top); |
|
GC_push_all(bottom, cold_gc_frame + sizeof(ptr_t)); |
GC_push_all(bottom, cold_gc_frame + sizeof(ptr_t)); |
|
GC_push_all_eager(cold_gc_frame, top); |
# endif /* STACK_GROWS_UP */ |
# endif /* STACK_GROWS_UP */ |
} else { |
} else { |
GC_push_all_eager(bottom, top); |
GC_push_all_eager(bottom, top); |