mpstate.h 9.7 KB
Newer Older
1
/*
2
 * This file is part of the MicroPython project, http://micropython.org/
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * 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.
 */
26 27
#ifndef MICROPY_INCLUDED_PY_MPSTATE_H
#define MICROPY_INCLUDED_PY_MPSTATE_H
28 29 30 31

#include <stdint.h>

#include "py/mpconfig.h"
32
#include "py/mpthread.h"
33 34 35
#include "py/misc.h"
#include "py/nlr.h"
#include "py/obj.h"
36
#include "py/objlist.h"
37 38
#include "py/objexcept.h"

39
// This file contains structures defining the state of the MicroPython
40 41 42
// memory system, runtime and virtual machine.  The state is a global
// variable, but in the future it is hoped that the state can become local.

43
enum {
44 45 46 47
    #if MICROPY_PY_SYS_PS1_PS2
    MP_SYS_MUTABLE_PS1,
    MP_SYS_MUTABLE_PS2,
    #endif
48 49 50
    #if MICROPY_PY_SYS_TRACEBACKLIMIT
    MP_SYS_MUTABLE_TRACEBACKLIMIT,
    #endif
51 52 53
    MP_SYS_MUTABLE_NUM,
};

54 55 56 57
// This structure contains dynamic configuration for the compiler.
#if MICROPY_DYNAMIC_COMPILER
typedef struct mp_dynamic_compiler_t {
    uint8_t small_int_bits; // must be <= host small_int_bits
58
    uint8_t native_arch;
59
    uint8_t nlr_buf_num_regs;
60 61 62 63
} mp_dynamic_compiler_t;
extern mp_dynamic_compiler_t mp_dynamic_compiler;
#endif

64 65 66 67 68 69 70 71 72 73
// These are the values for sched_state
#define MP_SCHED_IDLE (1)
#define MP_SCHED_LOCKED (-1)
#define MP_SCHED_PENDING (0) // 0 so it's a quick check in the VM

typedef struct _mp_sched_item_t {
    mp_obj_t func;
    mp_obj_t arg;
} mp_sched_item_t;

74 75 76 77 78
// This structure holds information about a single contiguous area of
// memory reserved for the memory manager.
typedef struct _mp_state_mem_area_t {
    #if MICROPY_GC_SPLIT_HEAP
    struct _mp_state_mem_area_t *next;
79 80 81
    #endif

    byte *gc_alloc_table_start;
82
    size_t gc_alloc_table_byte_len;
83 84 85
    #if MICROPY_ENABLE_FINALISER
    byte *gc_finaliser_table_start;
    #endif
86 87
    byte *gc_pool_start;
    byte *gc_pool_end;
88

89 90 91 92 93 94 95 96 97 98 99 100 101
    size_t gc_last_free_atb_index;
} mp_state_mem_area_t;

// This structure hold information about the memory allocation system.
typedef struct _mp_state_mem_t {
    #if MICROPY_MEM_STATS
    size_t total_bytes_allocated;
    size_t current_bytes_allocated;
    size_t peak_bytes_allocated;
    #endif

    mp_state_mem_area_t area;

102
    int gc_stack_overflow;
103 104 105 106 107
    MICROPY_GC_STACK_ENTRY_TYPE gc_block_stack[MICROPY_ALLOC_GC_STACK_SIZE];
    #if MICROPY_GC_SPLIT_HEAP
    // Array that tracks the area for each block on gc_block_stack.
    mp_state_mem_area_t *gc_area_stack[MICROPY_ALLOC_GC_STACK_SIZE];
    #endif
108 109 110 111 112 113

    // 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.
    uint16_t gc_auto_collect_enabled;

114 115 116 117 118
    #if MICROPY_GC_ALLOC_THRESHOLD
    size_t gc_alloc_amount;
    size_t gc_alloc_threshold;
    #endif

119 120 121
    #if MICROPY_GC_SPLIT_HEAP
    mp_state_mem_area_t *gc_last_free_area;
    #endif
122 123

    #if MICROPY_PY_GC_COLLECT_RETVAL
124
    size_t gc_collected;
125
    #endif
126

127
    #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
128 129 130
    // This is a global mutex used to make the GC thread-safe.
    mp_thread_mutex_t gc_mutex;
    #endif
131 132 133 134 135
} mp_state_mem_t;

// This structure hold runtime and VM information.  It includes a section
// which contains root pointers that must be scanned by the GC.
typedef struct _mp_state_vm_t {
136 137 138 139 140
    //
    // CONTINUE ROOT POINTER SECTION
    // This must start at the start of this structure and follows
    // the state in the mp_state_thread_t structure, continuing
    // the root pointer section from there.
141 142 143 144
    //

    qstr_pool_t *last_pool;

145 146 147 148
    #if MICROPY_TRACKED_ALLOC
    struct _m_tracked_node_t *m_tracked_head;
    #endif

149 150 151 152 153 154
    // non-heap memory for creating an exception if we can't allocate RAM
    mp_obj_exception_t mp_emergency_exception_obj;

    // memory for exception arguments if we can't allocate RAM
    #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
    #if MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE > 0
155 156
    // statically allocated buf (needs to be aligned to mp_obj_t)
    mp_obj_t mp_emergency_exception_buf[MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE / sizeof(mp_obj_t)];
157 158 159 160 161 162
    #else
    // dynamically allocated buf
    byte *mp_emergency_exception_buf;
    #endif
    #endif

163 164 165 166 167
    #if MICROPY_KBD_EXCEPTION
    // exception object of type KeyboardInterrupt
    mp_obj_exception_t mp_kbd_exception;
    #endif

168 169
    // dictionary with loaded modules (may be exposed as sys.modules)
    mp_obj_dict_t mp_loaded_modules_dict;
170 171 172 173 174 175 176 177 178

    // dictionary for the __main__ module
    mp_obj_dict_t dict_main;

    // dictionary for overridden builtins
    #if MICROPY_CAN_OVERRIDE_BUILTINS
    mp_obj_dict_t *mp_module_builtins_override_dict;
    #endif

179 180 181 182 183 184 185
    // Include any root pointers registered with MP_REGISTER_ROOT_POINTER().
    #ifndef NO_QSTR
    // Only include root pointer definitions when not doing qstr extraction, because
    // the qstr extraction stage also generates the root pointers header file.
    #include "genhdr/root_pointers.h"
    #endif

186 187 188 189
    //
    // END ROOT POINTER SECTION
    ////////////////////////////////////////////////////////////

190 191
    // pointer and sizes to store interned string data
    // (qstr_last_chunk can be root pointer but is also stored in qstr pool)
192
    char *qstr_last_chunk;
193 194
    size_t qstr_last_alloc;
    size_t qstr_last_used;
195

196
    #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
197 198 199 200
    // This is a global mutex used to make qstr interning thread-safe.
    mp_thread_mutex_t qstr_mutex;
    #endif

201
    #if MICROPY_ENABLE_COMPILER
202
    mp_uint_t mp_optimise_value;
203 204 205
    #if MICROPY_EMIT_NATIVE
    uint8_t default_emit_opt; // one of MP_EMIT_OPT_xxx
    #endif
206
    #endif
207 208 209 210 211

    // size of the emergency exception buf, if it's dynamically allocated
    #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF && MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE == 0
    mp_int_t mp_emergency_exception_buf_size;
    #endif
212

213 214
    #if MICROPY_ENABLE_SCHEDULER
    volatile int16_t sched_state;
215 216 217 218 219 220 221 222 223 224

    #if MICROPY_SCHEDULER_STATIC_NODES
    // These will usually point to statically allocated memory.  They are not
    // traced by the GC.  They are assumed to be zero'd out before mp_init() is
    // called (usually because this struct lives in the BSS).
    struct _mp_sched_node_t *sched_head;
    struct _mp_sched_node_t *sched_tail;
    #endif

    // These index sched_queue.
225 226
    uint8_t sched_len;
    uint8_t sched_idx;
227 228
    #endif

229 230 231 232 233
    #if MICROPY_ENABLE_VM_ABORT
    bool vm_abort;
    nlr_buf_t *nlr_abort;
    #endif

234 235 236 237
    #if MICROPY_PY_THREAD_GIL
    // This is a global mutex used to make the VM/runtime thread-safe.
    mp_thread_mutex_t gil_mutex;
    #endif
238 239 240 241 242

    #if MICROPY_OPT_MAP_LOOKUP_CACHE
    // See mp_map_lookup.
    uint8_t map_lookup_cache[MICROPY_OPT_MAP_LOOKUP_CACHE_SIZE];
    #endif
243 244
} mp_state_vm_t;

245 246 247 248 249 250 251 252 253
// This structure holds state that is specific to a given thread.
// Everything in this structure is scanned for root pointers.
typedef struct _mp_state_thread_t {
    // Stack top at the start of program
    char *stack_top;

    #if MICROPY_STACK_CHECK
    size_t stack_limit;
    #endif
254 255 256 257 258 259

    #if MICROPY_ENABLE_PYSTACK
    uint8_t *pystack_start;
    uint8_t *pystack_end;
    uint8_t *pystack_cur;
    #endif
260

261 262 263
    // Locking of the GC is done per thread.
    uint16_t gc_lock_depth;

264 265 266 267 268 269 270 271 272 273
    ////////////////////////////////////////////////////////////
    // START ROOT POINTER SECTION
    // Everything that needs GC scanning must start here, and
    // is followed by state in the mp_state_vm_t structure.
    //

    mp_obj_dict_t *dict_locals;
    mp_obj_dict_t *dict_globals;

    nlr_buf_t *nlr_top;
274
    nlr_jump_callback_node_t *nlr_jump_callback_top;
275

276 277 278
    // pending exception object (MP_OBJ_NULL if not pending)
    volatile mp_obj_t mp_pending_exception;

279 280 281
    // If MP_OBJ_STOP_ITERATION is propagated then this holds its argument.
    mp_obj_t stop_iteration_arg;

282 283 284 285 286
    #if MICROPY_PY_SYS_SETTRACE
    mp_obj_t prof_trace_callback;
    bool prof_callback_is_executing;
    struct _mp_code_state_t *current_code_state;
    #endif
287 288
} mp_state_thread_t;

289 290
// This structure combines the above 3 structures.
// The order of the entries are important for root pointer scanning in the GC to work.
291
typedef struct _mp_state_ctx_t {
292
    mp_state_thread_t thread;
293 294 295 296 297 298 299 300
    mp_state_vm_t vm;
    mp_state_mem_t mem;
} mp_state_ctx_t;

extern mp_state_ctx_t mp_state_ctx;

#define MP_STATE_VM(x) (mp_state_ctx.vm.x)
#define MP_STATE_MEM(x) (mp_state_ctx.mem.x)
301
#define MP_STATE_MAIN_THREAD(x) (mp_state_ctx.thread.x)
302

303 304 305
#if MICROPY_PY_THREAD
extern mp_state_thread_t *mp_thread_get_state(void);
#define MP_STATE_THREAD(x) (mp_thread_get_state()->x)
306
#define mp_thread_is_main_thread() (mp_thread_get_state() == &mp_state_ctx.thread)
307
#else
308
#define MP_STATE_THREAD(x)  MP_STATE_MAIN_THREAD(x)
309
#define mp_thread_is_main_thread() (true)
310
#endif
311

312
#endif // MICROPY_INCLUDED_PY_MPSTATE_H