Skip to content

super() allocates memory, not possible to call a supermethod without heap allocation #2719

Description

@pfalcon

While uPy can call a method without allocating memory, it can't call a supermethod in such way, because super() allocates memory. Can anything be done about that?

Activity

  1. dhylands commented on Dec 24, 2016

    @dhylands
    Contributor

    You could do self.mysuper = super() during __init__ and then call self.mysuper.func() later.

  2. dpgeorge commented on Dec 28, 2016

    @dpgeorge
    Member

    It looks like the only way of making it allocation free is to add a new bytecode and change the compiler.

    For example, the line of code super().foo(1) would change from the current bytecode:

    LOAD_GLOBAL super
    LOAD_GLOBAL __class__
    LOAD_FAST 0
    CALL_FUNCTION n=2 nkw=0 # this creates a super object
    LOAD_METHOD foo # this loads the foo method from the parent
    LOAD_CONST_SMALL_INT 1
    CALL_METHOD n=1 nkw=0
    POP_TOP
    

    to something like:

    LOAD_GLOBAL __class__
    LOAD_FAST 0
    LOAD_SUPER_METHOD foo # this loads the foo method directly
    LOAD_CONST_SMALL_INT 1
    CALL_METHOD n=1 nkw=0
    POP_TOP
    

    That requires a fair bit of addition to the compiler to detect this pattern and emit different code, and then a new bytecode in the VM. A lot of bytes for such an improvement/optimisation.

    I'd suggest doing what @dhylands suggests, pre-creating the super object.

  3. pfalcon commented on Dec 28, 2016

    @pfalcon
    ContributorAuthor

    It looks like the only way of making it allocation free is to add a new bytecode and change the compiler.

    Yes, I'd definitely think this should be handled by the compiler.

    That requires a fair bit of addition to the compiler to detect this pattern and emit different code, and then a new bytecode in the VM. A lot of bytes for such an improvement/optimisation.

    I'm not familiar enough with the compiler, but wouldn't think it would add that much code. And super() already appears to be handled (somewhat) specially, based e.g. on #1158. But the whole point is that claim with which any MicroPython presentation starts - that it can call a method without allocating memory - becomes not true as soon as it comes to calling a supermethod, and that's basic OO pattern. I'd think it's worth fixing that.

    I'd suggest doing what @dhylands suggests, pre-creating the super object.

    Of course I workaround that, even without wasting local var slots, using Python 1.x style super method call: SuperClass.method(self, params). The talk is about fixing it implementation-side to allow efficient idiomatic Python3.

  4. peterhinch commented on Dec 28, 2016

    @peterhinch
    Contributor

    If super() is being revisited I should mention that I've encountered rare cases where it returned an incorrect object. This only happened in the __init__() method and in large programs; despite effort I never managed to produce a small reproducible test case. I worked round the problem using SuperClass.__init__(self, args).
    Alas I failed to record what it returned but it may have been None.

  5. dpgeorge commented on May 6, 2017

    @dpgeorge
    Member

    super() method calls now work without allocating heap memory.

  6. added a commit that references this issue on Mar 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementFeature requests, new feature implementations

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions