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
45typedef 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;
52extern 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
60typedef 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.
66typedef 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 uint16_t gc_lock_depth;
84
85 // This variable controls auto garbage collection. If set to 0 then the
86 // GC won't automatically run when gc_alloc can't find enough blocks. But
87 // you can still allocate/free memory and also explicitly call gc_collect.
88 uint16_t gc_auto_collect_enabled;
89
90 #if MICROPY_GC_ALLOC_THRESHOLD
91 size_t gc_alloc_amount;
92 size_t gc_alloc_threshold;
93 #endif
94
95 size_t gc_last_free_atb_index;
96
97 #if MICROPY_PY_GC_COLLECT_RETVAL
98 size_t gc_collected;
99 #endif
100
101 #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
102 // This is a global mutex used to make the GC thread-safe.
103 mp_thread_mutex_t gc_mutex;
104 #endif
105} mp_state_mem_t;
106
107// This structure hold runtime and VM information. It includes a section
108// which contains root pointers that must be scanned by the GC.
109typedef struct _mp_state_vm_t {
110 //
111 // CONTINUE ROOT POINTER SECTION
112 // This must start at the start of this structure and follows
113 // the state in the mp_state_thread_t structure, continuing
114 // the root pointer section from there.
115 //
116
117 qstr_pool_t *last_pool;
118
119 // non-heap memory for creating an exception if we can't allocate RAM
120 mp_obj_exception_t mp_emergency_exception_obj;
121
122 // memory for exception arguments if we can't allocate RAM
123 #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
124 #if MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE > 0
125 // statically allocated buf (needs to be aligned to mp_obj_t)
126 mp_obj_t mp_emergency_exception_buf[MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE / sizeof(mp_obj_t)];
127 #else
128 // dynamically allocated buf
129 byte *mp_emergency_exception_buf;
130 #endif
131 #endif
132
133 #if MICROPY_KBD_EXCEPTION
134 // exception object of type KeyboardInterrupt
135 mp_obj_exception_t mp_kbd_exception;
136 #endif
137
138 // dictionary with loaded modules (may be exposed as sys.modules)
139 mp_obj_dict_t mp_loaded_modules_dict;
140
141 // pending exception object (MP_OBJ_NULL if not pending)
142 volatile mp_obj_t mp_pending_exception;
143
144 #if MICROPY_ENABLE_SCHEDULER
145 mp_sched_item_t sched_queue[MICROPY_SCHEDULER_DEPTH];
146 #endif
147
148 // current exception being handled, for sys.exc_info()
149 #if MICROPY_PY_SYS_EXC_INFO
150 mp_obj_base_t *cur_exception;
151 #endif
152
153 #if MICROPY_PY_SYS_ATEXIT
154 // exposed through sys.atexit function
155 mp_obj_t sys_exitfunc;
156 #endif
157
158 // dictionary for the __main__ module
159 mp_obj_dict_t dict_main;
160
161 // these two lists must be initialised per port, after the call to mp_init
162 mp_obj_list_t mp_sys_path_obj;
163 mp_obj_list_t mp_sys_argv_obj;
164
165 // dictionary for overridden builtins
166 #if MICROPY_CAN_OVERRIDE_BUILTINS
167 mp_obj_dict_t *mp_module_builtins_override_dict;
168 #endif
169
170 #if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE
171 // An mp_obj_list_t that tracks relocated native code to prevent the GC from reclaiming them.
172 mp_obj_t track_reloc_code_list;
173 #endif
174
175 // include any root pointers defined by a port
176 MICROPY_PORT_ROOT_POINTERS
177
178 // root pointers for extmod
179
180 #if MICROPY_REPL_EVENT_DRIVEN
181 vstr_t *repl_line;
182 #endif
183
184 #if MICROPY_PY_OS_DUPTERM
185 mp_obj_t dupterm_objs[MICROPY_PY_OS_DUPTERM];
186 #endif
187
188 #if MICROPY_PY_LWIP_SLIP
189 mp_obj_t lwip_slip_stream;
190 #endif
191
192 #if MICROPY_VFS
193 struct _mp_vfs_mount_t *vfs_cur;
194 struct _mp_vfs_mount_t *vfs_mount_table;
195 #endif
196
197 #if MICROPY_PY_BLUETOOTH
198 mp_obj_t bluetooth;
199 #endif
200
201 //
202 // END ROOT POINTER SECTION
203 ////////////////////////////////////////////////////////////
204
205 // pointer and sizes to store interned string data
206 // (qstr_last_chunk can be root pointer but is also stored in qstr pool)
207 byte *qstr_last_chunk;
208 size_t qstr_last_alloc;
209 size_t qstr_last_used;
210
211 #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
212 // This is a global mutex used to make qstr interning thread-safe.
213 mp_thread_mutex_t qstr_mutex;
214 #endif
215
216 #if MICROPY_ENABLE_COMPILER
217 mp_uint_t mp_optimise_value;
218 #if MICROPY_EMIT_NATIVE
219 uint8_t default_emit_opt; // one of MP_EMIT_OPT_xxx
220 #endif
221 #endif
222
223 // size of the emergency exception buf, if it's dynamically allocated
224 #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF && MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE == 0
225 mp_int_t mp_emergency_exception_buf_size;
226 #endif
227
228 #if MICROPY_ENABLE_SCHEDULER
229 volatile int16_t sched_state;
230 uint8_t sched_len;
231 uint8_t sched_idx;
232 #endif
233
234 #if MICROPY_PY_THREAD_GIL
235 // This is a global mutex used to make the VM/runtime thread-safe.
236 mp_thread_mutex_t gil_mutex;
237 #endif
238} mp_state_vm_t;
239
240// This structure holds state that is specific to a given thread.
241// Everything in this structure is scanned for root pointers.
242typedef struct _mp_state_thread_t {
243 // Stack top at the start of program
244 char *stack_top;
245
246 #if MICROPY_STACK_CHECK
247 size_t stack_limit;
248 #endif
249
250 #if MICROPY_ENABLE_PYSTACK
251 uint8_t *pystack_start;
252 uint8_t *pystack_end;
253 uint8_t *pystack_cur;
254 #endif
255
256 ////////////////////////////////////////////////////////////
257 // START ROOT POINTER SECTION
258 // Everything that needs GC scanning must start here, and
259 // is followed by state in the mp_state_vm_t structure.
260 //
261
262 mp_obj_dict_t *dict_locals;
263 mp_obj_dict_t *dict_globals;
264
265 nlr_buf_t *nlr_top;
266
267 #if MICROPY_PY_SYS_SETTRACE
268 mp_obj_t prof_trace_callback;
269 bool prof_callback_is_executing;
270 struct _mp_code_state_t *current_code_state;
271 #endif
272} mp_state_thread_t;
273
274// This structure combines the above 3 structures.
275// The order of the entries are important for root pointer scanning in the GC to work.
276typedef struct _mp_state_ctx_t {
277 mp_state_thread_t thread;
278 mp_state_vm_t vm;
279 mp_state_mem_t mem;
280} mp_state_ctx_t;
281
282extern mp_state_ctx_t mp_state_ctx;
283
284#define MP_STATE_VM(x) (mp_state_ctx.vm.x)
285#define MP_STATE_MEM(x) (mp_state_ctx.mem.x)
286
287#if MICROPY_PY_THREAD
288extern mp_state_thread_t *mp_thread_get_state(void);
289#define MP_STATE_THREAD(x) (mp_thread_get_state()->x)
290#else
291#define MP_STATE_THREAD(x) (mp_state_ctx.thread.x)
292#endif
293
294#endif // MICROPY_INCLUDED_PY_MPSTATE_H
295