acton icon indicating copy to clipboard operation
acton copied to clipboard

Support single object areas for malloced objects with the same lifetime

Open plajjan opened this issue 1 year ago • 0 comments

Could we support having one memory area that we place multiple objects into to reduce the number of malloc calls? We would do this for malloced objects that have the same or roughly the same lifetime. Two examples come to mind:

  • actor attributes, they all share the exact lifetime of the actor
  • variables in functions / methods that are broken into multiple continuations, which have roughly the same lifetime

Today we malloc each individual object and then pass these to the next continuation.

Consider this example:


actor Foo():
    def foo():
        pass

actor main(env):
    def _one():
        a = 1231
        f = Foo()
        a += 1232
        b = 456
        await async f.foo()
        a += b
        env.exit(0)

    _one()

The first part of _one() that sets a = 1231 and f = Foo() turns into:

$R fooQ_mainD__oneG_local (fooQ_main self, $Cont C_cont) {
    B_int a = to$int(1231);
    return fooQ_FooG_newact((($Cont)fooQ_L_5ContG_new(a, self, C_cont)));
}

Creating an actor leads to chopping into continuations, so that's all we do, and a is passed as an argument to the next continuation. Skipping the irrelevant parts, next up we have:

$R fooQ_L_2C_1cont (fooQ_main self, $Cont C_cont, fooQ_Foo f, B_int a) {
    a = ((B_int (*) (B_Plus, B_int, B_int))fooQ_W_33->$class->__iadd__)(fooQ_W_33, a, to$int(1232));
    B_int b = to$int(456);
    return $AWAIT((($Cont)fooQ_L_4ContG_new(b, a, self, C_cont)), ((B_Msg (*) (fooQ_Foo))f->$class->foo)(f));
}

so here the next variable is malloced b = 456 and further passed on as an argument to the next continuation together with a.

Would it not be advantageous to allocate one chunk on the heap for all variables in this function, i.e. a and b?

I guess this is close to trivial for actor attributes, since it doesn't share it's attributes with anyone external and all its continuations / functions can just have access to its attributes passed around as pointers, right?

For method continuations we still need an escape analysis to determine if variables are returned or passed to other actors, right?

I think this strategy is different and complementary to that of more normal escape analysis to move (return) objects to being stack allocated in outer functions and passed as pointers. Such escape analysis is still bound to the stack whereas actor attributes and variables in functions split into continuations are not bound by the stack.

plajjan avatar Jan 30 '24 08:01 plajjan