summaryrefslogtreecommitdiffstatshomepage
path: root/unix
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2015-11-07 23:04:42 +0300
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2015-11-08 16:05:33 +0200
commit6e68a68d18c53789e5a1179b0c0d83246e562ab6 (patch)
tree2684249b33e620b4565a6e4af801013b8115c7dd /unix
parent57e00ef26236264bc54ad32442df5854aa0df27b (diff)
downloadmicropython-6e68a68d18c53789e5a1179b0c0d83246e562ab6.tar.gz
micropython-6e68a68d18c53789e5a1179b0c0d83246e562ab6.zip
unix/gccollect: Fallback to setjmp-based register fetching automatically.
Now, if we build for an architecture which doesn't have dedicated support for getting registers for GC scanning, fallback to setjmp-based method automatically. It's still possible to force setjmp-based implementation on archs with dedicated support (e.g. for testing, or for peculiar calling conventions/optimizations).
Diffstat (limited to 'unix')
-rw-r--r--unix/gccollect.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/unix/gccollect.c b/unix/gccollect.c
index 4c5db6a4fd..007fbfcdbc 100644
--- a/unix/gccollect.c
+++ b/unix/gccollect.c
@@ -31,22 +31,15 @@
#if MICROPY_ENABLE_GC
-#if MICROPY_GCREGS_SETJMP
-#include <setjmp.h>
-
-typedef jmp_buf regs_t;
-
-STATIC void gc_helper_get_regs(regs_t arr) {
- setjmp(arr);
-}
-
-#else // !MICROPY_GCREGS_SETJMP
+// Even if we have specific support for an architecture, it is
+// possible to force use of setjmp-based implementation.
+#if !MICROPY_GCREGS_SETJMP
// We capture here callee-save registers, i.e. ones which may contain
// interesting values held there by our callers. It doesn't make sense
// to capture caller-saved registers, because they, well, put on the
// stack already by the caller.
-#ifdef __x86_64__
+#if defined(__x86_64__)
typedef mp_uint_t regs_t[6];
STATIC void gc_helper_get_regs(regs_t arr) {
@@ -77,9 +70,9 @@ STATIC void gc_helper_get_regs(regs_t arr) {
arr[4] = r14;
arr[5] = r15;
}
-#endif
-#ifdef __i386__
+#elif defined(__i386__)
+
typedef mp_uint_t regs_t[4];
STATIC void gc_helper_get_regs(regs_t arr) {
@@ -92,9 +85,9 @@ STATIC void gc_helper_get_regs(regs_t arr) {
arr[2] = edi;
arr[3] = ebp;
}
-#endif
-#if defined(__thumb2__) || defined(__thumb__) || defined(__arm__)
+#elif defined(__thumb2__) || defined(__thumb__) || defined(__arm__)
+
typedef mp_uint_t regs_t[10];
STATIC void gc_helper_get_regs(regs_t arr) {
@@ -119,9 +112,30 @@ STATIC void gc_helper_get_regs(regs_t arr) {
arr[8] = r12;
arr[9] = r13;
}
-#endif
+
+#else
+
+// If we don't have architecture-specific optimized support,
+// just fall back to setjmp-based implementation.
+#undef MICROPY_GCREGS_SETJMP
+#define MICROPY_GCREGS_SETJMP (1)
+
+#endif // Arch-specific selection
#endif // !MICROPY_GCREGS_SETJMP
+// If MICROPY_GCREGS_SETJMP was requested explicitly, or if
+// we enabled it as a fallback above.
+#if MICROPY_GCREGS_SETJMP
+#include <setjmp.h>
+
+typedef jmp_buf regs_t;
+
+STATIC void gc_helper_get_regs(regs_t arr) {
+ setjmp(arr);
+}
+
+#endif // MICROPY_GCREGS_SETJMP
+
void gc_collect(void) {
//gc_dump_info();