Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all: various fixes for [heap]/auto-heap handling #10033

Merged
merged 39 commits into from
May 7, 2021

Conversation

UweKrueger
Copy link
Member

@UweKrueger UweKrueger commented May 7, 2021

This if a followup to #9873. In addition to those cases handled there some additional checks are performed and some features are added/fixed:

  • returning addresses of "borrowed" objects is also checked if implicit de-referencing is used - like in
    fn f(mut x St) &St {
        return x // only allowed if `St` is declared as `[heap]`
    }
  • assignments of references to other handles is checked - as in
    fn g(x &St) &St {
        y := x // only allowed if `St` is declared as `[heap]`
        return y
    }
  • in the same manner as above using a reference as struct element initialization is checked:
    struct Qwe {
        z &St
    }

    fn h(x &St) Qwe {
        s := Qwe{
            z: x // only allowed if `St` is declared as `[heap]`
        }
        return s
}
  • a bug is fixed that lead to invalid C code in some cases because [heap] objects could become "auto-heap" at the same time
  • in parser not all definitions of structs are available, yet, so the information if a type is declared [heap] is not reliable. For this reason all decisions based on this declaration are postponed to checker.
  • If a struct is declared [heap] it is now transferred to the heap automatically even if initialized as value object. This makes the conversion of existing code significantly simpler because only [heap] has to be added at one single place:
    [heap]
    struct St { ... }

    fn f() &St {
        a := St{...} // will be on heap even when not declared as `&St{...}`
        return &a
    }

@UweKrueger UweKrueger marked this pull request as ready for review May 7, 2021 10:53
@spytheman
Copy link
Member

Good work. I am waiting for the CI to be green again (I think it should be in about 30min), then I'll merge it.

@medvednikov medvednikov merged commit d26ac56 into vlang:master May 7, 2021
@dumblob
Copy link
Contributor

dumblob commented May 7, 2021

Very good! This'll build more pressure on implementing some heuristic on passing non-mut non-& struct arguments without copying them as now if one wants to have efficient something like this:

struct Abc {
mut:
  ... // some big struct (maybe bigger than cache line or bigger than the platforms number of general purpose registers)
}
struct Def {
  ... // some big struct - this time fully immutable
}
fn pass( a &Abc, b &Def ) ( &Abc, &Def ) {
  return a, b
}
x := Abc{}  // x is immutable
y := Def{}  // y is immutable
_, z := pass( &x, &y )  // maybe make an exception for cases when receiver discards the value?

She has to write instead the following to be correct and not use [heap]:

...
fn pass( a Abc, b Def ) ( Abc, Def ) {
  return a, b
}
x := Abc{}  // immutable
y := Def{}  // immutable
_, z := pass( x, y )  // shall be passed as pointer internally

But that's inefficient as of now making [heap] still a viable option 😢.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants