1. 09 Jun, 2017 1 commit
    • Damien George's avatar
      py: Provide mp_decode_uint_skip() to help reduce stack usage. · a8a5d1e8
      Damien George authored
      Taking the address of a local variable leads to increased stack usage, so
      the mp_decode_uint_skip() function is added to reduce the need for taking
      addresses.  The changes in this patch reduce stack usage of a Python call
      by 8 bytes on ARM Thumb, by 16 bytes on non-windowing Xtensa archs, and by
      16 bytes on x86-64.  Code size is also slightly reduced on most archs by
      around 32 bytes.
      a8a5d1e8
  2. 29 May, 2017 1 commit
  3. 25 May, 2017 2 commits
  4. 22 Apr, 2017 1 commit
    • Damien George's avatar
      py: Add LOAD_SUPER_METHOD bytecode to allow heap-free super meth calls. · dd11af20
      Damien George authored
      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
      dd11af20
  5. 26 Mar, 2017 1 commit
  6. 24 Mar, 2017 1 commit
  7. 23 Mar, 2017 1 commit
  8. 20 Mar, 2017 2 commits
    • Damien George's avatar
      py/vm: Don't release the GIL if the scheduler is locked. · 1a5c8d10
      Damien George authored
      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).
      1a5c8d10
    • Damien George's avatar
  9. 17 Mar, 2017 2 commits
    • Damien George's avatar
      py: Provide mp_decode_uint_value to help optimise stack usage. · 5640e6da
      Damien George authored
      This has a noticeable improvement on x86-64 and Thumb2 archs, where stack
      usage is reduced by 2 machine words in the VM.
      5640e6da
    • Damien George's avatar
      py: Reduce size of mp_code_state_t structure. · 71a3d6ec
      Damien George authored
      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.
      71a3d6ec
  10. 16 Feb, 2017 5 commits
  11. 15 Feb, 2017 1 commit
  12. 27 Jan, 2017 1 commit
  13. 27 Sep, 2016 2 commits
    • Damien George's avatar
      71fec076
    • Damien George's avatar
      py: Only store the exception instance on Py stack in bytecode try block. · f040685b
      Damien George authored
      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.
      f040685b
  14. 19 Sep, 2016 1 commit
    • Damien George's avatar
      py: Combine 3 comprehension opcodes (list/dict/set) into 1. · adaf0d86
      Damien George authored
      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.
      adaf0d86
  15. 27 Aug, 2016 1 commit
  16. 28 Jun, 2016 1 commit
  17. 27 Apr, 2016 1 commit
  18. 17 Feb, 2016 1 commit
    • Damien George's avatar
      py/vm: Add macros to hook into various points in the VM. · 40d8430e
      Damien George authored
      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
      40d8430e
  19. 01 Feb, 2016 1 commit
  20. 02 Jan, 2016 1 commit
  21. 24 Dec, 2015 1 commit
  22. 17 Dec, 2015 1 commit
  23. 10 Dec, 2015 1 commit
    • Damien George's avatar
      py: Make UNARY_OP_NOT a first-class op, to agree with Py not semantics. · bdbe8c9a
      Damien George authored
      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.
      bdbe8c9a
  24. 29 Nov, 2015 1 commit
    • Damien George's avatar
      py: Wrap all obj-ptr conversions in MP_OBJ_TO_PTR/MP_OBJ_FROM_PTR. · 999cedb9
      Damien George authored
      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.
      999cedb9
  25. 13 Nov, 2015 1 commit
    • Damien George's avatar
      py: Add MICROPY_PERSISTENT_CODE so code can persist beyond the runtime. · c8e9c0d8
      Damien George authored
      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.
      c8e9c0d8
  26. 15 Oct, 2015 1 commit
  27. 01 Sep, 2015 1 commit
  28. 25 Jun, 2015 2 commits
    • Damien George's avatar
      py: Remove mp_load_const_bytes and instead load precreated bytes object. · 59fba2d6
      Damien George authored
      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.
      59fba2d6
    • Damien George's avatar
  29. 13 Jun, 2015 1 commit
  30. 12 May, 2015 1 commit
    • Damien George's avatar
      py: Convert hash API to use MP_UNARY_OP_HASH instead of ad-hoc function. · c2a4e4ef
      Damien George authored
      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__".
      c2a4e4ef
  31. 11 May, 2015 1 commit