#include "genesis/static-symbols.h"
#include "genesis/primitive-objects.h"
#include "thread.h"
+#include "arch.h"
/* So you need to debug? */
#if 0
lispobj *new_space_free_pointer;
static void scavenge_newspace(void);
-static void scavenge_interrupt_contexts(void);
-
-extern unsigned long bytes_consed_between_gcs;
\f
/* collecting garbage */
}
#endif
-#define BYTES_ZERO_BEFORE_END (1<<12)
-
-/* FIXME do we need this? Doesn't it duplicate lisp code in
- * scrub-control-stack? */
-
-static void
-zero_stack(void)
-{
- lispobj *ptr = current_control_stack_pointer;
- search:
- do {
- if (*ptr)
- goto fill;
- ptr++;
- } while (((unsigned long)ptr) & (BYTES_ZERO_BEFORE_END-1));
- return;
- fill:
- do {
- *ptr++ = 0;
- } while (((unsigned long)ptr) & (BYTES_ZERO_BEFORE_END-1));
-
- goto search;
-}
-
-
void *
-gc_general_alloc(long bytes, int unboxed_p, int quick_p) {
+gc_general_alloc(long bytes, int page_type_flag, int quick_p) {
lispobj *new=new_space_free_pointer;
new_space_free_pointer+=(bytes/N_WORD_BYTES);
return new;
* last_generation argument. That's meaningless for us, since we're
* not a generational GC. So we ignore it. */
void
-collect_garbage(unsigned ignore)
+collect_garbage(generation_index_t ignore)
{
#ifdef PRINTNOISE
struct timeval start_tv, stop_tv;
/* it's possible that signals are blocked already if this was called
* from a signal handler (e.g. with the sigsegv gc_trigger stuff) */
- sigemptyset(&tmp);
- sigaddset_blockable(&tmp);
- thread_sigmask(SIG_BLOCK, &tmp, &old);
+ block_blockable_signals(0, &old);
current_static_space_free_pointer =
(lispobj *) ((unsigned long)
/* Scan the weak pointers. */
#ifdef PRINTNOISE
+ printf("Scanning weak hash tables ...\n");
+#endif
+ scan_weak_hash_tables();
+
+ /* Scan the weak pointers. */
+#ifdef PRINTNOISE
printf("Scanning weak pointers ...\n");
#endif
scan_weak_pointers();
-
/* Flip spaces. */
#ifdef PRINTNOISE
printf("Flipping spaces ...\n");
/* Maybe FIXME: it's possible that we could significantly reduce
* RSS by zeroing the from_space or madvise(MADV_DONTNEED) or
* similar os-dependent tricks here */
+#ifdef LISP_FEATURE_HPUX
+ /* hpux cant handle unmapping areas that are not 100% mapped */
+ clear_auto_gc_trigger();
+#endif
os_zero((os_vm_address_t) from_space,
- (os_vm_size_t) DYNAMIC_SPACE_SIZE);
+ (os_vm_size_t) dynamic_space_size);
current_dynamic_space = new_space;
dynamic_space_free_pointer = new_space_free_pointer;
#ifdef PRINTNOISE
printf("Zeroing empty part of control stack ...\n");
#endif
- zero_stack();
+ scrub_control_stack();
set_auto_gc_trigger(size_retained+bytes_consed_between_gcs);
thread_sigmask(SIG_SETMASK, &old, 0);
here,new_space_free_pointer); */
next = new_space_free_pointer;
scavenge(here, next - here);
+ scav_weak_hash_tables();
here = next;
}
/* printf("done with newspace\n"); */
0x7FFFFFFFFFFFFFFF on 64-bit platforms */
lip_offset = (((unsigned long)1) << (N_WORD_BITS - 1)) - 1;
lip_register_pair = -1;
- for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) {
+ for (i = 0; i < (int)(sizeof(boxed_registers) / sizeof(int)); i++) {
unsigned long reg;
- long offset;
+ unsigned long offset;
int index;
index = boxed_registers[i];
#endif
/* Scavenge all boxed registers in the context. */
- for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) {
+ for (i = 0; i < (int)(sizeof(boxed_registers) / sizeof(int)); i++) {
int index;
lispobj foo;
}
\f
-/* vector-like objects */
-
-static long
-scav_vector(lispobj *where, lispobj object)
-{
- if (HeaderValue(object) == subtype_VectorValidHashing) {
- *where =
- (subtype_VectorMustRehash<<N_WIDETAG_BITS) | SIMPLE_VECTOR_WIDETAG;
- }
-
- return 1;
-}
-
-\f
/* weak pointers */
#define WEAK_POINTER_NWORDS \
gc_init(void)
{
gc_init_tables();
- scavtab[SIMPLE_VECTOR_WIDETAG] = scav_vector;
scavtab[WEAK_POINTER_WIDETAG] = scav_weak_pointer;
}
(unsigned long)((os_vm_address_t)dynamic_space_free_pointer
- (os_vm_address_t)current_dynamic_space));
- length = os_trunc_size_to_page(DYNAMIC_SPACE_SIZE - dynamic_usage);
+ length = os_trunc_size_to_page(dynamic_space_size - dynamic_usage);
if (length < 0)
lose("set_auto_gc_trigger: tried to set gc trigger too high! (0x%08lx)\n",
(unsigned long)dynamic_usage);
-#if defined(SUNOS) || defined(SOLARIS)
+#if defined(SUNOS) || defined(SOLARIS) || defined(LISP_FEATURE_HPUX)
os_invalidate(addr, length);
#else
os_protect(addr, length, 0);
return;
addr = (os_vm_address_t)current_auto_gc_trigger;
- length = DYNAMIC_SPACE_SIZE + (os_vm_address_t)current_dynamic_space - addr;
+ length = dynamic_space_size + (os_vm_address_t)current_dynamic_space - addr;
-#if defined(SUNOS) || defined(SOLARIS)
+#if defined(SUNOS) || defined(SOLARIS) || defined(LISP_FEATURE_HPUX)
/* don't want to force whole space into swapping mode... */
os_validate(addr, length);
#else
current_auto_gc_trigger = NULL;
}
+
+static boolean
+gc_trigger_hit(void *addr)
+{
+ if (current_auto_gc_trigger == NULL)
+ return 0;
+ else{
+ return (addr >= (void *)current_auto_gc_trigger &&
+ addr <((void *)current_dynamic_space + dynamic_space_size));
+ }
+}
+
+boolean
+cheneygc_handle_wp_violation(os_context_t *context, void *addr)
+{
+ if(!foreign_function_call_active && gc_trigger_hit(addr)){
+ struct thread *thread=arch_os_get_current_thread();
+ clear_auto_gc_trigger();
+ /* Don't flood the system with interrupts if the need to gc is
+ * already noted. This can happen for example when SUB-GC
+ * allocates or after a gc triggered in a WITHOUT-GCING. */
+ if (SymbolValue(GC_PENDING,thread) == NIL) {
+ if (SymbolValue(GC_INHIBIT,thread) == NIL) {
+ if (arch_pseudo_atomic_atomic(context)) {
+ /* set things up so that GC happens when we finish
+ * the PA section */
+ SetSymbolValue(GC_PENDING,T,thread);
+ arch_set_pseudo_atomic_interrupted(context);
+ maybe_save_gc_mask_and_block_deferrables
+ (os_context_sigmask_addr(context));
+ } else {
+ maybe_gc(context);
+ }
+ } else {
+ SetSymbolValue(GC_PENDING,T,thread);
+ }
+ }
+ return 1;
+ }
+ return 0;
+}