Author: Nicolas Truessel <ntrues...@njsm.de>
Branch: quad-color-gc
Changeset: r87021:636d1082681c
Date: 2016-09-12 11:08 +0200
http://bitbucket.org/pypy/pypy/changeset/636d1082681c/

Log:    Update qcgc codebase

diff --git a/rpython/translator/c/src/qcgc/allocator.c 
b/rpython/translator/c/src/qcgc/allocator.c
--- a/rpython/translator/c/src/qcgc/allocator.c
+++ b/rpython/translator/c/src/qcgc/allocator.c
@@ -215,7 +215,7 @@
 
 object_t *qcgc_fit_allocate(size_t bytes) {
 #if CHECKED
-       free_list_consistency_check();
+       //free_list_consistency_check();
 #endif
        size_t cells = bytes_to_cells(bytes);
        cell_t *mem;
diff --git a/rpython/translator/c/src/qcgc/config.h 
b/rpython/translator/c/src/qcgc/config.h
--- a/rpython/translator/c/src/qcgc/config.h
+++ b/rpython/translator/c/src/qcgc/config.h
@@ -13,8 +13,7 @@
 #define LOG_ALLOCATION 0                                       // Enable 
allocation log (warning:
                                                                                
        // significant performance impact)
 
-#define QCGC_SHADOWSTACK_SIZE 128                      // Number of initial 
entries for
-                                                                               
        // shadow stack
+#define QCGC_SHADOWSTACK_SIZE 163840           // Total shadowstack size
 #define QCGC_ARENA_BAG_INIT_SIZE 16                    // Initial size of the 
arena bag
 #define QCGC_ARENA_SIZE_EXP 20                         // Between 16 (64kB) 
and 20 (1MB)
 #define QCGC_LARGE_ALLOC_THRESHOLD_EXP 14      // Less than QCGC_ARENA_SIZE_EXP
@@ -52,3 +51,4 @@
 
 #define MAX(a,b) (((a)>(b))?(a):(b))
 #define MIN(a,b) (((a)<(b))?(a):(b))
+#define UNUSED(x) (void)(x)
diff --git a/rpython/translator/c/src/qcgc/gc_state.h 
b/rpython/translator/c/src/qcgc/gc_state.h
--- a/rpython/translator/c/src/qcgc/gc_state.h
+++ b/rpython/translator/c/src/qcgc/gc_state.h
@@ -25,7 +25,8 @@
  * Global state of the garbage collector
  */
 struct qcgc_state {
-       shadow_stack_t *shadow_stack;
+       object_t **shadow_stack;
+       object_t **shadow_stack_base;
        shadow_stack_t *prebuilt_objects;
        weakref_bag_t *weakrefs;
        gray_stack_t *gp_gray_stack;
diff --git a/rpython/translator/c/src/qcgc/qcgc.c 
b/rpython/translator/c/src/qcgc/qcgc.c
--- a/rpython/translator/c/src/qcgc/qcgc.c
+++ b/rpython/translator/c/src/qcgc/qcgc.c
@@ -5,10 +5,12 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/mman.h>
 
 #include "allocator.h"
+#include "event_logger.h"
 #include "hugeblocktable.h"
-#include "event_logger.h"
+#include "signal_handler.h"
 
 #define env_or_fallback(var, env_name, fallback) while(0) {            \
        char *env_val = getenv(env_name);                                       
                \
@@ -28,9 +30,11 @@
 static size_t incmark_threshold = QCGC_INCMARK_THRESHOLD;
 
 QCGC_STATIC void update_weakrefs(void);
+QCGC_STATIC void initialize_shadowstack(void);
+QCGC_STATIC void destroy_shadowstack(void);
 
 void qcgc_initialize(void) {
-       qcgc_state.shadow_stack = 
qcgc_shadow_stack_create(QCGC_SHADOWSTACK_SIZE);
+       initialize_shadowstack();
        qcgc_state.prebuilt_objects = qcgc_shadow_stack_create(16); // XXX
        qcgc_state.weakrefs = qcgc_weakref_bag_create(16); // XXX
        qcgc_state.gp_gray_stack = qcgc_gray_stack_create(16); // XXX
@@ -47,13 +51,15 @@
        env_or_fallback(major_collection_threshold, "QCGC_MAJOR_COLLECTION",
                        QCGC_MAJOR_COLLECTION_THRESHOLD);
        env_or_fallback(incmark_threshold, "QCGC_INCMARK", 
QCGC_INCMARK_THRESHOLD);
+
+       setup_signal_handler();
 }
 
 void qcgc_destroy(void) {
        qcgc_event_logger_destroy();
        qcgc_hbtable_destroy();
        qcgc_allocator_destroy();
-       free(qcgc_state.shadow_stack);
+       destroy_shadowstack();
        free(qcgc_state.prebuilt_objects);
        free(qcgc_state.weakrefs);
        free(qcgc_state.gp_gray_stack);
@@ -67,14 +73,14 @@
                qcgc_state.phase = GC_MARK;
                qcgc_push_object(object);
        }
-       qcgc_state.shadow_stack =
-               qcgc_shadow_stack_push(qcgc_state.shadow_stack, object);
+
+       *qcgc_state.shadow_stack = object;
+       qcgc_state.shadow_stack++;
 }
 
 object_t *qcgc_shadowstack_pop(void) {
-       object_t *result = qcgc_shadow_stack_top(qcgc_state.shadow_stack);
-       qcgc_state.shadow_stack = 
qcgc_shadow_stack_pop(qcgc_state.shadow_stack);
-       return result;
+       qcgc_state.shadow_stack--;
+       return *qcgc_state.shadow_stack;
 }
 
 
/*******************************************************************************
@@ -225,8 +231,10 @@
                // If we do this for the first time, push all roots.
                // All further changes to the roots (new additions) will be 
added
                // by qcgc_shadowstack_push
-               for (size_t i = 0; i < qcgc_state.shadow_stack->count; i++) {
-                       qcgc_push_object(qcgc_state.shadow_stack->items[i]);
+               for (object_t **it = qcgc_state.shadow_stack_base;
+                       it < qcgc_state.shadow_stack;
+                       it++) {
+                       qcgc_push_object(*it);
                }
 
                // If we do this for the first time, push all prebuilt objects.
@@ -483,3 +491,28 @@
                }
        }
 }
+
+QCGC_STATIC void *trap_page_addr(object_t **shadow_stack) {
+       object_t **shadow_stack_end = shadow_stack + QCGC_SHADOWSTACK_SIZE;
+       char *in_trap_page = (((char *)shadow_stack_end) + 4095);
+       void *rounded_trap_page = (void *)(((uintptr_t)in_trap_page) & (~4095));
+       return rounded_trap_page;
+}
+
+QCGC_STATIC void initialize_shadowstack(void) {
+       size_t stack_size = QCGC_SHADOWSTACK_SIZE * sizeof(object_t *);
+       // allocate stack + size for alignement + trap page
+       object_t **stack = (object_t **) malloc(stack_size + 8192);
+       assert(stack != NULL);
+       mprotect(trap_page_addr(stack), 4096, PROT_NONE);
+
+       qcgc_state.shadow_stack = stack;
+       qcgc_state.shadow_stack_base = stack;
+}
+
+QCGC_STATIC void destroy_shadowstack(void) {
+       mprotect(trap_page_addr(qcgc_state.shadow_stack_base), 4096, PROT_READ |
+                               PROT_WRITE);
+
+       free(qcgc_state.shadow_stack_base);
+}
diff --git a/rpython/translator/c/src/qcgc/signal_handler.c 
b/rpython/translator/c/src/qcgc/signal_handler.c
new file mode 100644
--- /dev/null
+++ b/rpython/translator/c/src/qcgc/signal_handler.c
@@ -0,0 +1,61 @@
+#include "signal_handler.h"
+
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "arena.h"
+#include "allocator.h"
+#include "gc_state.h"
+
+QCGC_STATIC void handle_error(int signo, siginfo_t *siginfo, void *context);
+QCGC_STATIC bool is_stack_overflow(void *addr);
+QCGC_STATIC bool is_in_arena(void *addr);
+
+void setup_signal_handler(void) {
+       struct sigaction sa;
+
+       sa.sa_handler = NULL;
+       sigemptyset(&sa.sa_mask);
+       sa.sa_flags = SA_SIGINFO | SA_NODEFER;
+       sa.sa_sigaction = &handle_error;
+
+       if (sigaction(SIGSEGV, &sa, NULL) < 0) {
+               perror("sigaction");
+               abort();
+       }
+}
+
+QCGC_STATIC void handle_error(int signo, siginfo_t *siginfo, void *context) {
+       UNUSED(signo);
+       UNUSED(context);
+
+       if (is_stack_overflow(siginfo->si_addr)) {
+               fprintf(stderr, "Stack overflow: Too many root objects\n");
+       } else if (is_in_arena(siginfo->si_addr)) {
+               fprintf(stderr, "Internal segmentation fault: accessing %p\n",
+                               siginfo->si_addr);
+       } else {
+               fprintf(stderr, "External segmentation fault: accessing %p\n",
+                               siginfo->si_addr);
+       }
+       exit(EXIT_FAILURE);
+}
+
+QCGC_STATIC bool is_stack_overflow(void *addr) {
+       void *shadow_stack_end = (void *)(qcgc_state.shadow_stack_base +
+               QCGC_SHADOWSTACK_SIZE);
+       return (addr >= shadow_stack_end && addr < shadow_stack_end + 8192);
+}
+
+QCGC_STATIC bool is_in_arena(void *addr) {
+       arena_t *arena = qcgc_arena_addr((cell_t *) addr);
+       size_t count = qcgc_allocator_state.arenas->count;
+       for (size_t i = 0; i < count; i++) {
+               if (arena == qcgc_allocator_state.arenas->items[i]) {
+                       return true;
+               }
+       }
+       return false;
+}
diff --git a/rpython/translator/c/src/qcgc/signal_handler.h 
b/rpython/translator/c/src/qcgc/signal_handler.h
new file mode 100644
--- /dev/null
+++ b/rpython/translator/c/src/qcgc/signal_handler.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "config.h"
+
+void setup_signal_handler(void);
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to