#include "genesis/static-symbols.h"
#include "genesis/primitive-objects.h"
#include "thread.h"
+#include "arch.h"
/* So you need to debug? */
#if 0
static void scavenge_newspace(void);
-extern unsigned long bytes_consed_between_gcs;
-
\f
/* collecting garbage */
* RSS by zeroing the from_space or madvise(MADV_DONTNEED) or
* similar os-dependent tricks here */
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;
(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);
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)
/* don't want to force whole space into swapping mode... */
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);
+ } else {
+ maybe_gc(context);
+ }
+ } else {
+ SetSymbolValue(GC_PENDING,T,thread);
+ }
+ }
+ return 1;
+ }
+ return 0;
+}