+2009-12-08 Ivan Maidanski <ivmai@mail.ru> (really mostly Hans Boehm)
+
+ * darwin_stop_world.c (GC_push_all_stacks): Rename
+ activation_frame to traced_stack_sect.
+ * include/private/gc_priv.h (GC_push_all_stack_frames,
+ GC_push_all_register_frames): Ditto.
+ * include/private/pthread_support.h (GC_Thread_Rep): Ditto.
+ * mark_rts.c (GC_push_all_register_frames,
+ GC_push_all_stack_frames, GC_push_all_stack_part_eager_frames,
+ GC_push_current_stack): Ditto.
+ * pthread_stop_world.c (GC_push_all_stacks): Ditto.
+ * pthread_support.c (GC_call_with_gc_active): Ditto.
+ * win32_threads.c (GC_Thread_Rep, GC_call_with_gc_active,
+ GC_push_stack_for): Ditto.
+ * include/private/gc_priv.h (GC_activation_frame_s): Rename to
+ GC_traced_stack_sect_s.
+ * include/private/gc_priv.h (GC_activation_frame): Rename to
+ GC_traced_stack_sect.
+ * misc.c (GC_activation_frame, GC_call_with_gc_active): Ditto.
+ * doc/README.macros (UNICODE): Document.
+
2009-12-07 Ivan Maidanski <ivmai@mail.ru>
* doc/README.macros (GC_READ_ENV_FILE): Document (new macro).
GC_printf("Darwin: Stack for thread 0x%lx = [%p,%p)\n",
(unsigned long) p -> id, lo, hi);
# endif
- GC_push_all_stack_frames(lo, hi, p -> activation_frame);
+ GC_push_all_stack_frames(lo, hi, p -> traced_stack_sect);
total_size += hi - lo; /* lo <= hi */
} /* for(p=GC_threads[i]...) */
} /* for(i=0;i<THREAD_TABLE_SZ...) */
GC_DGUX386_THREADS Enables support for DB/UX on I386 threads.
See README.DGUX386. (Probably has not been tested recently.)
-GC_WIN32_THREADS Enables support for win32 threads. That makes sense
+GC_WIN32_THREADS Enables support for Win32 threads. That makes sense
for this Makefile only under Cygwin.
GC_WIN32_PTHREADS Enables support for Ming32 pthreads. This cannot be
you don't want to (or can't) look at. It may not work for
existing code, but it often does. Neither works on all platforms,
since some ports use malloc or calloc to obtain system memory.
- (Probably works for UNIX, and win32.) If you build with DBG_HDRS_ALL,
+ (Probably works for UNIX, and Win32.) If you build with DBG_HDRS_ALL,
you should only use GC_debug_malloc_replacement as a malloc
replacement.
EMPTY_GETENV_RESULTS Define to workaround a reputed Wine bug in getenv
(getenv() may return an empty string instead of NULL for a missing entry).
-GC_READ_ENV_FILE (win32 only) Read environment variables from the GC "env"
+GC_READ_ENV_FILE (Win32 only) Read environment variables from the GC "env"
file (named as the program name plus ".gc.env" extension). Useful for WinCE
targets (which have no getenv()). In the file, every variable is specified
in a separate line and the format is as "<name>=<value>" (without spaces).
getting cancelled in unexpected places.) Even without this option,
PTHREAD_CANCEL_ASYNCHRONOUS is never safe with the collector. (We could
argue about its safety without the collector.)
+
+UNICODE (Win32 only) Use the Unicode variant ('W') of the Win32 API instead
+ of ANSI/ASCII one ('A'). Useful for WinCE.
};
/* This is used by GC_call_with_gc_active(), GC_push_all_stack_frames(). */
-struct GC_activation_frame_s {
+struct GC_traced_stack_sect_s {
ptr_t saved_stack_ptr;
#ifdef IA64
ptr_t saved_backing_store_ptr;
ptr_t backing_store_end;
#endif
- struct GC_activation_frame_s *prev;
+ struct GC_traced_stack_sect_s *prev;
};
#ifdef THREADS
-/* Process all activation "frames" - scan entire stack except for */
+/* Process all "traced stack sections" - scan entire stack except for */
/* frames belonging to the user functions invoked by GC_do_blocking(). */
GC_INNER void GC_push_all_stack_frames(ptr_t lo, ptr_t hi,
- struct GC_activation_frame_s *activation_frame);
+ struct GC_traced_stack_sect_s *traced_stack_sect);
GC_EXTERN word GC_total_stacksize; /* updated on every push_all_stacks */
#else
GC_EXTERN ptr_t GC_blocked_sp;
- GC_EXTERN struct GC_activation_frame_s *GC_activation_frame;
+ GC_EXTERN struct GC_traced_stack_sect_s *GC_traced_stack_sect;
/* Points to the "frame" data held in stack by */
/* the innermost GC_call_with_gc_active(). */
/* NULL if no such "frame" active. */
#ifdef IA64
/* Similar to GC_push_all_stack_frames() but for IA-64 registers store. */
GC_INNER void GC_push_all_register_frames(ptr_t bs_lo, ptr_t bs_hi,
- int eager, struct GC_activation_frame_s *activation_frame);
+ int eager, struct GC_traced_stack_sect_s *traced_stack_sect);
#endif
/* Marks are in a reserved area in */
ptr_t backing_store_ptr;
# endif
- struct GC_activation_frame_s *activation_frame;
+ struct GC_traced_stack_sect_s *traced_stack_sect;
/* Points to the "frame" data held in stack by */
/* the innermost GC_call_with_gc_active() of */
/* this thread. May be NULL. */
#ifdef IA64
/* Similar to GC_push_all_stack_frames() but for IA-64 registers store. */
GC_INNER void GC_push_all_register_frames(ptr_t bs_lo, ptr_t bs_hi,
- int eager, struct GC_activation_frame_s *activation_frame)
+ int eager, struct GC_traced_stack_sect_s *traced_stack_sect)
{
- while (activation_frame != NULL) {
- ptr_t frame_bs_lo = activation_frame -> backing_store_end;
+ while (traced_stack_sect != NULL) {
+ ptr_t frame_bs_lo = traced_stack_sect -> backing_store_end;
GC_ASSERT(frame_bs_lo <= bs_hi);
if (eager) {
GC_push_all_eager(frame_bs_lo, bs_hi);
} else {
GC_push_all_stack(frame_bs_lo, bs_hi);
}
- bs_hi = activation_frame -> saved_backing_store_ptr;
- activation_frame = activation_frame -> prev;
+ bs_hi = traced_stack_sect -> saved_backing_store_ptr;
+ traced_stack_sect = traced_stack_sect -> prev;
}
GC_ASSERT(bs_lo <= bs_hi);
if (eager) {
#ifdef THREADS
GC_INNER void GC_push_all_stack_frames(ptr_t lo, ptr_t hi,
- struct GC_activation_frame_s *activation_frame)
+ struct GC_traced_stack_sect_s *traced_stack_sect)
{
- while (activation_frame != NULL) {
- GC_ASSERT(lo HOTTER_THAN (ptr_t)activation_frame);
+ while (traced_stack_sect != NULL) {
+ GC_ASSERT(lo HOTTER_THAN (ptr_t)traced_stack_sect);
# ifdef STACK_GROWS_UP
- GC_push_all_stack((ptr_t)activation_frame, lo);
+ GC_push_all_stack((ptr_t)traced_stack_sect, lo);
# else /* STACK_GROWS_DOWN */
- GC_push_all_stack(lo, (ptr_t)activation_frame);
+ GC_push_all_stack(lo, (ptr_t)traced_stack_sect);
# endif
- lo = activation_frame -> saved_stack_ptr;
+ lo = traced_stack_sect -> saved_stack_ptr;
GC_ASSERT(lo != NULL);
- activation_frame = activation_frame -> prev;
+ traced_stack_sect = traced_stack_sect -> prev;
}
GC_ASSERT(!(hi HOTTER_THAN lo));
# ifdef STACK_GROWS_UP
/* Similar to GC_push_all_stack_frames() but also uses cold_gc_frame. */
STATIC void GC_push_all_stack_part_eager_frames(ptr_t lo, ptr_t hi,
- ptr_t cold_gc_frame, struct GC_activation_frame_s *activation_frame)
+ ptr_t cold_gc_frame, struct GC_traced_stack_sect_s *traced_stack_sect)
{
- GC_ASSERT(activation_frame == NULL || cold_gc_frame == NULL ||
- cold_gc_frame HOTTER_THAN (ptr_t)activation_frame);
+ GC_ASSERT(traced_stack_sect == NULL || cold_gc_frame == NULL ||
+ cold_gc_frame HOTTER_THAN (ptr_t)traced_stack_sect);
- while (activation_frame != NULL) {
- GC_ASSERT(lo HOTTER_THAN (ptr_t)activation_frame);
+ while (traced_stack_sect != NULL) {
+ GC_ASSERT(lo HOTTER_THAN (ptr_t)traced_stack_sect);
# ifdef STACK_GROWS_UP
- GC_push_all_stack_partially_eager((ptr_t)activation_frame, lo,
- cold_gc_frame);
+ GC_push_all_stack_partially_eager((ptr_t)traced_stack_sect, lo,
+ cold_gc_frame);
# else /* STACK_GROWS_DOWN */
- GC_push_all_stack_partially_eager(lo, (ptr_t)activation_frame,
- cold_gc_frame);
+ GC_push_all_stack_partially_eager(lo, (ptr_t)traced_stack_sect,
+ cold_gc_frame);
# endif
- lo = activation_frame -> saved_stack_ptr;
+ lo = traced_stack_sect -> saved_stack_ptr;
GC_ASSERT(lo != NULL);
- activation_frame = activation_frame -> prev;
+ traced_stack_sect = traced_stack_sect -> prev;
cold_gc_frame = NULL; /* Use at most once. */
}
# endif
# else
GC_push_all_stack_part_eager_frames(GC_approx_sp(), GC_stackbottom,
- cold_gc_frame, GC_activation_frame);
+ cold_gc_frame, GC_traced_stack_sect);
# ifdef IA64
/* We also need to push the register stack backing store. */
/* This should really be done in the same way as the */
if (GC_all_interior_pointers &&
cold_gc_bs_pointer > BACKING_STORE_BASE) {
/* Adjust cold_gc_bs_pointer if below our innermost */
- /* "activation frame" in backing store. */
- if (GC_activation_frame != NULL && cold_gc_bs_pointer <
- GC_activation_frame->backing_store_end)
+ /* "traced stack section" in backing store. */
+ if (GC_traced_stack_sect != NULL && cold_gc_bs_pointer <
+ GC_traced_stack_sect->backing_store_end)
cold_gc_bs_pointer =
- GC_activation_frame->backing_store_end;
+ GC_traced_stack_sect->backing_store_end;
GC_push_all_register_frames(BACKING_STORE_BASE,
- cold_gc_bs_pointer, FALSE, GC_activation_frame);
+ cold_gc_bs_pointer, FALSE, GC_traced_stack_sect);
GC_push_all_eager(cold_gc_bs_pointer, bsp);
} else {
GC_push_all_register_frames(BACKING_STORE_BASE, bsp,
- TRUE /* eager */, GC_activation_frame);
+ TRUE /* eager */, GC_traced_stack_sect);
}
/* All values should be sufficiently aligned that we */
/* don't have to worry about the boundary. */
STATIC ptr_t GC_blocked_register_sp = NULL;
# endif
-GC_INNER struct GC_activation_frame_s *GC_activation_frame = NULL;
+GC_INNER struct GC_traced_stack_sect_s *GC_traced_stack_sect = NULL;
/* This is nearly the same as in win32_threads.c */
GC_API void * GC_CALL GC_call_with_gc_active(GC_fn_type fn,
void * client_data)
{
- struct GC_activation_frame_s frame;
+ struct GC_traced_stack_sect_s frame;
GC_ASSERT(GC_is_initialized);
/* Adjust our stack base value (this could happen if */
/* but that probably doesn't hurt. */
frame.saved_backing_store_ptr = GC_blocked_register_sp;
# endif
- frame.prev = GC_activation_frame;
+ frame.prev = GC_traced_stack_sect;
GC_blocked_sp = NULL;
- GC_activation_frame = &frame;
+ GC_traced_stack_sect = &frame;
client_data = fn(client_data);
GC_ASSERT(GC_blocked_sp == NULL);
- GC_ASSERT(GC_activation_frame == &frame);
+ GC_ASSERT(GC_traced_stack_sect == &frame);
/* Restore original "frame". */
- GC_activation_frame = frame.prev;
+ GC_traced_stack_sect = frame.prev;
# ifdef IA64
GC_blocked_register_sp = frame.saved_backing_store_ptr;
# endif
(unsigned)(p -> id), lo, hi);
# endif
if (0 == lo) ABORT("GC_push_all_stacks: sp not set!");
- GC_push_all_stack_frames(lo, hi, p -> activation_frame);
+ GC_push_all_stack_frames(lo, hi, p -> traced_stack_sect);
# ifdef STACK_GROWS_UP
total_size += lo - hi;
# else
# endif
/* FIXME: This (if p->id==me) may add an unbounded number of */
/* entries, and hence overflow the mark stack, which is bad. */
- GC_push_all_register_frames(bs_lo, bs_hi,
- THREAD_EQUAL(p -> id, me), p -> activation_frame);
+ GC_push_all_register_frames(bs_lo, bs_hi, THREAD_EQUAL(p -> id, me),
+ p -> traced_stack_sect);
total_size += bs_hi - bs_lo; /* bs_lo <= bs_hi */
# endif
}
GC_API void * GC_CALL GC_call_with_gc_active(GC_fn_type fn,
void * client_data)
{
- struct GC_activation_frame_s frame;
+ struct GC_traced_stack_sect_s frame;
GC_thread me;
LOCK(); /* This will block if the world is stopped. */
me = GC_lookup_thread(pthread_self());
/* but that probably doesn't hurt. */
frame.saved_backing_store_ptr = me -> backing_store_ptr;
# endif
- frame.prev = me -> activation_frame;
+ frame.prev = me -> traced_stack_sect;
me -> thread_blocked = FALSE;
- me -> activation_frame = &frame;
+ me -> traced_stack_sect = &frame;
UNLOCK();
client_data = fn(client_data);
GC_ASSERT(me -> thread_blocked == FALSE);
- GC_ASSERT(me -> activation_frame == &frame);
+ GC_ASSERT(me -> traced_stack_sect == &frame);
/* Restore original "frame". */
LOCK();
- me -> activation_frame = frame.prev;
+ me -> traced_stack_sect = frame.prev;
# ifdef IA64
me -> backing_store_ptr = frame.saved_backing_store_ptr;
# endif
/* pointer manipulations. Thus it does */
/* not need to stop this thread. */
- struct GC_activation_frame_s *activation_frame;
+ struct GC_traced_stack_sect_s *traced_stack_sect;
/* Points to the "frame" data held in stack by */
/* the innermost GC_call_with_gc_active() of */
/* this thread. May be NULL. */
GC_API void * GC_CALL GC_call_with_gc_active(GC_fn_type fn,
void * client_data)
{
- struct GC_activation_frame_s frame;
+ struct GC_traced_stack_sect_s frame;
GC_thread me;
LOCK(); /* This will block if the world is stopped. */
me = GC_lookup_thread_inner(GetCurrentThreadId());
/* but that probably doesn't hurt. */
frame.saved_backing_store_ptr = me -> backing_store_ptr;
# endif
- frame.prev = me -> activation_frame;
+ frame.prev = me -> traced_stack_sect;
me -> thread_blocked_sp = NULL;
- me -> activation_frame = &frame;
+ me -> traced_stack_sect = &frame;
UNLOCK();
client_data = fn(client_data);
GC_ASSERT(me -> thread_blocked_sp == NULL);
- GC_ASSERT(me -> activation_frame == &frame);
+ GC_ASSERT(me -> traced_stack_sect == &frame);
/* Restore original "frame". */
LOCK();
- me -> activation_frame = frame.prev;
+ me -> traced_stack_sect = frame.prev;
# ifdef IA64
me -> backing_store_ptr = frame.saved_backing_store_ptr;
# endif
int dummy;
ptr_t sp, stack_min;
- struct GC_activation_frame_s *activation_frame =
- thread -> activation_frame;
+ struct GC_traced_stack_sect_s *traced_stack_sect =
+ thread -> traced_stack_sect;
if (thread -> id == me) {
GC_ASSERT(thread -> thread_blocked_sp == NULL);
sp = (ptr_t) &dummy;
if (thread -> last_stack_min == ADDR_LIMIT) {
# ifdef MSWINCE
if (GC_dont_query_stack_min) {
- stack_min = GC_wince_evaluate_stack_min(activation_frame != NULL ?
- (ptr_t)activation_frame : thread -> stack_base);
+ stack_min = GC_wince_evaluate_stack_min(traced_stack_sect != NULL ?
+ (ptr_t)traced_stack_sect : thread -> stack_base);
/* Keep last_stack_min value unmodified. */
} else
# endif
/* else */ {
- stack_min = GC_get_stack_min(activation_frame != NULL ?
- (ptr_t)activation_frame : thread -> stack_base);
+ stack_min = GC_get_stack_min(traced_stack_sect != NULL ?
+ (ptr_t)traced_stack_sect : thread -> stack_base);
UNPROTECT_THREAD(thread);
thread -> last_stack_min = stack_min;
}
} else {
/* First, adjust the latest known minimum stack address if we */
/* are inside GC_call_with_gc_active(). */
- if (activation_frame != NULL &&
- thread -> last_stack_min > (ptr_t)activation_frame) {
+ if (traced_stack_sect != NULL &&
+ thread -> last_stack_min > (ptr_t)traced_stack_sect) {
UNPROTECT_THREAD(thread);
- thread -> last_stack_min = (ptr_t)activation_frame;
+ thread -> last_stack_min = (ptr_t)traced_stack_sect;
}
if (sp < thread -> stack_base && sp >= thread -> last_stack_min) {
GC_printf("Pushing stack for 0x%x from sp %p to %p from 0x%x\n",
(int)thread -> id, sp, thread -> stack_base, (int)me);
# endif
- GC_push_all_stack_frames(sp, thread->stack_base, activation_frame);
+ GC_push_all_stack_frames(sp, thread->stack_base, traced_stack_sect);
} else {
/* If not current thread then it is possible for sp to point to */
/* the guarded (untouched yet) page just below the current */
(int)thread -> id, stack_min,
thread -> stack_base, (int)me);
# endif
- /* Push everything - ignore activation "frames" data. */
+ /* Push everything - ignore "traced stack section" data. */
GC_push_all_stack(stack_min, thread->stack_base);
}
return thread->stack_base - sp; /* stack grows down */