blob: af55e764f6cdce6ae5832ff735f1a18c515845f3 [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
Jim Mussared7d2ee8a2023-06-05 22:38:36 +100043#if MICROPY_PY_SYS_ATTR_DELEGATION
44// Must be kept in sync with sys_mutable_keys in modsys.c.
Damien Georgebc181552021-07-27 00:39:04 +100045enum {
Jim Mussared5e509752023-06-05 16:52:29 +100046 #if MICROPY_PY_SYS_PATH
47 MP_SYS_MUTABLE_PATH,
48 #endif
Damien Georgeac229312021-07-27 00:43:35 +100049 #if MICROPY_PY_SYS_PS1_PS2
50 MP_SYS_MUTABLE_PS1,
51 MP_SYS_MUTABLE_PS2,
52 #endif
Damien Georgecac939d2021-07-27 00:41:27 +100053 #if MICROPY_PY_SYS_TRACEBACKLIMIT
54 MP_SYS_MUTABLE_TRACEBACKLIMIT,
55 #endif
Damien Georgebc181552021-07-27 00:39:04 +100056 MP_SYS_MUTABLE_NUM,
57};
Jim Mussared7d2ee8a2023-06-05 22:38:36 +100058#endif // MICROPY_PY_SYS_ATTR_DELEGATION
Damien Georgebc181552021-07-27 00:39:04 +100059
Damien Georgeea235202016-02-11 22:30:53 +000060// This structure contains dynamic configuration for the compiler.
61#if MICROPY_DYNAMIC_COMPILER
62typedef struct mp_dynamic_compiler_t {
63 uint8_t small_int_bits; // must be <= host small_int_bits
Damien Georged9d92f22019-03-09 10:59:25 +110064 uint8_t native_arch;
Damien Georgeb5966382019-09-18 13:45:20 +100065 uint8_t nlr_buf_num_regs;
Damien Georgeea235202016-02-11 22:30:53 +000066} mp_dynamic_compiler_t;
67extern mp_dynamic_compiler_t mp_dynamic_compiler;
68#endif
69
Damien George6e74d242017-02-16 18:05:06 +110070// These are the values for sched_state
71#define MP_SCHED_IDLE (1)
72#define MP_SCHED_LOCKED (-1)
73#define MP_SCHED_PENDING (0) // 0 so it's a quick check in the VM
74
75typedef struct _mp_sched_item_t {
76 mp_obj_t func;
77 mp_obj_t arg;
78} mp_sched_item_t;
79
Ayke van Laethembcc827d2018-01-24 02:09:58 +010080// This structure holds information about a single contiguous area of
81// memory reserved for the memory manager.
82typedef struct _mp_state_mem_area_t {
83 #if MICROPY_GC_SPLIT_HEAP
84 struct _mp_state_mem_area_t *next;
Damien Georgeb4b10fd2015-01-01 23:30:53 +000085 #endif
86
87 byte *gc_alloc_table_start;
Damien Georged977d262015-12-16 20:09:11 -050088 size_t gc_alloc_table_byte_len;
Damien Georgeb4b10fd2015-01-01 23:30:53 +000089 #if MICROPY_ENABLE_FINALISER
90 byte *gc_finaliser_table_start;
91 #endif
Damien George94fe6e52015-11-27 13:07:48 +000092 byte *gc_pool_start;
93 byte *gc_pool_end;
Damien Georgeb4b10fd2015-01-01 23:30:53 +000094
Ayke van Laethembcc827d2018-01-24 02:09:58 +010095 size_t gc_last_free_atb_index;
Damien Tournoud2dcd7452022-12-15 14:09:19 -080096 size_t gc_last_used_block; // The block ID of the highest block allocated in the area
Ayke van Laethembcc827d2018-01-24 02:09:58 +010097} mp_state_mem_area_t;
98
Ayke van Laethembcc827d2018-01-24 02:09:58 +010099// This structure hold information about the memory allocation system.
100typedef struct _mp_state_mem_t {
101 #if MICROPY_MEM_STATS
102 size_t total_bytes_allocated;
103 size_t current_bytes_allocated;
104 size_t peak_bytes_allocated;
105 #endif
106
107 mp_state_mem_area_t area;
108
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000109 int gc_stack_overflow;
Rob Knegjens4a485312022-04-12 21:26:16 -0700110 MICROPY_GC_STACK_ENTRY_TYPE gc_block_stack[MICROPY_ALLOC_GC_STACK_SIZE];
111 #if MICROPY_GC_SPLIT_HEAP
112 // Array that tracks the area for each block on gc_block_stack.
113 mp_state_mem_area_t *gc_area_stack[MICROPY_ALLOC_GC_STACK_SIZE];
114 #endif
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000115
116 // This variable controls auto garbage collection. If set to 0 then the
117 // GC won't automatically run when gc_alloc can't find enough blocks. But
118 // you can still allocate/free memory and also explicitly call gc_collect.
119 uint16_t gc_auto_collect_enabled;
120
Paul Sokolovsky93e353e2016-07-21 00:37:30 +0300121 #if MICROPY_GC_ALLOC_THRESHOLD
122 size_t gc_alloc_amount;
123 size_t gc_alloc_threshold;
124 #endif
125
Ayke van Laethembcc827d2018-01-24 02:09:58 +0100126 #if MICROPY_GC_SPLIT_HEAP
127 mp_state_mem_area_t *gc_last_free_area;
128 #endif
Damien Georgee1e359f2015-02-07 17:24:10 +0000129
130 #if MICROPY_PY_GC_COLLECT_RETVAL
Damien Georged977d262015-12-16 20:09:11 -0500131 size_t gc_collected;
Damien Georgee1e359f2015-02-07 17:24:10 +0000132 #endif
Damien Georgec93d9ca2016-04-25 15:28:57 +0000133
David Lechnerccc18f02020-01-22 11:19:37 -0600134 #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
Damien Georgec93d9ca2016-04-25 15:28:57 +0000135 // This is a global mutex used to make the GC thread-safe.
136 mp_thread_mutex_t gc_mutex;
137 #endif
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000138} mp_state_mem_t;
139
140// This structure hold runtime and VM information. It includes a section
141// which contains root pointers that must be scanned by the GC.
142typedef struct _mp_state_vm_t {
Damien George749b1612018-05-12 22:09:34 +1000143 //
144 // CONTINUE ROOT POINTER SECTION
145 // This must start at the start of this structure and follows
146 // the state in the mp_state_thread_t structure, continuing
147 // the root pointer section from there.
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000148 //
149
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000150 qstr_pool_t *last_pool;
151
Damien Georgefca57012022-05-04 12:12:11 +1000152 #if MICROPY_TRACKED_ALLOC
153 struct _m_tracked_node_t *m_tracked_head;
154 #endif
155
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000156 // non-heap memory for creating an exception if we can't allocate RAM
157 mp_obj_exception_t mp_emergency_exception_obj;
158
159 // memory for exception arguments if we can't allocate RAM
160 #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
161 #if MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE > 0
Damien Georgeee86de12017-04-10 16:02:56 +1000162 // statically allocated buf (needs to be aligned to mp_obj_t)
163 mp_obj_t mp_emergency_exception_buf[MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE / sizeof(mp_obj_t)];
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000164 #else
165 // dynamically allocated buf
166 byte *mp_emergency_exception_buf;
167 #endif
168 #endif
169
Damien George7f1da0a2016-12-15 13:00:19 +1100170 #if MICROPY_KBD_EXCEPTION
171 // exception object of type KeyboardInterrupt
172 mp_obj_exception_t mp_kbd_exception;
173 #endif
174
Paul Sokolovsky1a1d11f2015-12-05 00:09:10 +0200175 // dictionary with loaded modules (may be exposed as sys.modules)
176 mp_obj_dict_t mp_loaded_modules_dict;
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000177
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000178 // dictionary for the __main__ module
179 mp_obj_dict_t dict_main;
180
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000181 // dictionary for overridden builtins
182 #if MICROPY_CAN_OVERRIDE_BUILTINS
183 mp_obj_dict_t *mp_module_builtins_override_dict;
184 #endif
185
David Lechnerfc3d7ae2022-07-01 12:29:08 -0500186 // Include any root pointers registered with MP_REGISTER_ROOT_POINTER().
187 #ifndef NO_QSTR
188 // Only include root pointer definitions when not doing qstr extraction, because
189 // the qstr extraction stage also generates the root pointers header file.
190 #include "genhdr/root_pointers.h"
191 #endif
192
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000193 //
194 // END ROOT POINTER SECTION
195 ////////////////////////////////////////////////////////////
196
Damien Georgeade9a052015-06-13 21:53:22 +0100197 // pointer and sizes to store interned string data
198 // (qstr_last_chunk can be root pointer but is also stored in qstr pool)
Artyom Skrobov18b1ba02021-05-03 14:17:36 -0400199 char *qstr_last_chunk;
Damien George25784852015-12-17 12:41:40 +0000200 size_t qstr_last_alloc;
201 size_t qstr_last_used;
Damien Georgeade9a052015-06-13 21:53:22 +0100202
David Lechneredbb73a2020-01-22 11:19:37 -0600203 #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
Damien George1f54ad22016-05-26 09:06:46 +0000204 // This is a global mutex used to make qstr interning thread-safe.
205 mp_thread_mutex_t qstr_mutex;
206 #endif
207
Damien George3f420c02018-04-04 14:24:03 +1000208 #if MICROPY_ENABLE_COMPILER
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000209 mp_uint_t mp_optimise_value;
Damien Georgeaf20c2e2019-08-23 11:20:50 +1000210 #if MICROPY_EMIT_NATIVE
211 uint8_t default_emit_opt; // one of MP_EMIT_OPT_xxx
212 #endif
Damien George3f420c02018-04-04 14:24:03 +1000213 #endif
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000214
215 // size of the emergency exception buf, if it's dynamically allocated
216 #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF && MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE == 0
217 mp_int_t mp_emergency_exception_buf_size;
218 #endif
Damien George4cec63a2016-05-26 10:42:53 +0000219
Damien George749b1612018-05-12 22:09:34 +1000220 #if MICROPY_ENABLE_SCHEDULER
221 volatile int16_t sched_state;
Damien George75506e42022-03-23 17:13:03 +1100222
223 #if MICROPY_SCHEDULER_STATIC_NODES
224 // These will usually point to statically allocated memory. They are not
225 // traced by the GC. They are assumed to be zero'd out before mp_init() is
226 // called (usually because this struct lives in the BSS).
227 struct _mp_sched_node_t *sched_head;
228 struct _mp_sched_node_t *sched_tail;
229 #endif
230
231 // These index sched_queue.
Andrew Leech8977c7e2019-03-21 11:52:10 +1100232 uint8_t sched_len;
233 uint8_t sched_idx;
Damien George749b1612018-05-12 22:09:34 +1000234 #endif
235
Damien Georged54208a2022-12-16 17:31:21 +1100236 #if MICROPY_ENABLE_VM_ABORT
237 bool vm_abort;
238 nlr_buf_t *nlr_abort;
239 #endif
240
Damien George4cec63a2016-05-26 10:42:53 +0000241 #if MICROPY_PY_THREAD_GIL
242 // This is a global mutex used to make the VM/runtime thread-safe.
243 mp_thread_mutex_t gil_mutex;
244 #endif
Jim Mussared11ef8f22021-08-18 14:52:48 +1000245
246 #if MICROPY_OPT_MAP_LOOKUP_CACHE
247 // See mp_map_lookup.
248 uint8_t map_lookup_cache[MICROPY_OPT_MAP_LOOKUP_CACHE_SIZE];
249 #endif
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000250} mp_state_vm_t;
251
Jim Mussared3883f292023-10-17 12:27:49 +1100252// This structure holds state that is specific to a given thread. Everything
253// in this structure is scanned for root pointers. Anything added to this
254// structure must have corresponding initialisation added to thread_entry (in
255// py/modthread.c).
Damien George330165a2016-04-22 22:44:56 +0000256typedef struct _mp_state_thread_t {
Damien George330165a2016-04-22 22:44:56 +0000257 // Stack top at the start of program
Damien George330165a2016-04-22 22:44:56 +0000258 char *stack_top;
259
260 #if MICROPY_STACK_CHECK
261 size_t stack_limit;
262 #endif
Damien George02d830c2017-11-26 23:28:40 +1100263
264 #if MICROPY_ENABLE_PYSTACK
265 uint8_t *pystack_start;
266 uint8_t *pystack_end;
267 uint8_t *pystack_cur;
268 #endif
Damien George749b1612018-05-12 22:09:34 +1000269
Damien Georgeb6b39bf2021-05-04 23:56:43 +1000270 // Locking of the GC is done per thread.
271 uint16_t gc_lock_depth;
272
Damien George749b1612018-05-12 22:09:34 +1000273 ////////////////////////////////////////////////////////////
274 // START ROOT POINTER SECTION
275 // Everything that needs GC scanning must start here, and
276 // is followed by state in the mp_state_vm_t structure.
277 //
278
279 mp_obj_dict_t *dict_locals;
280 mp_obj_dict_t *dict_globals;
281
282 nlr_buf_t *nlr_top;
Damien George2757acf2023-05-09 11:03:04 +1000283 nlr_jump_callback_node_t *nlr_jump_callback_top;
Milan Rossa310b3d12019-08-14 16:09:36 +0200284
David Lechnerca920f72021-05-10 21:53:22 -0500285 // pending exception object (MP_OBJ_NULL if not pending)
286 volatile mp_obj_t mp_pending_exception;
287
Damien Georgebb001252021-06-29 17:34:34 +1000288 // If MP_OBJ_STOP_ITERATION is propagated then this holds its argument.
289 mp_obj_t stop_iteration_arg;
290
Milan Rossa310b3d12019-08-14 16:09:36 +0200291 #if MICROPY_PY_SYS_SETTRACE
292 mp_obj_t prof_trace_callback;
293 bool prof_callback_is_executing;
294 struct _mp_code_state_t *current_code_state;
295 #endif
Damien George330165a2016-04-22 22:44:56 +0000296} mp_state_thread_t;
297
Damien George05fe66f2017-02-27 23:56:46 +1100298// This structure combines the above 3 structures.
299// The order of the entries are important for root pointer scanning in the GC to work.
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000300typedef struct _mp_state_ctx_t {
Damien George330165a2016-04-22 22:44:56 +0000301 mp_state_thread_t thread;
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000302 mp_state_vm_t vm;
303 mp_state_mem_t mem;
304} mp_state_ctx_t;
305
306extern mp_state_ctx_t mp_state_ctx;
307
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000308#define MP_STATE_VM(x) (mp_state_ctx.vm.x)
309#define MP_STATE_MEM(x) (mp_state_ctx.mem.x)
David Lechner259d9b62021-05-10 22:18:17 -0500310#define MP_STATE_MAIN_THREAD(x) (mp_state_ctx.thread.x)
Damien Georgeb4b10fd2015-01-01 23:30:53 +0000311
Damien George27cc0772016-04-22 22:52:33 +0000312#if MICROPY_PY_THREAD
Damien George27cc0772016-04-22 22:52:33 +0000313#define MP_STATE_THREAD(x) (mp_thread_get_state()->x)
Damien George5d4bfce2022-12-16 17:30:26 +1100314#define mp_thread_is_main_thread() (mp_thread_get_state() == &mp_state_ctx.thread)
Damien George27cc0772016-04-22 22:52:33 +0000315#else
David Lechner259d9b62021-05-10 22:18:17 -0500316#define MP_STATE_THREAD(x) MP_STATE_MAIN_THREAD(x)
Damien George5d4bfce2022-12-16 17:30:26 +1100317#define mp_thread_is_main_thread() (true)
Damien George27cc0772016-04-22 22:52:33 +0000318#endif
Damien George330165a2016-04-22 22:44:56 +0000319
Alexander Steffen299bc622017-06-29 23:14:58 +0200320#endif // MICROPY_INCLUDED_PY_MPSTATE_H