#ifdef MPROTECT_VDB
GC_INNER void GC_mprotect_stop(void);
GC_INNER void GC_mprotect_resume(void);
+# ifndef GC_NO_THREADS_DISCOVERY
+ GC_INNER void GC_darwin_register_mach_handler_thread(mach_port_t thread);
+# endif
#endif
#if defined(PARALLEL_MARK) && !defined(GC_NO_THREADS_DISCOVERY)
/* As GC_push_all but consider */
/* interior pointers as valid. */
+#if defined(WRAP_MARK_SOME) && defined(PARALLEL_MARK)
+ /* GC_mark_local does not handle memory protection faults yet. So, */
+ /* the static data regions are scanned immediately by GC_push_roots. */
+ GC_INNER void GC_push_conditional_eager(void *bottom, void *top,
+ GC_bool all);
+#endif
+
/* In the threads case, we push part of the current thread stack */
/* with GC_push_all_eager when we push the registers. This gets the */
/* callee-save registers that may disappear. The remainder of the */
GC_INNER GC_bool GC_is_static_root(void *p);
/* Is the address p in one of the registered static */
/* root sections? */
-#endif
+# ifdef TRACE_BUF
+ void GC_add_trace_entry(char *kind, word arg1, word arg2);
+# endif
+#endif /* !THREADS */
/* Black listing: */
#ifdef PRINT_BLACK_LIST
/* object is live. */
#endif
+GC_INNER GC_bool GC_collect_or_expand(word needed_blocks,
+ GC_bool ignore_off_page, GC_bool retry);
+
GC_INNER ptr_t GC_allocobj(size_t sz, int kind);
/* Make the indicated */
/* free list nonempty, and return its */
GC_EXTERN ptr_t * GC_gcjobjfreelist;
#endif
-#if defined(GWW_VDB) && defined(MPROTECT_VDB)
- GC_INNER GC_bool GC_gww_dirty_init(void);
- /* Defined in os_dep.c. Returns TRUE if GetWriteWatch is available. */
- /* May be called repeatedly. */
-#endif
+#ifdef MPROTECT_VDB
+# ifdef GWW_VDB
+ GC_INNER GC_bool GC_gww_dirty_init(void);
+ /* Returns TRUE if GetWriteWatch is available. */
+ /* May be called repeatedly. */
+# endif
+# ifdef USE_MUNMAP
+ GC_INNER GC_bool GC_mprotect_dirty_init(void);
+ GC_INNER GC_bool GC_has_unmapped_memory(void);
+# endif
+#endif /* MPROTECT_VDB */
#if defined(CHECKSUMS) || defined(PROC_VDB)
GC_INNER GC_bool GC_page_was_ever_dirty(struct hblk * h);
/* Could the page contain valid heap pointers? */
#endif
+#ifdef CHECKSUMS
+# if defined(MPROTECT_VDB) && !defined(DARWIN)
+ void GC_record_fault(struct hblk * h);
+# endif
+ void GC_check_dirty(void);
+#endif
+
GC_INNER void GC_default_print_heap_obj_proc(ptr_t p);
GC_INNER void GC_setpagesize(void);
# ifdef MPROTECT_VDB
GC_INNER void GC_set_write_fault_handler(void);
# endif
+# if defined(WRAP_MARK_SOME) && !defined(GC_PTHREADS)
+ GC_INNER GC_bool GC_started_thread_while_stopped(void);
+ /* Did we invalidate mark phase with an unexpected thread start? */
+# endif
#endif /* GC_WIN32_THREADS */
#ifdef THREADS
#ifdef SEARCH_FOR_DATA_START
GC_INNER void GC_init_linux_data_start(void);
+ ptr_t GC_find_limit(ptr_t, GC_bool);
#endif
#if defined(NETBSD) && defined(__ELF__)
GC_INNER void GC_init_netbsd_elf(void);
+ ptr_t GC_find_limit(ptr_t, GC_bool);
#endif
#ifdef UNIX_LIKE
GC_INNER char *GC_parse_map_entry(char *buf_ptr, ptr_t *start, ptr_t *end,
char **prot, unsigned int *maj_dev,
char **mapping_name);
+# endif
+# if defined(IA64) || defined(INCLUDE_LINUX_THREAD_DESCR)
+ GC_INNER GC_bool GC_enclosing_mapping(ptr_t addr,
+ ptr_t *startp, ptr_t *endp);
# endif
GC_INNER char *GC_get_maps(void); /* from os_dep.c */
#endif /* NEED_PROC_MAPS */
/* Do we need the GC_find_limit machinery to find the end of a */
/* data segment. */
-#if defined(HEURISTIC2) || defined(SEARCH_FOR_DATA_START)
-# define NEED_FIND_LIMIT
-#endif
-
-#if !defined(STACKBOTTOM) && defined(HEURISTIC2)
-# define NEED_FIND_LIMIT
-#endif
-
-#if (defined(SVR4) || defined(AIX) || defined(DGUX) \
- || (defined(LINUX) && defined(SPARC))) && !defined(PCR)
+#if defined(HEURISTIC2) || defined(SEARCH_FOR_DATA_START) \
+ || (!defined(STACKBOTTOM) && defined(HEURISTIC2)) \
+ || ((defined(SVR4) || defined(AIX) || defined(DGUX) \
+ || (defined(LINUX) && defined(SPARC))) && !defined(PCR))
# define NEED_FIND_LIMIT
#endif
# define GC_INNER_PTHRSTART GC_INNER
#endif
+GC_INNER_PTHRSTART void * GC_CALLBACK GC_inner_start_routine(
+ struct GC_stack_base *sb, void *arg);
+
GC_INNER_PTHRSTART GC_thread GC_start_rtn_prepare_thread(
void *(**pstart)(void *),
void **pstart_arg,
/* we take care of an individual thread freelist structure. */
GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p);
+#ifdef GC_ASSERTIONS
+ GC_bool GC_is_thread_tsd_valid(void *tsd);
+ void GC_check_tls_for(GC_tlfs p);
+# if defined(USE_CUSTOM_SPECIFIC)
+ void GC_check_tsd_marks(tsd *key);
+# endif
+#endif /* GC_ASSERTIONS */
+
#ifndef GC_ATTR_TLS_FAST
# define GC_ATTR_TLS_FAST /* empty */
#endif
return(TRUE);
}
-GC_INNER GC_bool GC_collect_or_expand(word needed_blocks,
- GC_bool ignore_off_page,
- GC_bool retry); /* from alloc.c */
-
/* Allocate a large block of size lb bytes. */
/* The block is not cleared. */
/* Flags is 0 or IGNORE_OFF_PAGE. */
scan_ptr = 0;
}
-#ifdef CHECKSUMS
- void GC_check_dirty(void);
-#endif
-
/* Initiate a garbage collection. Initiates a full collection if the */
/* mark state is invalid. */
GC_INNER void GC_initiate_gc(void)
}
# endif /* __GNUC__ && MSWIN32 */
-#if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)
- GC_INNER GC_bool GC_started_thread_while_stopped(void);
- /* In win32_threads.c. Did we invalidate mark phase with an */
- /* unexpected thread start? */
-#endif
-
GC_INNER GC_bool GC_mark_some(ptr_t cold_gc_frame)
{
GC_bool ret_val;
}
#if defined(WRAP_MARK_SOME) && defined(PARALLEL_MARK)
- /* GC_mark_local does not handle memory protection faults yet. So, */
- /* the static data regions are scanned immediately by GC_push_roots. */
- GC_INNER void GC_push_conditional_eager(void *bottom, void *top,
- GC_bool all);
# define GC_PUSH_CONDITIONAL(b, t, all) \
(GC_parallel \
? GC_push_conditional_eager(b, t, all) \
#else /* !THREADS */
-# ifdef TRACE_BUF
- /* Defined in mark.c. */
- void GC_add_trace_entry(char *kind, word arg1, word arg2);
-# endif
-
/* Similar to GC_push_all_eager, but only the */
/* part hotter than cold_gc_frame is scanned */
/* immediately. Needed to ensure that callee- */
ptr_t GC_data_start = NULL;
- ptr_t GC_find_limit(ptr_t, GC_bool);
-
GC_INNER void GC_init_linux_data_start(void)
{
ptr_t data_end = DATAEND;
#if defined(NETBSD) && defined(__ELF__)
ptr_t GC_data_start = NULL;
- ptr_t GC_find_limit(ptr_t, GC_bool);
extern char **environ;
#ifndef DARWIN
-# ifdef CHECKSUMS
- void GC_record_fault(struct hblk * h); /* from checksums.c */
-# endif
-
# if !defined(MSWIN32) && !defined(MSWINCE)
# include <errno.h>
# if defined(FREEBSD) || defined(HURD) || defined(HPUX)
}
#ifdef USE_MUNMAP
- GC_INNER GC_bool GC_has_unmapped_memory(void); /* from allchblk.c */
- GC_INNER GC_bool GC_mprotect_dirty_init(void);
-
/* MPROTECT_VDB cannot deal with address space holes (for now), */
/* so if the collector is configured with both MPROTECT_VDB and */
/* USE_MUNMAP then, as a work around, select only one of them */
GC_mprotect_thread_notify(ID_RESUME);
}
-# ifndef GC_NO_THREADS_DISCOVERY
- GC_INNER void GC_darwin_register_mach_handler_thread(mach_port_t thread);
-# endif
-
#else
/* The compiler should optimize away any GC_mprotect_state computations */
# define GC_mprotect_state GC_MP_NORMAL
}
# if defined(GC_ASSERTIONS)
- void GC_check_tls_for(GC_tlfs p);
-# if defined(USE_CUSTOM_SPECIFIC)
- void GC_check_tsd_marks(tsd *key);
-# endif
-
/* Check that all thread-local free-lists are completely marked. */
/* Also check that thread-specific-data structures are marked. */
void GC_check_tls(void)
#ifdef INCLUDE_LINUX_THREAD_DESCR
__thread int GC_dummy_thread_local;
- GC_INNER GC_bool GC_enclosing_mapping(ptr_t addr,
- ptr_t *startp, ptr_t *endp);
#endif
#ifdef PARALLEL_MARK
}
#if !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2)
- GC_INNER_PTHRSTART void * GC_CALLBACK GC_inner_start_routine(
- struct GC_stack_base *sb, void *arg);
- /* defined in pthread_start.c */
-
STATIC void * GC_start_routine(void * arg)
{
# ifdef INCLUDE_LINUX_THREAD_DESCR
# endif
}
-#ifdef GC_ASSERTIONS
- /* Defined in pthread_support.c or win32_threads.c. */
- GC_bool GC_is_thread_tsd_valid(void *tsd);
-#endif
-
GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_kind(size_t bytes, int knd)
{
size_t granules;
}
# if defined(GC_ASSERTIONS)
- void GC_check_tls_for(GC_tlfs p);
-# if defined(USE_CUSTOM_SPECIFIC)
- void GC_check_tsd_marks(tsd *key);
-# endif
/* Check that all thread-local free-lists are completely marked. */
/* also check that thread-specific-data structures are marked. */
void GC_check_tls(void)