summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2017-07-23 15:32:05 -0400
committerScott Shawcroft <scott@tannewt.org>2017-07-23 15:32:05 -0400
commitf91493c97e20eef1d39a9cdc6c42a25cfd511734 (patch)
tree7e7062c9c12220d798cfa154e0729b7cf3e6447b /py
parentaf1ede930ba643d68850c541ef4075d5f7fd4f02 (diff)
Measure and report maximum stack usage. (#175)
Add max stack usage tracking, visible via debug module ustack. Add separate cpp flag for enabling modules: MICROPY_DEBUG_MODULES
Diffstat (limited to 'py')
-rw-r--r--py/mpconfig.h5
-rw-r--r--py/mpstate.h4
-rw-r--r--py/objmodule.c2
-rw-r--r--py/stackctrl.c25
-rw-r--r--py/stackctrl.h8
5 files changed, 43 insertions, 1 deletions
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 39e773183..14c5af3e7 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -446,6 +446,11 @@
#define MICROPY_STACK_CHECK (0)
#endif
+// Whether to measure maximum stack excursion
+#ifndef MICROPY_MAX_STACK_USAGE
+#define MICROPY_MAX_STACK_USAGE (0)
+#endif
+
// Whether to have an emergency exception buffer
#ifndef MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (0)
diff --git a/py/mpstate.h b/py/mpstate.h
index 30785775b..0b195a096 100644
--- a/py/mpstate.h
+++ b/py/mpstate.h
@@ -221,6 +221,10 @@ typedef struct _mp_state_thread_t {
// Stack top at the start of program
char *stack_top;
+ #if MICROPY_MAX_STACK_USAGE
+ char* stack_bottom;
+ #endif
+
#if MICROPY_STACK_CHECK
size_t stack_limit;
#endif
diff --git a/py/objmodule.c b/py/objmodule.c
index 9171b2b22..1b9b9d65e 100644
--- a/py/objmodule.c
+++ b/py/objmodule.c
@@ -226,7 +226,7 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = {
// extra builtin modules as defined by a port
MICROPY_PORT_BUILTIN_MODULES
-#if defined(DEBUG) && defined(MICROPY_PORT_BUILTIN_DEBUG_MODULES)
+#if defined(MICROPY_DEBUG_MODULES) && defined(MICROPY_PORT_BUILTIN_DEBUG_MODULES)
, MICROPY_PORT_BUILTIN_DEBUG_MODULES
#endif
};
diff --git a/py/stackctrl.c b/py/stackctrl.c
index d9969b56c..202ae3d48 100644
--- a/py/stackctrl.c
+++ b/py/stackctrl.c
@@ -66,3 +66,28 @@ void mp_stack_check(void) {
}
#endif // MICROPY_STACK_CHECK
+
+#if MICROPY_MAX_STACK_USAGE
+
+// Fill stack space with this unusual value.
+const char MP_MAX_STACK_USAGE_SENTINEL_BYTE = 0xEE;
+
+// Record absolute bottom (logical limit) of stack.
+void mp_stack_set_bottom(void* stack_bottom) {
+ MP_STATE_THREAD(stack_bottom) = stack_bottom;
+}
+
+// Fill stack space down toward the stack limit with a known unusual value.
+void mp_stack_fill_with_sentinel(void) {
+ // Force routine to not be inlined. Better guarantee than MP_NOINLINE for -flto.
+ __asm volatile ("");
+ volatile char* volatile p;
+ // Start filling stack just below the last variable in the current stack frame, which is p.
+ // Continue until we've hit the bottom of the stack (lowest address, logical "ceiling" of stack).
+ p = (char *) (&p - 1);
+ while(p >= MP_STATE_THREAD(stack_bottom)) {
+ *p-- = MP_MAX_STACK_USAGE_SENTINEL_BYTE;
+ }
+}
+
+#endif // MICROPY_MAX_STACK_USAGE
diff --git a/py/stackctrl.h b/py/stackctrl.h
index e915f5000..2fb3784c5 100644
--- a/py/stackctrl.h
+++ b/py/stackctrl.h
@@ -45,4 +45,12 @@ void mp_stack_check(void);
#endif
+#if MICROPY_MAX_STACK_USAGE
+
+const char MP_MAX_STACK_USAGE_SENTINEL_BYTE;
+void mp_stack_set_bottom(void* stack_bottom);
+void mp_stack_fill_with_sentinel(void);
+
+#endif
+
#endif // __MICROPY_INCLUDED_PY_STACKCTRL_H__