summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2018-07-08 23:21:38 -0400
committerGitHub <noreply@github.com>2018-07-08 23:21:38 -0400
commit64b9ee9c74dd3cc07400678caa7032d845358576 (patch)
treea726389ca1073f5de907591f12b6a8d2e20ce6b5 /py
parenta45659c59a26a108924de88adb7f8d969cd7e5fc (diff)
parent54179a01897ace60099b76690e7793d3241b1556 (diff)
Merge pull request #985 from tannewt/heap_tweaks3
A few heap related tweaks
Diffstat (limited to 'py')
-rwxr-xr-x[-rw-r--r--]py/builtinimport.c5
-rwxr-xr-x[-rw-r--r--]py/gc.c0
-rwxr-xr-x[-rw-r--r--]py/gc_long_lived.c2
-rwxr-xr-x[-rw-r--r--]py/mpconfig.h6
-rwxr-xr-x[-rw-r--r--]py/qstr.c10
5 files changed, 19 insertions, 4 deletions
diff --git a/py/builtinimport.c b/py/builtinimport.c
index 9f7d34dca..c1437da4c 100644..100755
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -31,6 +31,7 @@
#include "py/compile.h"
#include "py/gc_long_lived.h"
+#include "py/gc.h"
#include "py/objmodule.h"
#include "py/persistentcode.h"
#include "py/runtime.h"
@@ -468,6 +469,10 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
// (the module that was just loaded) is not a package. This will be caught
// on the next iteration because the file will not exist.
}
+
+ // Loading a module thrashes the heap significantly so we explicitly clean up
+ // afterwards.
+ gc_collect();
}
if (outer_module_obj != MP_OBJ_NULL) {
qstr s = qstr_from_strn(mod_str + last, i - last);
diff --git a/py/gc.c b/py/gc.c
index 2c2354e4c..2c2354e4c 100644..100755
--- a/py/gc.c
+++ b/py/gc.c
diff --git a/py/gc_long_lived.c b/py/gc_long_lived.c
index d34fde5d9..e30b389fa 100644..100755
--- a/py/gc_long_lived.c
+++ b/py/gc_long_lived.c
@@ -121,7 +121,7 @@ mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth){
} else if (MP_OBJ_IS_TYPE(obj, &mp_type_property)) {
mp_obj_property_t *prop = MP_OBJ_TO_PTR(obj);
return MP_OBJ_FROM_PTR(make_property_long_lived(prop, max_depth));
- } else if (MP_OBJ_IS_TYPE(obj, &mp_type_str)) {
+ } else if (MP_OBJ_IS_TYPE(obj, &mp_type_str) || MP_OBJ_IS_TYPE(obj, &mp_type_bytes)) {
mp_obj_str_t *str = MP_OBJ_TO_PTR(obj);
return MP_OBJ_FROM_PTR(make_str_long_lived(str));
} else if (MP_OBJ_IS_TYPE(obj, &mp_type_type)) {
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 765ae1e8f..74d7c2c92 100644..100755
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -130,6 +130,12 @@
#define MICROPY_ALLOC_QSTR_CHUNK_INIT (128)
#endif
+// Max number of entries in newly allocated QSTR pools. Smaller numbers may make QSTR lookups
+// slightly slower but reduce the waste of unused spots.
+#ifndef MICROPY_QSTR_POOL_MAX_ENTRIES
+#define MICROPY_QSTR_POOL_MAX_ENTRIES (64)
+#endif
+
// Initial amount for lexer indentation level
#ifndef MICROPY_ALLOC_LEXER_INDENT_INIT
#define MICROPY_ALLOC_LEXER_INDENT_INIT (10)
diff --git a/py/qstr.c b/py/qstr.c
index 49b2d9daa..de4dc6240 100644..100755
--- a/py/qstr.c
+++ b/py/qstr.c
@@ -144,14 +144,18 @@ STATIC qstr qstr_add(const byte *q_ptr) {
// make sure we have room in the pool for a new qstr
if (MP_STATE_VM(last_pool)->len >= MP_STATE_VM(last_pool)->alloc) {
- qstr_pool_t *pool = m_new_ll_obj_var_maybe(qstr_pool_t, const char*, MP_STATE_VM(last_pool)->alloc * 2);
+ uint32_t new_pool_length = MP_STATE_VM(last_pool)->alloc * 2;
+ if (new_pool_length > MICROPY_QSTR_POOL_MAX_ENTRIES) {
+ new_pool_length = MICROPY_QSTR_POOL_MAX_ENTRIES;
+ }
+ qstr_pool_t *pool = m_new_ll_obj_var_maybe(qstr_pool_t, const char*, new_pool_length);
if (pool == NULL) {
QSTR_EXIT();
- m_malloc_fail(MP_STATE_VM(last_pool)->alloc * 2);
+ m_malloc_fail(new_pool_length);
}
pool->prev = MP_STATE_VM(last_pool);
pool->total_prev_len = MP_STATE_VM(last_pool)->total_prev_len + MP_STATE_VM(last_pool)->len;
- pool->alloc = MP_STATE_VM(last_pool)->alloc * 2;
+ pool->alloc = new_pool_length;
pool->len = 0;
MP_STATE_VM(last_pool) = pool;
DEBUG_printf("QSTR: allocate new pool of size %d\n", MP_STATE_VM(last_pool)->alloc);