1 /* 2 * This file is part of the MicroPython project, http://micropython.org/ 3 * 4 * The MIT License (MIT) 5 * 6 * Copyright (c) 2014 Damien P. George 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this software and associated documentation files (the "Software"), to deal 10 * in the Software without restriction, including without limitation the rights 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * copies of the Software, and to permit persons to whom the Software is 13 * furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 * THE SOFTWARE. 25 */ 26 #ifndef MICROPY_INCLUDED_PY_MPSTATE_H 27 #define MICROPY_INCLUDED_PY_MPSTATE_H 28 29 #include <stdint.h> 30 31 #include "py/mpconfig.h" 32 #include "py/mpthread.h" 33 #include "py/misc.h" 34 #include "py/nlr.h" 35 #include "py/obj.h" 36 #include "py/objlist.h" 37 #include "py/objexcept.h" 38 39 // This file contains structures defining the state of the MicroPython 40 // memory system, runtime and virtual machine. The state is a global 41 // variable, but in the future it is hoped that the state can become local. 42 43 // This structure contains dynamic configuration for the compiler. 44 #if MICROPY_DYNAMIC_COMPILER 45 typedef struct mp_dynamic_compiler_t { 46 uint8_t small_int_bits; // must be <= host small_int_bits 47 bool opt_cache_map_lookup_in_bytecode; 48 bool py_builtins_str_unicode; 49 uint8_t native_arch; 50 uint8_t nlr_buf_num_regs; 51 } mp_dynamic_compiler_t; 52 extern mp_dynamic_compiler_t mp_dynamic_compiler; 53 #endif 54 55 // These are the values for sched_state 56 #define MP_SCHED_IDLE (1) 57 #define MP_SCHED_LOCKED (-1) 58 #define MP_SCHED_PENDING (0) // 0 so it's a quick check in the VM 59 60 typedef struct _mp_sched_item_t { 61 mp_obj_t func; 62 mp_obj_t arg; 63 } mp_sched_item_t; 64 65 // This structure hold information about the memory allocation system. 66 typedef struct _mp_state_mem_t { 67 #if MICROPY_MEM_STATS 68 size_t total_bytes_allocated; 69 size_t current_bytes_allocated; 70 size_t peak_bytes_allocated; 71 #endif 72 73 byte *gc_alloc_table_start; 74 size_t gc_alloc_table_byte_len; 75 #if MICROPY_ENABLE_FINALISER 76 byte *gc_finaliser_table_start; 77 #endif 78 byte *gc_pool_start; 79 byte *gc_pool_end; 80 81 int gc_stack_overflow; 82 MICROPY_GC_STACK_ENTRY_TYPE gc_stack[MICROPY_ALLOC_GC_STACK_SIZE]; 83 84 // This variable controls auto garbage collection. If set to 0 then the 85 // GC won't automatically run when gc_alloc can't find enough blocks. But 86 // you can still allocate/free memory and also explicitly call gc_collect. 87 uint16_t gc_auto_collect_enabled; 88 89 #if MICROPY_GC_ALLOC_THRESHOLD 90 size_t gc_alloc_amount; 91 size_t gc_alloc_threshold; 92 #endif 93 94 size_t gc_last_free_atb_index; 95 96 #if MICROPY_PY_GC_COLLECT_RETVAL 97 size_t gc_collected; 98 #endif 99 100 #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL 101 // This is a global mutex used to make the GC thread-safe. 102 mp_thread_mutex_t gc_mutex; 103 #endif 104 } mp_state_mem_t; 105 106 // This structure hold runtime and VM information. It includes a section 107 // which contains root pointers that must be scanned by the GC. 108 typedef struct _mp_state_vm_t { 109 // 110 // CONTINUE ROOT POINTER SECTION 111 // This must start at the start of this structure and follows 112 // the state in the mp_state_thread_t structure, continuing 113 // the root pointer section from there. 114 // 115 116 qstr_pool_t *last_pool; 117 118 // non-heap memory for creating an exception if we can't allocate RAM 119 mp_obj_exception_t mp_emergency_exception_obj; 120 121 // memory for exception arguments if we can't allocate RAM 122 #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF 123 #if MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE > 0 124 // statically allocated buf (needs to be aligned to mp_obj_t) 125 mp_obj_t mp_emergency_exception_buf[MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE / sizeof(mp_obj_t)]; 126 #else 127 // dynamically allocated buf 128 byte *mp_emergency_exception_buf; 129 #endif 130 #endif 131 132 #if MICROPY_KBD_EXCEPTION 133 // exception object of type KeyboardInterrupt 134 mp_obj_exception_t mp_kbd_exception; 135 #endif 136 137 // dictionary with loaded modules (may be exposed as sys.modules) 138 mp_obj_dict_t mp_loaded_modules_dict; 139 140 #if MICROPY_ENABLE_SCHEDULER 141 mp_sched_item_t sched_queue[MICROPY_SCHEDULER_DEPTH]; 142 #endif 143 144 // current exception being handled, for sys.exc_info() 145 #if MICROPY_PY_SYS_EXC_INFO 146 mp_obj_base_t *cur_exception; 147 #endif 148 149 #if MICROPY_PY_SYS_ATEXIT 150 // exposed through sys.atexit function 151 mp_obj_t sys_exitfunc; 152 #endif 153 154 // dictionary for the __main__ module 155 mp_obj_dict_t dict_main; 156 157 // these two lists must be initialised per port, after the call to mp_init 158 mp_obj_list_t mp_sys_path_obj; 159 mp_obj_list_t mp_sys_argv_obj; 160 161 // dictionary for overridden builtins 162 #if MICROPY_CAN_OVERRIDE_BUILTINS 163 mp_obj_dict_t *mp_module_builtins_override_dict; 164 #endif 165 166 #if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE 167 // An mp_obj_list_t that tracks relocated native code to prevent the GC from reclaiming them. 168 mp_obj_t track_reloc_code_list; 169 #endif 170 171 // include any root pointers defined by a port 172 MICROPY_PORT_ROOT_POINTERS 173 174 // root pointers for extmod 175 176 #if MICROPY_REPL_EVENT_DRIVEN 177 vstr_t *repl_line; 178 #endif 179 180 #if MICROPY_PY_OS_DUPTERM 181 mp_obj_t dupterm_objs[MICROPY_PY_OS_DUPTERM]; 182 #endif 183 184 #if MICROPY_PY_LWIP_SLIP 185 mp_obj_t lwip_slip_stream; 186 #endif 187 188 #if MICROPY_VFS 189 struct _mp_vfs_mount_t *vfs_cur; 190 struct _mp_vfs_mount_t *vfs_mount_table; 191 #endif 192 193 #if MICROPY_PY_BLUETOOTH 194 mp_obj_t bluetooth; 195 #endif 196 197 // 198 // END ROOT POINTER SECTION 199 //////////////////////////////////////////////////////////// 200 201 // pointer and sizes to store interned string data 202 // (qstr_last_chunk can be root pointer but is also stored in qstr pool) 203 byte *qstr_last_chunk; 204 size_t qstr_last_alloc; 205 size_t qstr_last_used; 206 207 #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL 208 // This is a global mutex used to make qstr interning thread-safe. 209 mp_thread_mutex_t qstr_mutex; 210 #endif 211 212 #if MICROPY_ENABLE_COMPILER 213 mp_uint_t mp_optimise_value; 214 #if MICROPY_EMIT_NATIVE 215 uint8_t default_emit_opt; // one of MP_EMIT_OPT_xxx 216 #endif 217 #endif 218 219 // size of the emergency exception buf, if it's dynamically allocated 220 #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF && MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE == 0 221 mp_int_t mp_emergency_exception_buf_size; 222 #endif 223 224 #if MICROPY_ENABLE_SCHEDULER 225 volatile int16_t sched_state; 226 uint8_t sched_len; 227 uint8_t sched_idx; 228 #endif 229 230 #if MICROPY_PY_THREAD_GIL 231 // This is a global mutex used to make the VM/runtime thread-safe. 232 mp_thread_mutex_t gil_mutex; 233 #endif 234 } mp_state_vm_t; 235 236 // This structure holds state that is specific to a given thread. 237 // Everything in this structure is scanned for root pointers. 238 typedef struct _mp_state_thread_t { 239 // Stack top at the start of program 240 char *stack_top; 241 242 #if MICROPY_STACK_CHECK 243 size_t stack_limit; 244 #endif 245 246 #if MICROPY_ENABLE_PYSTACK 247 uint8_t *pystack_start; 248 uint8_t *pystack_end; 249 uint8_t *pystack_cur; 250 #endif 251 252 // Locking of the GC is done per thread. 253 uint16_t gc_lock_depth; 254 255 //////////////////////////////////////////////////////////// 256 // START ROOT POINTER SECTION 257 // Everything that needs GC scanning must start here, and 258 // is followed by state in the mp_state_vm_t structure. 259 // 260 261 mp_obj_dict_t *dict_locals; 262 mp_obj_dict_t *dict_globals; 263 264 nlr_buf_t *nlr_top; 265 266 // pending exception object (MP_OBJ_NULL if not pending) 267 volatile mp_obj_t mp_pending_exception; 268 269 // If MP_OBJ_STOP_ITERATION is propagated then this holds its argument. 270 mp_obj_t stop_iteration_arg; 271 272 #if MICROPY_PY_SYS_SETTRACE 273 mp_obj_t prof_trace_callback; 274 bool prof_callback_is_executing; 275 struct _mp_code_state_t *current_code_state; 276 #endif 277 } mp_state_thread_t; 278 279 // This structure combines the above 3 structures. 280 // The order of the entries are important for root pointer scanning in the GC to work. 281 typedef struct _mp_state_ctx_t { 282 mp_state_thread_t thread; 283 mp_state_vm_t vm; 284 mp_state_mem_t mem; 285 } mp_state_ctx_t; 286 287 extern mp_state_ctx_t mp_state_ctx; 288 289 #define MP_STATE_VM(x) (mp_state_ctx.vm.x) 290 #define MP_STATE_MEM(x) (mp_state_ctx.mem.x) 291 #define MP_STATE_MAIN_THREAD(x) (mp_state_ctx.thread.x) 292 293 #if MICROPY_PY_THREAD 294 extern mp_state_thread_t *mp_thread_get_state(void); 295 #define MP_STATE_THREAD(x) (mp_thread_get_state()->x) 296 #else 297 #define MP_STATE_THREAD(x) MP_STATE_MAIN_THREAD(x) 298 #endif 299 300 #endif // MICROPY_INCLUDED_PY_MPSTATE_H 301