blob: 7f86399f572a73db76de53e30df41a8b2c8209bb [file] [log] [blame]
Damien Georgeb4b10fd2015-01-01 23:30:53 +00001/*
Alexander Steffen55f33242017-06-30 09:22:17 +02002 * This file is part of the MicroPython project, http://micropython.org/
Damien Georgeb4b10fd2015-01-01 23:30:53 +00003 *
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 */
Alexander Steffen299bc622017-06-29 23:14:58 +020026#ifndef MICROPY_INCLUDED_PY_MPSTATE_H
27#define MICROPY_INCLUDED_PY_MPSTATE_H
Damien Georgeb4b10fd2015-01-01 23:30:53 +000028
29#include <stdint.h>
30
31#include "py/mpconfig.h"
Damien Georgec93d9ca2016-04-25 15:28:57 +000032#include "py/mpthread.h"
Damien Georgeb4b10fd2015-01-01 23:30:53 +000033#include "py/misc.h"
34#include "py/nlr.h"
35#include "py/obj.h"
Damien Georgee1e359f2015-02-07 17:24:10 +000036#include "py/objlist.h"
Damien Georgeb4b10fd2015-01-01 23:30:53 +000037#include "py/objexcept.h"
38
Alexander Steffen55f33242017-06-30 09:22:17 +020039// This file contains structures defining the state of the MicroPython
Damien Georgeb4b10fd2015-01-01 23:30:53 +000040// 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
Damien Georgeea235202016-02-11 22:30:53 +000043// This structure contains dynamic configuration for the compiler.
44#if MICROPY_DYNAMIC_COMPILER
45typedef struct mp_dynamic_compiler_t {
46 uint8_t small_int_bits; // must be <= host small_int_bits
Damien Georgeea235202016-02-11 22:30:53 +000047 bool py_builtins_str_unicode;
Damien Georged9d92f22019-03-09 10:59:25 +110048 uint8_t native_arch;
Damien Georgeb5966382019-09-18 13:45:20 +100049 uint8_t nlr_buf_num_regs;
Damien Georgeea235202016-02-11 22:30:53 +000050} mp_dynamic_compiler_t;
51extern mp_dynamic_compiler_t mp_dynamic_compiler;
52#endif
53
Damien George6e74d242017-02-16 18:05:06 +110054// These are the values for sched_state
55#define MP_SCHED_IDLE (1)
56#define MP_SCHED_LOCKED (-1)
57#define MP_SCHED_PENDING (0) // 0 so it's a quick check in the VM
58
59typedef struct _mp_sched_item_t {
60 mp_obj_t func;
61 mp_obj_t arg;
62} mp_sched_item_t;
63
Damien Georgeb4b10fd2015-01-01 23:30:53 +000064// This structure hold information about the memory allocation system.
65typedef struct _mp_state_mem_t {
66 #if MICROPY_MEM_STATS
67 size_t total_bytes_allocated;
68 size_t current_bytes_allocated;
69 size_t peak_bytes_allocated;
70 #endif
71
72 byte *gc_alloc_table_start;
Damien Georged977d262015-12-16 20:09:11 -050073 size_t gc_alloc_table_byte_len;
Damien Georgeb4b10fd2015-01-01 23:30:53 +000074 #if MICROPY_ENABLE_FINALISER
75 byte *gc_finaliser_table_start;
76 #endif
Damien George94fe6e52015-11-27 13:07:48 +000077 byte *gc_pool_start;
78 byte *gc_pool_end;
Damien Georgeb4b10fd2015-01-01 23:30:53 +000079
80 int gc_stack_overflow;
Ayke van Laethem31cf5282018-02-23 18:59:31 +010081 MICROPY_GC_STACK_ENTRY_TYPE gc_stack[MICROPY_ALLOC_GC_STACK_SIZE];
Damien Georgeb4b10fd2015-01-01 23:30:53 +000082
83 // This variable controls auto garbage collection. If set to 0 then the
84 // GC won't automatically run when gc_alloc can't find enough blocks. But
85 // you can still allocate/free memory and also explicitly call gc_collect.
86 uint16_t gc_auto_collect_enabled;
87
Paul Sokolovsky93e353e2016-07-21 00:37:30 +030088 #if MICROPY_GC_ALLOC_THRESHOLD
89 size_t gc_alloc_amount;
90 size_t gc_alloc_threshold;
91 #endif
92
Damien Georged977d262015-12-16 20:09:11 -050093 size_t gc_last_free_atb_index;
Damien Georgee1e359f2015-02-07 17:24:10 +000094
95 #if MICROPY_PY_GC_COLLECT_RETVAL
Damien Georged977d262015-12-16 20:09:11 -050096 size_t gc_collected;
Damien Georgee1e359f2015-02-07 17:24:10 +000097 #endif
Damien Georgec93d9ca2016-04-25 15:28:57 +000098
David Lechnerccc18f02020-01-22 11:19:37 -060099 #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
Damien Georgec93d9ca2016-04-25 15:28:57 +0000100 // This is a global mutex used to make the GC thread-safe.
101 mp_thread_mutex_t gc_mutex;
102 #endif
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000103} mp_state_mem_t;
104
105// This structure hold runtime and VM information. It includes a section
106// which contains root pointers that must be scanned by the GC.
107typedef struct _mp_state_vm_t {
Damien George749b1612018-05-12 22:09:34 +1000108 //
109 // CONTINUE ROOT POINTER SECTION
110 // This must start at the start of this structure and follows
111 // the state in the mp_state_thread_t structure, continuing
112 // the root pointer section from there.
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000113 //
114
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000115 qstr_pool_t *last_pool;
116
117 // non-heap memory for creating an exception if we can't allocate RAM
118 mp_obj_exception_t mp_emergency_exception_obj;
119
120 // memory for exception arguments if we can't allocate RAM
121 #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
122 #if MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE > 0
Damien Georgeee86de12017-04-10 16:02:56 +1000123 // statically allocated buf (needs to be aligned to mp_obj_t)
124 mp_obj_t mp_emergency_exception_buf[MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE / sizeof(mp_obj_t)];
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000125 #else
126 // dynamically allocated buf
127 byte *mp_emergency_exception_buf;
128 #endif
129 #endif
130
Damien George7f1da0a2016-12-15 13:00:19 +1100131 #if MICROPY_KBD_EXCEPTION
132 // exception object of type KeyboardInterrupt
133 mp_obj_exception_t mp_kbd_exception;
134 #endif
135
Paul Sokolovsky1a1d11f2015-12-05 00:09:10 +0200136 // dictionary with loaded modules (may be exposed as sys.modules)
137 mp_obj_dict_t mp_loaded_modules_dict;
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000138
Damien George6e74d242017-02-16 18:05:06 +1100139 #if MICROPY_ENABLE_SCHEDULER
Jim Mussaredbc66fe92019-07-11 11:55:31 +1000140 mp_sched_item_t sched_queue[MICROPY_SCHEDULER_DEPTH];
Damien George6e74d242017-02-16 18:05:06 +1100141 #endif
142
Paul Sokolovsky8b85d142015-04-25 03:17:41 +0300143 // current exception being handled, for sys.exc_info()
144 #if MICROPY_PY_SYS_EXC_INFO
Damien George999cedb2015-11-27 17:01:44 +0000145 mp_obj_base_t *cur_exception;
Paul Sokolovsky8b85d142015-04-25 03:17:41 +0300146 #endif
147
Milan Rossacb364702019-08-05 15:06:41 +0200148 #if MICROPY_PY_SYS_ATEXIT
149 // exposed through sys.atexit function
150 mp_obj_t sys_exitfunc;
151 #endif
152
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000153 // dictionary for the __main__ module
154 mp_obj_dict_t dict_main;
155
Damien Georgefe9ffff2021-12-19 08:55:40 +1100156 #if MICROPY_PY_SYS
Damien Georgede43b502021-12-17 23:35:32 +1100157 // If MICROPY_PY_SYS_PATH_ARGV_DEFAULTS is not enabled then these two lists
158 // must be initialised after the call to mp_init.
Damien Georgee1e359f2015-02-07 17:24:10 +0000159 mp_obj_list_t mp_sys_path_obj;
160 mp_obj_list_t mp_sys_argv_obj;
Damien Georgefe9ffff2021-12-19 08:55:40 +1100161 #endif
Damien Georgee1e359f2015-02-07 17:24:10 +0000162
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000163 // dictionary for overridden builtins
164 #if MICROPY_CAN_OVERRIDE_BUILTINS
165 mp_obj_dict_t *mp_module_builtins_override_dict;
166 #endif
167
Damien George9883d8e2020-07-27 23:52:38 +1000168 #if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE
169 // An mp_obj_list_t that tracks relocated native code to prevent the GC from reclaiming them.
170 mp_obj_t track_reloc_code_list;
171 #endif
172
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000173 // include any root pointers defined by a port
174 MICROPY_PORT_ROOT_POINTERS
175
Paul Sokolovskye0d77402015-10-27 00:04:33 +0300176 // root pointers for extmod
Paul Sokolovsky00ee84e2016-01-01 14:19:26 +0200177
Damien George9d8347a2018-02-26 16:08:58 +1100178 #if MICROPY_REPL_EVENT_DRIVEN
179 vstr_t *repl_line;
180 #endif
181
Paul Sokolovsky00ee84e2016-01-01 14:19:26 +0200182 #if MICROPY_PY_OS_DUPTERM
Damien George37282f82017-10-13 20:01:57 +1100183 mp_obj_t dupterm_objs[MICROPY_PY_OS_DUPTERM];
Paul Sokolovsky00ee84e2016-01-01 14:19:26 +0200184 #endif
185
Paul Sokolovskye0d77402015-10-27 00:04:33 +0300186 #if MICROPY_PY_LWIP_SLIP
187 mp_obj_t lwip_slip_stream;
188 #endif
189
Damien Georgedcb9ea72017-01-27 15:10:09 +1100190 #if MICROPY_VFS
Damien George3f6b4e02017-01-27 22:40:15 +1100191 struct _mp_vfs_mount_t *vfs_cur;
192 struct _mp_vfs_mount_t *vfs_mount_table;
Damien Georgedcb9ea72017-01-27 15:10:09 +1100193 #endif
194
Jim Mussared16f8cee2019-07-24 00:49:06 +1000195 #if MICROPY_PY_BLUETOOTH
196 mp_obj_t bluetooth;
197 #endif
198
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000199 //
200 // END ROOT POINTER SECTION
201 ////////////////////////////////////////////////////////////
202
Damien Georgeade9a052015-06-13 21:53:22 +0100203 // pointer and sizes to store interned string data
204 // (qstr_last_chunk can be root pointer but is also stored in qstr pool)
Artyom Skrobov18b1ba02021-05-03 14:17:36 -0400205 char *qstr_last_chunk;
Damien George25784852015-12-17 12:41:40 +0000206 size_t qstr_last_alloc;
207 size_t qstr_last_used;
Damien Georgeade9a052015-06-13 21:53:22 +0100208
David Lechneredbb73a2020-01-22 11:19:37 -0600209 #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
Damien George1f54ad22016-05-26 09:06:46 +0000210 // This is a global mutex used to make qstr interning thread-safe.
211 mp_thread_mutex_t qstr_mutex;
212 #endif
213
Damien George3f420c02018-04-04 14:24:03 +1000214 #if MICROPY_ENABLE_COMPILER
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000215 mp_uint_t mp_optimise_value;
Damien Georgeaf20c2e2019-08-23 11:20:50 +1000216 #if MICROPY_EMIT_NATIVE
217 uint8_t default_emit_opt; // one of MP_EMIT_OPT_xxx
218 #endif
Damien George3f420c02018-04-04 14:24:03 +1000219 #endif
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000220
221 // size of the emergency exception buf, if it's dynamically allocated
222 #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF && MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE == 0
223 mp_int_t mp_emergency_exception_buf_size;
224 #endif
Damien George4cec63a2016-05-26 10:42:53 +0000225
Damien George749b1612018-05-12 22:09:34 +1000226 #if MICROPY_ENABLE_SCHEDULER
227 volatile int16_t sched_state;
Andrew Leech8977c7e2019-03-21 11:52:10 +1100228 uint8_t sched_len;
229 uint8_t sched_idx;
Damien George749b1612018-05-12 22:09:34 +1000230 #endif
231
Damien George4cec63a2016-05-26 10:42:53 +0000232 #if MICROPY_PY_THREAD_GIL
233 // This is a global mutex used to make the VM/runtime thread-safe.
234 mp_thread_mutex_t gil_mutex;
235 #endif
Jim Mussared11ef8f22021-08-18 14:52:48 +1000236
237 #if MICROPY_OPT_MAP_LOOKUP_CACHE
238 // See mp_map_lookup.
239 uint8_t map_lookup_cache[MICROPY_OPT_MAP_LOOKUP_CACHE_SIZE];
240 #endif
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000241} mp_state_vm_t;
242
Damien George330165a2016-04-22 22:44:56 +0000243// This structure holds state that is specific to a given thread.
244// Everything in this structure is scanned for root pointers.
245typedef struct _mp_state_thread_t {
Damien George330165a2016-04-22 22:44:56 +0000246 // Stack top at the start of program
Damien George330165a2016-04-22 22:44:56 +0000247 char *stack_top;
248
249 #if MICROPY_STACK_CHECK
250 size_t stack_limit;
251 #endif
Damien George02d830c2017-11-26 23:28:40 +1100252
253 #if MICROPY_ENABLE_PYSTACK
254 uint8_t *pystack_start;
255 uint8_t *pystack_end;
256 uint8_t *pystack_cur;
257 #endif
Damien George749b1612018-05-12 22:09:34 +1000258
Damien Georgeb6b39bf2021-05-04 23:56:43 +1000259 // Locking of the GC is done per thread.
260 uint16_t gc_lock_depth;
261
Damien George749b1612018-05-12 22:09:34 +1000262 ////////////////////////////////////////////////////////////
263 // START ROOT POINTER SECTION
264 // Everything that needs GC scanning must start here, and
265 // is followed by state in the mp_state_vm_t structure.
266 //
267
268 mp_obj_dict_t *dict_locals;
269 mp_obj_dict_t *dict_globals;
270
271 nlr_buf_t *nlr_top;
Milan Rossa310b3d12019-08-14 16:09:36 +0200272
David Lechnerca920f72021-05-10 21:53:22 -0500273 // pending exception object (MP_OBJ_NULL if not pending)
274 volatile mp_obj_t mp_pending_exception;
275
Damien Georgebb001252021-06-29 17:34:34 +1000276 // If MP_OBJ_STOP_ITERATION is propagated then this holds its argument.
277 mp_obj_t stop_iteration_arg;
278
Milan Rossa310b3d12019-08-14 16:09:36 +0200279 #if MICROPY_PY_SYS_SETTRACE
280 mp_obj_t prof_trace_callback;
281 bool prof_callback_is_executing;
282 struct _mp_code_state_t *current_code_state;
283 #endif
Damien George330165a2016-04-22 22:44:56 +0000284} mp_state_thread_t;
285
Damien George05fe66f2017-02-27 23:56:46 +1100286// This structure combines the above 3 structures.
287// The order of the entries are important for root pointer scanning in the GC to work.
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000288typedef struct _mp_state_ctx_t {
Damien George330165a2016-04-22 22:44:56 +0000289 mp_state_thread_t thread;
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000290 mp_state_vm_t vm;
291 mp_state_mem_t mem;
292} mp_state_ctx_t;
293
294extern mp_state_ctx_t mp_state_ctx;
295
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000296#define MP_STATE_VM(x) (mp_state_ctx.vm.x)
297#define MP_STATE_MEM(x) (mp_state_ctx.mem.x)
David Lechner259d9b62021-05-10 22:18:17 -0500298#define MP_STATE_MAIN_THREAD(x) (mp_state_ctx.thread.x)
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000299
Damien George27cc0772016-04-22 22:52:33 +0000300#if MICROPY_PY_THREAD
301extern mp_state_thread_t *mp_thread_get_state(void);
302#define MP_STATE_THREAD(x) (mp_thread_get_state()->x)
303#else
David Lechner259d9b62021-05-10 22:18:17 -0500304#define MP_STATE_THREAD(x) MP_STATE_MAIN_THREAD(x)
Damien George27cc0772016-04-22 22:52:33 +0000305#endif
Damien George330165a2016-04-22 22:44:56 +0000306
Alexander Steffen299bc622017-06-29 23:14:58 +0200307#endif // MICROPY_INCLUDED_PY_MPSTATE_H