mpstate.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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. #include <stdint.h>
  29. #include "py/mpconfig.h"
  30. #include "py/mpthread.h"
  31. #include "py/misc.h"
  32. #include "py/nlr.h"
  33. #include "py/obj.h"
  34. #include "py/objlist.h"
  35. #include "py/objexcept.h"
  36. // This file contains structures defining the state of the MicroPython
  37. // memory system, runtime and virtual machine. The state is a global
  38. // variable, but in the future it is hoped that the state can become local.
  39. #if MICROPY_PY_SYS_ATTR_DELEGATION
  40. // Must be kept in sync with sys_mutable_keys in modsys.c.
  41. enum {
  42. #if MICROPY_PY_SYS_PATH
  43. MP_SYS_MUTABLE_PATH,
  44. #endif
  45. #if MICROPY_PY_SYS_PS1_PS2
  46. MP_SYS_MUTABLE_PS1,
  47. MP_SYS_MUTABLE_PS2,
  48. #endif
  49. #if MICROPY_PY_SYS_TRACEBACKLIMIT
  50. MP_SYS_MUTABLE_TRACEBACKLIMIT,
  51. #endif
  52. MP_SYS_MUTABLE_NUM,
  53. };
  54. #endif // MICROPY_PY_SYS_ATTR_DELEGATION
  55. // This structure contains dynamic configuration for the compiler.
  56. #if MICROPY_DYNAMIC_COMPILER
  57. typedef struct mp_dynamic_compiler_t {
  58. uint8_t small_int_bits; // must be <= host small_int_bits
  59. uint8_t native_arch;
  60. uint8_t nlr_buf_num_regs;
  61. } mp_dynamic_compiler_t;
  62. extern mp_dynamic_compiler_t mp_dynamic_compiler;
  63. #endif
  64. // These are the values for sched_state
  65. #define MP_SCHED_IDLE (1)
  66. #define MP_SCHED_LOCKED (-1)
  67. #define MP_SCHED_PENDING (0) // 0 so it's a quick check in the VM
  68. typedef struct _mp_sched_item_t {
  69. mp_obj_t func;
  70. mp_obj_t arg;
  71. } mp_sched_item_t;
  72. // This structure holds information about a single contiguous area of
  73. // memory reserved for the memory manager.
  74. typedef struct _mp_state_mem_area_t {
  75. #if MICROPY_GC_SPLIT_HEAP
  76. struct _mp_state_mem_area_t *next;
  77. #endif
  78. byte *gc_alloc_table_start;
  79. size_t gc_alloc_table_byte_len;
  80. #if MICROPY_ENABLE_FINALISER
  81. byte *gc_finaliser_table_start;
  82. #endif
  83. byte *gc_pool_start;
  84. byte *gc_pool_end;
  85. size_t gc_last_free_atb_index;
  86. size_t gc_last_used_block; // The block ID of the highest block allocated in the area
  87. } mp_state_mem_area_t;
  88. // This structure hold information about the memory allocation system.
  89. typedef struct _mp_state_mem_t {
  90. #if MICROPY_MEM_STATS
  91. size_t total_bytes_allocated;
  92. size_t current_bytes_allocated;
  93. size_t peak_bytes_allocated;
  94. #endif
  95. mp_state_mem_area_t area;
  96. int gc_stack_overflow;
  97. MICROPY_GC_STACK_ENTRY_TYPE gc_block_stack[MICROPY_ALLOC_GC_STACK_SIZE];
  98. #if MICROPY_GC_SPLIT_HEAP
  99. // Array that tracks the area for each block on gc_block_stack.
  100. mp_state_mem_area_t *gc_area_stack[MICROPY_ALLOC_GC_STACK_SIZE];
  101. #endif
  102. // This variable controls auto garbage collection. If set to 0 then the
  103. // GC won't automatically run when gc_alloc can't find enough blocks. But
  104. // you can still allocate/free memory and also explicitly call gc_collect.
  105. uint16_t gc_auto_collect_enabled;
  106. #if MICROPY_GC_ALLOC_THRESHOLD
  107. size_t gc_alloc_amount;
  108. size_t gc_alloc_threshold;
  109. #endif
  110. #if MICROPY_GC_SPLIT_HEAP
  111. mp_state_mem_area_t *gc_last_free_area;
  112. #endif
  113. #if MICROPY_PY_GC_COLLECT_RETVAL
  114. size_t gc_collected;
  115. #endif
  116. #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
  117. // This is a global mutex used to make the GC thread-safe.
  118. mp_thread_mutex_t gc_mutex;
  119. #endif
  120. } mp_state_mem_t;
  121. // This structure hold runtime and VM information. It includes a section
  122. // which contains root pointers that must be scanned by the GC.
  123. typedef struct _mp_state_vm_t {
  124. //
  125. // CONTINUE ROOT POINTER SECTION
  126. // This must start at the start of this structure and follows
  127. // the state in the mp_state_thread_t structure, continuing
  128. // the root pointer section from there.
  129. //
  130. qstr_pool_t *last_pool;
  131. #if MICROPY_TRACKED_ALLOC
  132. struct _m_tracked_node_t *m_tracked_head;
  133. #endif
  134. // non-heap memory for creating an exception if we can't allocate RAM
  135. mp_obj_exception_t mp_emergency_exception_obj;
  136. // memory for exception arguments if we can't allocate RAM
  137. #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
  138. #if MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE > 0
  139. // statically allocated buf (needs to be aligned to mp_obj_t)
  140. mp_obj_t mp_emergency_exception_buf[MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE / sizeof(mp_obj_t)];
  141. #else
  142. // dynamically allocated buf
  143. byte *mp_emergency_exception_buf;
  144. #endif
  145. #endif
  146. #if MICROPY_KBD_EXCEPTION
  147. // exception object of type KeyboardInterrupt
  148. mp_obj_exception_t mp_kbd_exception;
  149. #endif
  150. // dictionary with loaded modules (may be exposed as sys.modules)
  151. mp_obj_dict_t mp_loaded_modules_dict;
  152. // dictionary for the __main__ module
  153. mp_obj_dict_t dict_main;
  154. // dictionary for overridden builtins
  155. #if MICROPY_CAN_OVERRIDE_BUILTINS
  156. mp_obj_dict_t *mp_module_builtins_override_dict;
  157. #endif
  158. // Include any root pointers registered with MP_REGISTER_ROOT_POINTER().
  159. #ifndef NO_QSTR
  160. // Only include root pointer definitions when not doing qstr extraction, because
  161. // the qstr extraction stage also generates the root pointers header file.
  162. #include "genhdr/root_pointers.h"
  163. #endif
  164. //
  165. // END ROOT POINTER SECTION
  166. ////////////////////////////////////////////////////////////
  167. // pointer and sizes to store interned string data
  168. // (qstr_last_chunk can be root pointer but is also stored in qstr pool)
  169. char *qstr_last_chunk;
  170. size_t qstr_last_alloc;
  171. size_t qstr_last_used;
  172. #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
  173. // This is a global mutex used to make qstr interning thread-safe.
  174. mp_thread_mutex_t qstr_mutex;
  175. #endif
  176. #if MICROPY_ENABLE_COMPILER
  177. mp_uint_t mp_optimise_value;
  178. #if MICROPY_EMIT_NATIVE
  179. uint8_t default_emit_opt; // one of MP_EMIT_OPT_xxx
  180. #endif
  181. #endif
  182. // size of the emergency exception buf, if it's dynamically allocated
  183. #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF && MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE == 0
  184. mp_int_t mp_emergency_exception_buf_size;
  185. #endif
  186. #if MICROPY_ENABLE_SCHEDULER
  187. volatile int16_t sched_state;
  188. #if MICROPY_SCHEDULER_STATIC_NODES
  189. // These will usually point to statically allocated memory. They are not
  190. // traced by the GC. They are assumed to be zero'd out before mp_init() is
  191. // called (usually because this struct lives in the BSS).
  192. struct _mp_sched_node_t *sched_head;
  193. struct _mp_sched_node_t *sched_tail;
  194. #endif
  195. // These index sched_queue.
  196. uint8_t sched_len;
  197. uint8_t sched_idx;
  198. #endif
  199. #if MICROPY_ENABLE_VM_ABORT
  200. bool vm_abort;
  201. nlr_buf_t *nlr_abort;
  202. #endif
  203. #if MICROPY_PY_THREAD_GIL
  204. // This is a global mutex used to make the VM/runtime thread-safe.
  205. mp_thread_mutex_t gil_mutex;
  206. #endif
  207. #if MICROPY_OPT_MAP_LOOKUP_CACHE
  208. // See mp_map_lookup.
  209. uint8_t map_lookup_cache[MICROPY_OPT_MAP_LOOKUP_CACHE_SIZE];
  210. #endif
  211. } mp_state_vm_t;
  212. // This structure holds state that is specific to a given thread. Everything
  213. // in this structure is scanned for root pointers. Anything added to this
  214. // structure must have corresponding initialisation added to thread_entry (in
  215. // py/modthread.c).
  216. typedef struct _mp_state_thread_t {
  217. // Stack top at the start of program
  218. char *stack_top;
  219. #if MICROPY_STACK_CHECK
  220. size_t stack_limit;
  221. #endif
  222. #if MICROPY_ENABLE_PYSTACK
  223. uint8_t *pystack_start;
  224. uint8_t *pystack_end;
  225. uint8_t *pystack_cur;
  226. #endif
  227. // Locking of the GC is done per thread.
  228. uint16_t gc_lock_depth;
  229. ////////////////////////////////////////////////////////////
  230. // START ROOT POINTER SECTION
  231. // Everything that needs GC scanning must start here, and
  232. // is followed by state in the mp_state_vm_t structure.
  233. //
  234. mp_obj_dict_t *dict_locals;
  235. mp_obj_dict_t *dict_globals;
  236. nlr_buf_t *nlr_top;
  237. nlr_jump_callback_node_t *nlr_jump_callback_top;
  238. // pending exception object (MP_OBJ_NULL if not pending)
  239. volatile mp_obj_t mp_pending_exception;
  240. // If MP_OBJ_STOP_ITERATION is propagated then this holds its argument.
  241. mp_obj_t stop_iteration_arg;
  242. #if MICROPY_PY_SYS_SETTRACE
  243. mp_obj_t prof_trace_callback;
  244. bool prof_callback_is_executing;
  245. struct _mp_code_state_t *current_code_state;
  246. #endif
  247. } mp_state_thread_t;
  248. // This structure combines the above 3 structures.
  249. // The order of the entries are important for root pointer scanning in the GC to work.
  250. typedef struct _mp_state_ctx_t {
  251. mp_state_thread_t thread;
  252. mp_state_vm_t vm;
  253. mp_state_mem_t mem;
  254. } mp_state_ctx_t;
  255. extern mp_state_ctx_t mp_state_ctx;
  256. #define MP_STATE_VM(x) (mp_state_ctx.vm.x)
  257. #define MP_STATE_MEM(x) (mp_state_ctx.mem.x)
  258. #define MP_STATE_MAIN_THREAD(x) (mp_state_ctx.thread.x)
  259. #if MICROPY_PY_THREAD
  260. #define MP_STATE_THREAD(x) (mp_thread_get_state()->x)
  261. #define mp_thread_is_main_thread() (mp_thread_get_state() == &mp_state_ctx.thread)
  262. #else
  263. #define MP_STATE_THREAD(x) MP_STATE_MAIN_THREAD(x)
  264. #define mp_thread_is_main_thread() (true)
  265. #endif
  266. #endif // MICROPY_INCLUDED_PY_MPSTATE_H