Skip to content

Commit

Permalink
py: Put all global state together in state structures.
Browse files Browse the repository at this point in the history
This patch consolidates all global variables in py/ core into one place,
in a global structure.  Root pointers are all located together to make
GC tracing easier and more efficient.
  • Loading branch information
dpgeorge committed Jan 7, 2015
1 parent ad2307c commit b4b10fd
Show file tree
Hide file tree
Showing 34 changed files with 465 additions and 296 deletions.
3 changes: 2 additions & 1 deletion bare-arm/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#include "py/nlr.h"
#include "py/parsehelper.h"
#include "py/compile.h"
#include "py/runtime0.h"
#include "py/runtime.h"
#include "py/stackctrl.h"
#include "py/repl.h"
#include "py/pfenv.h"

Expand Down Expand Up @@ -48,6 +48,7 @@ void do_str(const char *src) {
}

int main(int argc, char **argv) {
mp_stack_set_limit(10240);
mp_init();
do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\n')");
mp_deinit();
Expand Down
3 changes: 2 additions & 1 deletion esp8266/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@
#include "py/compile.h"
#include "py/runtime0.h"
#include "py/runtime.h"
#include "py/stackctrl.h"
#include "py/gc.h"
#include "pyexec.h"
#include "gccollect.h"
#include MICROPY_HAL_H

void user_init(void) {
soft_reset:
//mp_stack_set_limit((char*)&_ram_end - (char*)&_heap_end - 1024);
mp_stack_set_limit(10240);
mp_hal_init();
gc_init(&_heap_start, &_heap_end);
gc_collect_init();
Expand Down
1 change: 0 additions & 1 deletion py/builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ extern const mp_obj_module_t mp_module_sys;
extern const mp_obj_module_t mp_module_gc;

extern const mp_obj_dict_t mp_module_builtins_globals;
extern mp_obj_dict_t *mp_module_builtins_override_dict;

struct _dummy_t;
extern struct _dummy_t mp_sys_stdin_obj;
Expand Down
3 changes: 2 additions & 1 deletion py/emitbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <string.h>
#include <assert.h>

#include "py/mpstate.h"
#include "py/emit.h"
#include "py/bc0.h"

Expand Down Expand Up @@ -383,7 +384,7 @@ STATIC void emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta) {
STATIC void emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) {
//printf("source: line %d -> %d offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->bytecode_offset);
#if MICROPY_ENABLE_SOURCE_LINE
if (mp_optimise_value >= 3) {
if (MP_STATE_VM(mp_optimise_value) >= 3) {
// If we compile with -O3, don't store line numbers.
return;
}
Expand Down
161 changes: 74 additions & 87 deletions py/gc.c

Large diffs are not rendered by default.

5 changes: 0 additions & 5 deletions py/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ void gc_lock(void);
void gc_unlock(void);
bool gc_is_locked(void);

// This variable controls auto garbage collection. If set to 0 then the
// GC won't automatically run when gc_alloc can't find enough blocks. But
// you can still allocate/free memory and also explicitly call gc_collect.
extern uint16_t gc_auto_collect_enabled;

// A given port must implement gc_collect by using the other collect functions.
void gc_collect(void);
void gc_collect_start(void);
Expand Down
5 changes: 2 additions & 3 deletions py/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@
#include <stdio.h>
#include <assert.h>

#include "py/mpstate.h"
#include "py/lexer.h"

#define TAB_SIZE (8)

// TODO seems that CPython allows NULL byte in the input stream
// don't know if that's intentional or not, but we don't allow it

mp_uint_t mp_optimise_value;

// TODO replace with a call to a standard function
STATIC bool str_strn_equal(const char *str, const char *strn, mp_uint_t len) {
mp_uint_t i = 0;
Expand Down Expand Up @@ -662,7 +661,7 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, bool first_token) {
if (str_strn_equal(tok_kw[i], lex->vstr.buf, lex->vstr.len)) {
if (i == MP_ARRAY_SIZE(tok_kw) - 1) {
// tok_kw[MP_ARRAY_SIZE(tok_kw) - 1] == "__debug__"
lex->tok_kind = (mp_optimise_value == 0 ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE);
lex->tok_kind = (MP_STATE_VM(mp_optimise_value) == 0 ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE);
} else {
lex->tok_kind = MP_TOKEN_KW_FALSE + i;
}
Expand Down
2 changes: 0 additions & 2 deletions py/lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,4 @@ typedef enum {
mp_import_stat_t mp_import_stat(const char *path);
mp_lexer_t *mp_lexer_new_from_file(const char *filename);

extern mp_uint_t mp_optimise_value;

#endif // __MICROPY_INCLUDED_PY_LEXER_H__
35 changes: 16 additions & 19 deletions py/malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "py/mpconfig.h"
#include "py/misc.h"
#include "py/mpstate.h"

#if 0 // print debugging info
#define DEBUG_printf DEBUG_printf
Expand All @@ -38,11 +39,7 @@
#endif

#if MICROPY_MEM_STATS
STATIC size_t total_bytes_allocated = 0;
STATIC size_t current_bytes_allocated = 0;
STATIC size_t peak_bytes_allocated = 0;

#define UPDATE_PEAK() { if (current_bytes_allocated > peak_bytes_allocated) peak_bytes_allocated = current_bytes_allocated; }
#define UPDATE_PEAK() { if (MP_STATE_MEM(current_bytes_allocated) > MP_STATE_MEM(peak_bytes_allocated)) MP_STATE_MEM(peak_bytes_allocated) = MP_STATE_MEM(current_bytes_allocated); }
#endif

#if MICROPY_ENABLE_GC
Expand All @@ -68,8 +65,8 @@ void *m_malloc(size_t num_bytes) {
return m_malloc_fail(num_bytes);
}
#if MICROPY_MEM_STATS
total_bytes_allocated += num_bytes;
current_bytes_allocated += num_bytes;
MP_STATE_MEM(total_bytes_allocated) += num_bytes;
MP_STATE_MEM(current_bytes_allocated) += num_bytes;
UPDATE_PEAK();
#endif
DEBUG_printf("malloc %d : %p\n", num_bytes, ptr);
Expand All @@ -79,8 +76,8 @@ void *m_malloc(size_t num_bytes) {
void *m_malloc_maybe(size_t num_bytes) {
void *ptr = malloc(num_bytes);
#if MICROPY_MEM_STATS
total_bytes_allocated += num_bytes;
current_bytes_allocated += num_bytes;
MP_STATE_MEM(total_bytes_allocated) += num_bytes;
MP_STATE_MEM(current_bytes_allocated) += num_bytes;
UPDATE_PEAK();
#endif
DEBUG_printf("malloc %d : %p\n", num_bytes, ptr);
Expand All @@ -94,8 +91,8 @@ void *m_malloc_with_finaliser(size_t num_bytes) {
return m_malloc_fail(num_bytes);
}
#if MICROPY_MEM_STATS
total_bytes_allocated += num_bytes;
current_bytes_allocated += num_bytes;
MP_STATE_MEM(total_bytes_allocated) += num_bytes;
MP_STATE_MEM(current_bytes_allocated) += num_bytes;
UPDATE_PEAK();
#endif
DEBUG_printf("malloc %d : %p\n", num_bytes, ptr);
Expand Down Expand Up @@ -124,8 +121,8 @@ void *m_realloc(void *ptr, size_t old_num_bytes, size_t new_num_bytes) {
// allocated total. If we process only positive increments,
// we'll count 3K.
size_t diff = new_num_bytes - old_num_bytes;
total_bytes_allocated += diff;
current_bytes_allocated += diff;
MP_STATE_MEM(total_bytes_allocated) += diff;
MP_STATE_MEM(current_bytes_allocated) += diff;
UPDATE_PEAK();
#endif
DEBUG_printf("realloc %p, %d, %d : %p\n", ptr, old_num_bytes, new_num_bytes, new_ptr);
Expand All @@ -143,8 +140,8 @@ void *m_realloc_maybe(void *ptr, size_t old_num_bytes, size_t new_num_bytes) {
// Also, don't count failed reallocs.
if (!(new_ptr == NULL && new_num_bytes != 0)) {
size_t diff = new_num_bytes - old_num_bytes;
total_bytes_allocated += diff;
current_bytes_allocated += diff;
MP_STATE_MEM(total_bytes_allocated) += diff;
MP_STATE_MEM(current_bytes_allocated) += diff;
UPDATE_PEAK();
}
#endif
Expand All @@ -155,21 +152,21 @@ void *m_realloc_maybe(void *ptr, size_t old_num_bytes, size_t new_num_bytes) {
void m_free(void *ptr, size_t num_bytes) {
free(ptr);
#if MICROPY_MEM_STATS
current_bytes_allocated -= num_bytes;
MP_STATE_MEM(current_bytes_allocated) -= num_bytes;
#endif
DEBUG_printf("free %p, %d\n", ptr, num_bytes);
}

#if MICROPY_MEM_STATS
size_t m_get_total_bytes_allocated(void) {
return total_bytes_allocated;
return MP_STATE_MEM(total_bytes_allocated);
}

size_t m_get_current_bytes_allocated(void) {
return current_bytes_allocated;
return MP_STATE_MEM(current_bytes_allocated);
}

size_t m_get_peak_bytes_allocated(void) {
return peak_bytes_allocated;
return MP_STATE_MEM(peak_bytes_allocated);
}
#endif
7 changes: 4 additions & 3 deletions py/modgc.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* THE SOFTWARE.
*/

#include "py/mpstate.h"
#include "py/obj.h"
#include "py/gc.h"

Expand All @@ -48,21 +49,21 @@ MP_DEFINE_CONST_FUN_OBJ_0(gc_collect_obj, py_gc_collect);
/// \function disable()
/// Disable the garbage collector.
STATIC mp_obj_t gc_disable(void) {
gc_auto_collect_enabled = 0;
MP_STATE_MEM(gc_auto_collect_enabled) = 0;
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(gc_disable_obj, gc_disable);

/// \function enable()
/// Enable the garbage collector.
STATIC mp_obj_t gc_enable(void) {
gc_auto_collect_enabled = 1;
MP_STATE_MEM(gc_auto_collect_enabled) = 1;
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(gc_enable_obj, gc_enable);

STATIC mp_obj_t gc_isenabled(void) {
return MP_BOOL(gc_auto_collect_enabled);
return MP_BOOL(MP_STATE_MEM(gc_auto_collect_enabled));
}
MP_DEFINE_CONST_FUN_OBJ_0(gc_isenabled_obj, gc_isenabled);

Expand Down
5 changes: 5 additions & 0 deletions py/mpconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,11 @@ typedef double mp_float_t;
#define MICROPY_PORT_CONSTANTS
#endif

// Any root pointers for GC scanning - see mpstate.c
#ifndef MICROPY_PORT_ROOT_POINTERS
#define MICROPY_PORT_ROOT_POINTERS
#endif

/*****************************************************************************/
/* Miscellaneous settings */

Expand Down
29 changes: 29 additions & 0 deletions py/mpstate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2014 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "py/mpstate.h"

mp_state_ctx_t mp_state_ctx;
Loading

0 comments on commit b4b10fd

Please sign in to comment.