summaryrefslogtreecommitdiffstatshomepage
path: root/py/vm.c
Commit message (Collapse)AuthorAge
* py: Add LOAD_SUPER_METHOD bytecode to allow heap-free super meth calls.Damien George2017-04-22
| | | | | | | | | | | | | | | | | | | | | | This patch allows the following code to run without allocating on the heap: super().foo(...) Before this patch such a call would allocate a super object on the heap and then load the foo method and call it right away. The super object is only needed to perform the lookup of the method and not needed after that. This patch makes an optimisation to allocate the super object on the C stack and discard it right after use. Changes in code size due to this patch are: bare-arm: +128 minimal: +232 unix x64: +416 unix nanbox: +364 stmhal: +184 esp8266: +340 cc3200: +128
* py/vm: Fix VM opcode tracing to print correct stack pointer.Damien George2017-03-27
| | | | Also const_table is now moved to the code_state->fun_bc structure.
* py: Use mp_locals/mp_globals accessor funcs instead of MP_STATE_CTX.Damien George2017-03-24
| | | | To improve maintainability of the code.
* py: Define and use MP_OBJ_ITER_BUF_NSLOTS to get size of stack iter buf.Damien George2017-03-23
| | | | | | | | It improves readability of code and reduces the chance to make a mistake. This patch also fixes a bug with nan-boxing builds by rounding up the calculation of the new NSLOTS variable, giving the correct number of slots (being 4) even if mp_obj_t is larger than the native machine size.
* py/vm: Don't release the GIL if the scheduler is locked.Damien George2017-03-20
| | | | | | | | | | | | | The scheduler being locked general means we are running a scheduled function, and switching to another thread violates that, so don't switch in such a case (even though we technically could). And if we are running a scheduled function then we want to finish it ASAP, so we shouldn't switch to another thread. Furthermore, ports with threading enabled will lock the scheduler during a hard IRQ, and this patch to the VM will make sure that threads are not switched during a hard IRQ (which would crash the VM).
* py: Add micropython.schedule() function and associated runtime code.Damien George2017-03-20
|
* py: Provide mp_decode_uint_value to help optimise stack usage.Damien George2017-03-17
| | | | | This has a noticeable improvement on x86-64 and Thumb2 archs, where stack usage is reduced by 2 machine words in the VM.
* py: Reduce size of mp_code_state_t structure.Damien George2017-03-17
| | | | | | | | | | | | | | | | | | | | | Instead of caching data that is constant (code_info, const_table and n_state), store just a pointer to the underlying function object from which this data can be derived. This helps reduce stack usage for the case when the mp_code_state_t structure is stored on the stack, as well as heap usage when it's stored on the heap. The downside is that the VM becomes a little more complex because it now needs to derive the data from the underlying function object. But this doesn't impact the performance by much (if at all) because most of the decoding of data is done outside the main opcode loop. Measurements using pystone show that little to no performance is lost. This patch also fixes a nasty bug whereby the bytecode can be reclaimed by the GC during execution. With this patch there is always a pointer to the function object held by the VM during execution, since it's stored in the mp_code_state_t structure.
* py: Optimise storage of iterator so it takes only 4 slots on Py stack.Damien George2017-02-16
|
* py: Make FOR_ITER opcode pop 1+4 slots from the stack when finished.Damien George2017-02-16
| | | | The extra 4 slots correspond to the iterator object stored on the stack.
* py: Allow bytecode/native to put iter_buf on stack for simple for loops.Damien George2017-02-16
| | | | | So that the "for x in it: ..." statement can now work without using the heap (so long as the iterator argument fits in an iter_buf structure).
* py: Add iter_buf to getiter type method.Damien George2017-02-16
| | | | | | | | | | | | | | | Allows to iterate over the following without allocating on the heap: - tuple - list - string, bytes - bytearray, array - dict (not dict.keys, dict.values, dict.items) - set, frozenset Allows to call the following without heap memory: - all, any, min, max, sum TODO: still need to allocate stack memory in bytecode for iter_buf.
* py/vm: Convert mp_uint_t to size_t where appropriate.Damien George2017-02-16
|
* py/vm: Add MICROPY_PY_THREAD_GIL_VM_DIVISOR option.Damien George2017-02-15
| | | | | | This improves efficiency of GIL release within the VM, by only doing the release after a fixed number of jump-opcodes have executed in the current thread.
* py/showbc: Make sure to set the const_table before printing bytecode.Damien George2017-01-27
|
* py/vm: Use MP_OBJ_FROM_PTR to cast a type to an object.Damien George2016-09-27
|
* py: Only store the exception instance on Py stack in bytecode try block.Damien George2016-09-27
| | | | | | | | | | | | | | | | | | | | When an exception is raised and is to be handled by the VM, it is stored on the Python value stack so the bytecode can access it. CPython stores 3 objects on the stack for each exception: exc type, exc instance and traceback. uPy followed this approach, but it turns out not to be necessary. Instead, it is enough to store just the exception instance on the Python value stack. The only place where the 3 values are needed explicitly is for the __exit__ handler of a with-statement context, but for these cases the 3 values can be extracted from the single exception instance. This patch removes the need to store 3 values on the stack, and instead just stores the exception instance. Code size is reduced by about 50-100 bytes, the compiler and VM are slightly simpler, generate bytecode is smaller (by 2 bytes for each try block), and the Python value stack is reduced in size for functions that handle exceptions.
* py: Combine 3 comprehension opcodes (list/dict/set) into 1.Damien George2016-09-19
| | | | | | | | | With the previous patch combining 3 emit functions into 1, it now makes sense to also combine the corresponding VM opcodes, which is what this patch does. This eliminates 2 opcodes which simplifies the VM and reduces code size, in bytes: bare-arm:44, minimal:64, unix(NDEBUG,x86-64):272, stmhal:92, esp8266:200. Profiling (with a simple script that creates many list/dict/set comprehensions) shows no measurable change in performance.
* py: Rename struct mp_code_state to mp_code_state_t.Damien George2016-08-27
| | | | Also at _t to mp_exc_stack pre-declaration in struct typedef.
* py: Implement a simple global interpreter lock.Damien George2016-06-28
| | | | | This makes the VM/runtime thread safe, at the cost of not being able to run code in parallel.
* py/vm: "yield from" didn't handle MP_OBJ_STOP_ITERATION optimization.Paul Sokolovsky2016-04-28
| | | | E.g. crashed when yielding from already stopped generators.
* py/vm: Add macros to hook into various points in the VM.Damien George2016-02-17
| | | | | | | | | | | | | | | | | | | | These can be used to insert arbitrary checks, polling, etc into the VM. They are left general because the VM is a highly tuned loop and it should be up to a given port how that port wants to modify the VM internals. One common use would be to insert a polling check, but only done after a certain number of opcodes were executed, so as not to slow down the VM too much. For example: #define MICROPY_VM_HOOK_COUNT (30) #define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT #define MICROPY_VM_HOOK_POLL if (--vm_hook_divisor == 0) { \ vm_hook_divisor = MICROPY_VM_HOOK_COUNT; extern void vm_hook_function(void); vm_hook_function(); } #define MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_POLL #define MICROPY_VM_HOOK_RETURN MICROPY_VM_HOOK_POLL
* py/vm: Fix popping of exception block in UNWIND_JUMP opcode.Damien George2016-02-01
| | | | Fixes issue #1812.
* py: Change exception traceback data to use size_t instead of mp_uint_t.Damien George2016-01-02
| | | | | The traceback array stores qstrs and line numbers. qstrs are typed as size_t, and line numbers should safely fit in size_t as well.
* py: Handle case of return within the finally block of try-finally.Damien George2015-12-24
| | | | Addresses issue #1636.
* py: Fix MICROPY_STACKLESS mode to compile with MICROPY_OBJ_REPR_D.Damien George2015-12-17
|
* py: Make UNARY_OP_NOT a first-class op, to agree with Py not semantics.Damien George2015-12-10
| | | | | | | | | | | | | | | Fixes #1684 and makes "not" match Python semantics. The code is also simplified (the separate MP_BC_NOT opcode is removed) and the patch saves 68 bytes for bare-arm/ and 52 bytes for minimal/. Previously "not x" was implemented as !mp_unary_op(x, MP_UNARY_OP_BOOL), so any given object only needs to implement MP_UNARY_OP_BOOL (and the VM had a special opcode to do the ! bit). With this patch "not x" is implemented as mp_unary_op(x, MP_UNARY_OP_NOT), but this operation is caught at the start of mp_unary_op and dispatched as !mp_obj_is_true(x). mp_obj_is_true has special logic to test for truthness, and is the correct way to handle the not operation.
* py: Wrap all obj-ptr conversions in MP_OBJ_TO_PTR/MP_OBJ_FROM_PTR.Damien George2015-11-29
| | | | | | | | | This allows the mp_obj_t type to be configured to something other than a pointer-sized primitive type. This patch also includes additional changes to allow the code to compile when sizeof(mp_uint_t) != sizeof(void*), such as using size_t instead of mp_uint_t, and various casts.
* py: Add MICROPY_PERSISTENT_CODE so code can persist beyond the runtime.Damien George2015-11-13
| | | | | | | | | | | Main changes when MICROPY_PERSISTENT_CODE is enabled are: - qstrs are encoded as 2-byte fixed width in the bytecode - all pointers are removed from bytecode and put in const_table (this includes const objects and raw code pointers) Ultimately this option will enable persistence for not just bytecode but also native code.
* py: Fix with+for+return bug by popping for-iter when unwinding exc stack.Damien George2015-10-15
| | | | Addresses issue #1182.
* vm: Handle "raise X from Y" statements the best way we can.Paul Sokolovsky2015-09-01
| | | | | By issuing a warning that exception chaining is not supported, and ignoring "from Y" argument.
* py: Remove mp_load_const_bytes and instead load precreated bytes object.Damien George2015-06-25
| | | | | | | | | | | | | | | | Previous to this patch each time a bytes object was referenced a new instance (with the same data) was created. With this patch a single bytes object is created in the compiler and is loaded directly at execute time as a true constant (similar to loading bignum and float objects). This saves on allocating RAM and means that bytes objects can now be used when the memory manager is locked (eg in interrupts). The MP_BC_LOAD_CONST_BYTES bytecode was removed as part of this. Generated bytecode is slightly larger due to storing a pointer to the bytes object instead of the qstr identifier. Code size is reduced by about 60 bytes on Thumb2 architectures.
* py: Remove mp_load_const_str and replace uses with inlined version.Damien George2015-06-25
|
* py: Add MP_BINARY_OP_DIVMOD to simplify and consolidate divmod builtin.Damien George2015-06-13
|
* py: Convert hash API to use MP_UNARY_OP_HASH instead of ad-hoc function.Damien George2015-05-12
| | | | | | | | | | | | | | Hashing is now done using mp_unary_op function with MP_UNARY_OP_HASH as the operator argument. Hashing for int, str and bytes still go via fast-path in mp_unary_op since they are the most common objects which need to be hashed. This lead to quite a bit of code cleanup, and should be more efficient if anything. It saves 176 bytes code space on Thumb2, and 360 bytes on x86. The only loss is that the error message "unhashable type" is now the more generic "unsupported type for __hash__".
* vm: Properly handle StopIteration raised in user instance iterator.Paul Sokolovsky2015-05-11
| | | | I.e. in bytecode Python functions.
* vm: Null pointer test when checking for StopIteration optimizations.Paul Sokolovsky2015-05-10
| | | | | | | When generator raises exception, it is automatically terminated (by setting its code_state.ip to 0), which interferes with this check. Triggered in particular by CPython's test_pep380.py.
* py: Remove LOAD_CONST_ELLIPSIS bytecode, use LOAD_CONST_OBJ instead.Damien George2015-05-05
| | | | | Ellipsis constant is rarely used so no point having an extra bytecode for it.
* vm: On exiting except block, clear sys.exc_info() value.Paul Sokolovsky2015-04-26
| | | | | | This doesn't handle case fo enclosed except blocks, but once again, sys.exc_info() support is a workaround for software which uses it instead of properly catching exceptions via variable in except clause.
* modsys: Add basic sys.exc_info() implementation.Paul Sokolovsky2015-04-25
| | | | | | The implementation is very basic and non-compliant and provided solely for CPython compatibility. The function itself is bad Python2 heritage, its usage is discouraged.
* py: Modify bytecode "with" behaviour so it doesn't use any heap.Damien George2015-04-24
| | | | | | Before this patch a "with" block needed to create a bound method object on the heap for the __exit__ call. Now it doesn't because we use load_method instead of load_attr, and save the method+self on the stack.
* py: Combine load_attr and store_attr type methods into one (attr).Damien George2015-04-11
| | | | | | This simplifies the API for objects and reduces code size (by around 400 bytes on Thumb2, and around 2k on x86). Performance impact was measured with Pystone score, but change was barely noticeable.
* py: Adjust some spaces in code style/format, purely for consistency.Damien George2015-04-09
|
* py: Fix msvc warning '*/ found outside of comment'stijn2015-04-09
| | | | | Also prevents some of the weaker syntax parsers out there treating the whole '*/*const*/' part as a comment
* py: Add finer configuration of static funcs when not in stackless mode.Damien George2015-04-02
| | | | Also rename call_args_t to mp_call_args_t.
* vm: Support strict stackless mode, with proper exception reporting.Paul Sokolovsky2015-04-03
| | | | | | I.e. in this mode, C stack will never be used to call a Python function, but if there's no free heap for a call, it will be reported as RuntimeError (as expected), not MemoryError.
* vm: Implement stackless for CALL_FUNCTION_VAR_KW & CALL_METHOD_VAR_KW.Paul Sokolovsky2015-04-03
|
* vm: Stackless support for MP_BC_CALL_METHOD.Paul Sokolovsky2015-04-03
|
* vm: If there's no heap to call function in stackless manner, call via C stack.Paul Sokolovsky2015-04-03
|
* vm: Initial support for calling bytecode functions w/o C stack ("stackless").Paul Sokolovsky2015-04-03
|