summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorroot <siehputz@gmail.com>2020-07-24 23:28:41 -0500
committerroot <siehputz@gmail.com>2020-07-24 23:28:41 -0500
commitc4817968eee29257cbeaabace0a29fcbed1c3b47 (patch)
tree25108d321af3697e608270872e59b5aec2043cc5 /py
parentd9503e579b72d8bad6f556589da50ba9833b4574 (diff)
parent3dfed3c4aa52d06bd2eb1c28d0a1916821cc3f80 (diff)
Merge branch 'opt-test' of https://github.com/DavePutz/circuitpython into opt-test
Diffstat (limited to 'py')
-rw-r--r--py/circuitpy_defns.mk6
-rw-r--r--py/circuitpy_mpconfig.h12
-rw-r--r--py/circuitpy_mpconfig.mk3
-rw-r--r--py/compile.c2
-rw-r--r--py/emitglue.c2
-rwxr-xr-xpy/gc.c16
-rw-r--r--py/obj.h2
-rw-r--r--py/objgenerator.c19
-rw-r--r--py/objstr.h4
-rw-r--r--py/py.mk5
-rw-r--r--py/runtime0.h1
11 files changed, 66 insertions, 6 deletions
diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk
index 815ee2e62..a39e0c9dd 100644
--- a/py/circuitpy_defns.mk
+++ b/py/circuitpy_defns.mk
@@ -174,6 +174,9 @@ endif
ifeq ($(CIRCUITPY__EVE),1)
SRC_PATTERNS += _eve/%
endif
+ifeq ($(CIRCUITPY_MEMORYMONITOR),1)
+SRC_PATTERNS += memorymonitor/%
+endif
ifeq ($(CIRCUITPY_MICROCONTROLLER),1)
SRC_PATTERNS += microcontroller/%
endif
@@ -398,6 +401,9 @@ SRC_SHARED_MODULE_ALL = \
gamepad/__init__.c \
gamepadshift/GamePadShift.c \
gamepadshift/__init__.c \
+ memorymonitor/__init__.c \
+ memorymonitor/AllocationAlarm.c \
+ memorymonitor/AllocationSize.c \
network/__init__.c \
os/__init__.c \
random/__init__.c \
diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h
index a7853fabd..a1a7ec238 100644
--- a/py/circuitpy_mpconfig.h
+++ b/py/circuitpy_mpconfig.h
@@ -430,6 +430,16 @@ extern const struct _mp_obj_module_t _eve_module;
#define _EVE_MODULE
#endif
+#if CIRCUITPY_MEMORYMONITOR
+extern const struct _mp_obj_module_t memorymonitor_module;
+#define MEMORYMONITOR_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_memorymonitor), (mp_obj_t)&memorymonitor_module },
+#define MEMORYMONITOR_ROOT_POINTERS mp_obj_t active_allocationsizes; \
+ mp_obj_t active_allocationalarms;
+#else
+#define MEMORYMONITOR_MODULE
+#define MEMORYMONITOR_ROOT_POINTERS
+#endif
+
#if CIRCUITPY_MICROCONTROLLER
extern const struct _mp_obj_module_t microcontroller_module;
#define MICROCONTROLLER_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)&microcontroller_module },
@@ -709,6 +719,7 @@ extern const struct _mp_obj_module_t watchdog_module;
JSON_MODULE \
MATH_MODULE \
_EVE_MODULE \
+ MEMORYMONITOR_MODULE \
MICROCONTROLLER_MODULE \
NEOPIXEL_WRITE_MODULE \
NETWORK_MODULE \
@@ -766,6 +777,7 @@ extern const struct _mp_obj_module_t watchdog_module;
mp_obj_t terminal_tilegrid_tiles; \
BOARD_UART_ROOT_POINTER \
FLASH_ROOT_POINTERS \
+ MEMORYMONITOR_ROOT_POINTERS \
NETWORK_ROOT_POINTERS \
void supervisor_run_background_tasks_if_tick(void);
diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk
index 2d4a5ecee..baa29e26b 100644
--- a/py/circuitpy_mpconfig.mk
+++ b/py/circuitpy_mpconfig.mk
@@ -118,6 +118,9 @@ CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH)
CIRCUITPY__EVE ?= 0
CFLAGS += -DCIRCUITPY__EVE=$(CIRCUITPY__EVE)
+CIRCUITPY_MEMORYMONITOR ?= 0
+CFLAGS += -DCIRCUITPY_MEMORYMONITOR=$(CIRCUITPY_MEMORYMONITOR)
+
CIRCUITPY_MICROCONTROLLER ?= 1
CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER)
diff --git a/py/compile.c b/py/compile.c
index 470811005..9b0d29998 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -1890,7 +1890,7 @@ STATIC void compile_async_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
// async def
compile_funcdef(comp, pns0);
scope_t *fscope = (scope_t*)pns0->nodes[4];
- fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
+ fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR | MP_SCOPE_FLAG_ASYNC;
} else if (MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_for_stmt) {
// async for
compile_async_for_stmt(comp, pns0);
diff --git a/py/emitglue.c b/py/emitglue.c
index 3a3174b0f..7635a73d6 100644
--- a/py/emitglue.c
+++ b/py/emitglue.c
@@ -152,7 +152,7 @@ mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_ar
// check for generator functions and if so wrap in generator object
if ((rc->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) {
- fun = mp_obj_new_gen_wrap(fun);
+ fun = mp_obj_new_gen_wrap(fun, (rc->scope_flags & MP_SCOPE_FLAG_ASYNC) != 0);
}
return fun;
diff --git a/py/gc.c b/py/gc.c
index 2f3f63522..69327060f 100755
--- a/py/gc.c
+++ b/py/gc.c
@@ -33,6 +33,10 @@
#include "supervisor/shared/safe_mode.h"
+#if CIRCUITPY_MEMORYMONITOR
+#include "shared-module/memorymonitor/__init__.h"
+#endif
+
#if MICROPY_ENABLE_GC
#if MICROPY_DEBUG_VERBOSE // print debugging info
@@ -653,6 +657,10 @@ void *gc_alloc(size_t n_bytes, bool has_finaliser, bool long_lived) {
gc_dump_alloc_table();
#endif
+ #if CIRCUITPY_MEMORYMONITOR
+ memorymonitor_track_allocation(end_block - start_block + 1);
+ #endif
+
return ret_ptr;
}
@@ -906,6 +914,10 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) {
gc_log_change(block, new_blocks);
#endif
+ #if CIRCUITPY_MEMORYMONITOR
+ memorymonitor_track_allocation(new_blocks);
+ #endif
+
return ptr_in;
}
@@ -935,6 +947,10 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) {
gc_log_change(block, new_blocks);
#endif
+ #if CIRCUITPY_MEMORYMONITOR
+ memorymonitor_track_allocation(new_blocks);
+ #endif
+
return ptr_in;
}
diff --git a/py/obj.h b/py/obj.h
index 8536e3333..e603d4a49 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -665,7 +665,7 @@ mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args, mp_obj_t def_kw_args, const byte *
mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data, const mp_uint_t *const_table);
mp_obj_t mp_obj_new_fun_viper(size_t n_args, void *fun_data, mp_uint_t type_sig);
mp_obj_t mp_obj_new_fun_asm(size_t n_args, void *fun_data, mp_uint_t type_sig);
-mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun);
+mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun, bool is_coroutine);
mp_obj_t mp_obj_new_closure(mp_obj_t fun, size_t n_closed, const mp_obj_t *closed);
mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items);
mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items);
diff --git a/py/objgenerator.c b/py/objgenerator.c
index 6ffcfae46..df421b60c 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -42,11 +42,13 @@
typedef struct _mp_obj_gen_wrap_t {
mp_obj_base_t base;
mp_obj_t *fun;
+ bool coroutine_generator;
} mp_obj_gen_wrap_t;
typedef struct _mp_obj_gen_instance_t {
mp_obj_base_t base;
mp_obj_dict_t *globals;
+ bool coroutine_generator;
mp_code_state_t code_state;
} mp_obj_gen_instance_t;
@@ -64,6 +66,7 @@ STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons
n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t));
o->base.type = &mp_type_gen_instance;
+ o->coroutine_generator = self->coroutine_generator;
o->globals = self_fun->globals;
o->code_state.fun_bc = self_fun;
o->code_state.ip = 0;
@@ -78,10 +81,11 @@ const mp_obj_type_t mp_type_gen_wrap = {
.unary_op = mp_generic_unary_op,
};
-mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun) {
+mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun, bool is_coroutine) {
mp_obj_gen_wrap_t *o = m_new_obj(mp_obj_gen_wrap_t);
o->base.type = &mp_type_gen_wrap;
o->fun = MP_OBJ_TO_PTR(fun);
+ o->coroutine_generator = is_coroutine;
return MP_OBJ_FROM_PTR(o);
}
@@ -91,6 +95,12 @@ mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun) {
STATIC void gen_instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind;
mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in);
+#if MICROPY_PY_ASYNC_AWAIT
+ if (self->coroutine_generator) {
+ mp_printf(print, "<coroutine object '%q' at %p>", mp_obj_fun_get_name(MP_OBJ_FROM_PTR(self->code_state.fun_bc)), self);
+ return;
+ }
+#endif
mp_printf(print, "<generator object '%q' at %p>", mp_obj_fun_get_name(MP_OBJ_FROM_PTR(self->code_state.fun_bc)), self);
}
@@ -194,6 +204,13 @@ STATIC mp_obj_t gen_resume_and_raise(mp_obj_t self_in, mp_obj_t send_value, mp_o
}
STATIC mp_obj_t gen_instance_iternext(mp_obj_t self_in) {
+#if MICROPY_PY_ASYNC_AWAIT
+ // This translate is literally too much for m0 boards
+ mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in);
+ if (self->coroutine_generator) {
+ mp_raise_TypeError(translate("'coroutine' object is not an iterator"));
+ }
+#endif
return gen_resume_and_raise(self_in, mp_const_none, MP_OBJ_NULL);
}
diff --git a/py/objstr.h b/py/objstr.h
index 4b5e2054e..cddc6a83a 100644
--- a/py/objstr.h
+++ b/py/objstr.h
@@ -77,8 +77,8 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s
mp_obj_t index, bool is_slice);
const byte *find_subbytes(const byte *haystack, size_t hlen, const byte *needle, size_t nlen, int direction);
-const char nibble_to_hex_upper[16];
-const char nibble_to_hex_lower[16];
+extern const char nibble_to_hex_upper[16];
+extern const char nibble_to_hex_lower[16];
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj);
diff --git a/py/py.mk b/py/py.mk
index 3cb505920..3e1d7989f 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -346,6 +346,11 @@ $(HEADER_BUILD)/qstrdefs.generated.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/
$(PY_BUILD)/qstr.o: $(HEADER_BUILD)/qstrdefs.generated.h
+# Standard C functions like memset need to be compiled with special flags so
+# the compiler does not optimise these functions in terms of themselves.
+CFLAGS_BUILTIN ?= -ffreestanding -fno-builtin -fno-lto
+$(BUILD)/lib/libc/string0.o: CFLAGS += $(CFLAGS_BUILTIN)
+
# Force nlr code to always be compiled with space-saving optimisation so
# that the function preludes are of a minimal and predictable form.
$(PY_BUILD)/nlr%.o: CFLAGS += -Os
diff --git a/py/runtime0.h b/py/runtime0.h
index a8089ea64..fb35c8a9f 100644
--- a/py/runtime0.h
+++ b/py/runtime0.h
@@ -33,6 +33,7 @@
#define MP_SCOPE_FLAG_VARKEYWORDS (0x02)
#define MP_SCOPE_FLAG_GENERATOR (0x04)
#define MP_SCOPE_FLAG_DEFKWARGS (0x08)
+#define MP_SCOPE_FLAG_ASYNC (0x10)
// types for native (viper) function signature
#define MP_NATIVE_TYPE_OBJ (0x00)