from nonstandard places (e.g. from dynamic library data areas on a
machine on which the collector doesn't already understand them.) On
some machines, it may be desirable to set `GC_stackbottom` to a good
-approximation of the stack base. (This enhances code portability on
-HP PA machines, since there is no good way for the collector to
-compute this value.) Client code may include "gc.h", which defines
-all of the following, plus many others.
+approximation of the stack base (bottom).
+
+Client code may include "gc.h", which defines all of the following, plus many
+others.
1. `GC_malloc(bytes)` - Allocate an object of a given size. Unlike malloc,
the object is cleared before being returned to the user. `GC_malloc` will
USE_GET_STACKBASE_FOR_MAIN (Linux only) Use pthread_attr_getstack() instead
of __libc_stack_end (or instead of any hard-coded value) for getting the
- primordial thread stack base (useful if the client modifies the program's
+ primordial thread stack bottom (useful if the client modifies the program's
address space).
architecture has more than one stack per thread, and is not supported yet,
you will need to do more work. Grep for "IA64" in the source for an
example.)
- * `STACKBOTTOM` - Defined to be the cool end of the stack, which is usually
- the highest address in the stack. It must bound the region of the stack that
- contains pointers into the GC heap. With thread support, this must be the
- cold end of the main stack, which typically cannot be found in the same way
- as the other thread stacks. If this is not defined and none of the following
- three macros is defined, client code must explicitly set `GC_stackbottom`
- to an appropriate value before calling `GC_INIT` or any other `GC_` routine.
+ * `STACKBOTTOM` - Defined to be the cold end of the stack, which is usually
+ (i.e. when the stacks grow down) the highest address in the stack. It must
+ bound the region of the stack that contains pointers into the GC heap. With
+ thread support, this must be the cold end of the main stack, which typically
+ cannot be found in the same way as the other thread stacks. If this is not
+ defined and none of the following three macros is defined, client code must
+ explicitly set `GC_stackbottom` to an appropriate value before calling
+ `GC_INIT` or any other `GC_` routine.
* `LINUX_STACKBOTTOM` - May be defined instead of `STACKBOTTOM`. If defined,
then the cold end of the stack will be determined, we usually read it from
`/proc`.
* `HEURISTIC1` - May be defined instead of `STACKBOTTOM`. `STACK_GRAN`
should generally also be redefined. The cold end of the stack is determined
by taking an address inside `GC_init`s frame, and rounding it up to the next
- multiple of `STACK_GRAN`. This works well if the stack base is always
+ multiple of `STACK_GRAN`. This works well if the stack bottom is always
aligned to a large power of two. (`STACK_GRAN` is predefined to 0x1000000,
which is rarely optimal.)
* `HEURISTIC2` - May be defined instead of `STACKBOTTOM`. The cold end
incrementing it repeatedly in small steps (decrement if `STACK_GROWS_UP`),
and reading the value at each location. We remember the value when the first
Segmentation violation or Bus error is signaled, round that to the nearest
- plausible page boundary, and use that as the stack base.
+ plausible page boundary, and use that as the stack bottom.
* `DYNAMIC_LOADING` - Should be defined if `dyn_load.c` has been updated for
this platform and tracing of dynamic library roots is supported.
* `GWW_VDB`, `MPROTECT_VDB`, `PROC_VDB` - May be defined if the
GC_API GC_ATTR_DEPRECATED char *GC_stackbottom;
- /* Cool end of user stack. */
+ /* The cold end (bottom) of user stack. */
/* May be set in the client prior to */
/* calling any GC_ routines. This */
/* avoids some overhead, and */
/* is to always make redundant registration safe. In the short run, */
/* this is being implemented a platform at a time. */
/* The interface is complicated by the fact that we probably will not */
-/* ever be able to automatically determine the stack base for thread */
+/* ever be able to automatically determine the stack bottom for thread */
/* stacks on all platforms. */
-/* Structure representing the base of a thread stack. On most */
-/* platforms this contains just a single address. */
+/* Structure representing the bottom (cold end) of a thread stack. */
+/* On most platforms this contains just a single address. */
struct GC_stack_base {
- void * mem_base; /* Base of memory stack. */
+ void * mem_base; /* the bottom of the general-purpose stack */
# if defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
- void * reg_base; /* Base of separate register stack. */
+ void * reg_base; /* the bottom of the register stack */
# endif
};
/* Call a function with a stack base structure corresponding to */
/* somewhere in the GC_call_with_stack_base frame. This often can */
-/* be used to provide a sufficiently accurate stack base. And we */
+/* be used to provide a sufficiently accurate stack bottom. And we */
/* implement it everywhere. */
GC_API void * GC_CALL GC_call_with_stack_base(GC_stack_base_func /* fn */,
void * /* arg */) GC_ATTR_NONNULL(1);
/* registering of a thread (it should be called as late as possible). */
GC_API void GC_CALL GC_allow_register_threads(void);
- /* Register the current thread, with the indicated stack base, as */
+ /* Register the current thread, with the indicated stack bottom, as */
/* a new thread whose stack(s) should be traced by the GC. If it */
/* is not implicitly called by the GC, this must be called before a */
/* thread can allocate garbage collected memory, or assign pointers */
/* initialized and the current thread is registered. fn may toggle */
/* the collector thread's state temporarily to "inactive" one by using */
/* GC_do_blocking. GC_call_with_gc_active() often can be used to */
-/* provide a sufficiently accurate stack base. */
+/* provide a sufficiently accurate stack bottom. */
GC_API void * GC_CALL GC_call_with_gc_active(GC_fn_type /* fn */,
void * /* client_data */) GC_ATTR_NONNULL(1);
-/* Attempt to fill in the GC_stack_base structure with the stack base */
+/* Attempt to fill in the GC_stack_base structure with the stack bottom */
/* for this thread. This appears to be required to implement anything */
/* like the JNI AttachCurrentThread in an environment in which new */
/* threads are not automatically registered with the collector. */
* cause failures on alpha*-*-* with -msmall-data or -fpic or mips-*-*
* without any special options.
*
- * STACKBOTTOM is the cool end of the stack, which is usually the
+ * STACKBOTTOM is the cold end of the stack, which is usually the
* highest address in the stack.
* Under PCR or OS/2, we have other ways of finding thread stacks.
* For each machine, the following should:
* LINUX_STACKBOTTOM
* HEURISTIC1
* HEURISTIC2
- * If STACKBOTTOM is defined, then its value will be used directly as the
- * stack base. If LINUX_STACKBOTTOM is defined, then it will be determined
+ * If STACKBOTTOM is defined, then its value will be used directly (as the
+ * stack bottom). If LINUX_STACKBOTTOM is defined, then it will be determined
* with a method appropriate for most Linux systems. Currently we look
* first for __libc_stack_end (currently only if USE_LIBC_PRIVATES is
* defined), and if that fails read it from /proc. (If USE_LIBC_PRIVATES
#if defined(LINUX_STACKBOTTOM) && defined(NO_PROC_STAT) \
&& !defined(USE_LIBC_PRIVATES)
/* This combination will fail, since we have no way to get */
- /* the stack base. Use HEURISTIC2 instead. */
+ /* the stack bottom. Use HEURISTIC2 instead. */
# undef LINUX_STACKBOTTOM
# define HEURISTIC2
/* This may still fail on some architectures like IA64. */
struct GC_traced_stack_sect_s stacksect;
GC_ASSERT(GC_is_initialized);
- /* Adjust our stack base value (this could happen if */
+ /* Adjust our stack bottom pointer (this could happen if */
/* GC_get_main_stack_base() is unimplemented or broken for */
/* the platform). */
if ((word)GC_stackbottom HOTTER_THAN (word)(&stacksect))
STATIC ptr_t GC_linux_main_stack_base(void)
{
- /* We read the stack base value from /proc/self/stat. We do this */
+ /* We read the stack bottom value from /proc/self/stat. We do this */
/* using direct I/O system calls in order to avoid calling malloc */
/* in case REDIRECT_MALLOC is defined. */
# ifndef STAT_READ
if (!stackbase_main_self && thr_main() != 0)
{
- /* Cache the stack base value for the primordial thread (this */
- /* is done during GC_init, so there is no race). */
+ /* Cache the stack bottom pointer for the primordial thread */
+ /* (this is done during GC_init, so there is no race). */
stackbase_main_ss_sp = s.ss_sp;
stackbase_main_self = self;
}
#ifndef HAVE_GET_STACK_BASE
# ifdef NEED_FIND_LIMIT
- /* Retrieve stack base. */
+ /* Retrieve the stack bottom. */
/* Using the GC_find_limit version is risky. */
/* On IA64, for example, there is no guard page between the */
/* stack of one thread and the register backing store of the */
LOCK(); /* This will block if the world is stopped. */
me = GC_lookup_thread(self);
- /* Adjust our stack base value (this could happen unless */
+ /* Adjust our stack bottom value (this could happen unless */
/* GC_get_stack_base() was used which returned GC_SUCCESS). */
if ((me -> flags & MAIN_THREAD) == 0) {
GC_ASSERT(me -> stack_end != NULL);
LOCK(); /* This will block if the world is stopped. */
me = GC_lookup_thread_inner(thread_id);
CHECK_LOOKUP_MY_THREAD(me);
- /* Adjust our stack base value (this could happen unless */
+ /* Adjust our stack bottom pointer (this could happen unless */
/* GC_get_stack_base() was used which returned GC_SUCCESS). */
GC_ASSERT(me -> stack_base != NULL);
if ((word)me->stack_base < (word)(&stacksect))