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

Allow user-defined stack types that aren't value types #783

Merged
merged 3 commits into from
Dec 17, 2024

Conversation

yorickpeterse
Copy link
Collaborator

@yorickpeterse yorickpeterse commented Dec 3, 2024

Commit 8ca46bf adds support for defining stack allocated value types using the syntax class inline Name { ... }. Using that syntax, the types are restricted to storing other inline types such as Int or a user-defined inline type.

This PR extends this setup to allow for stack types that can store heap types. The result is the following:

  • class A defines a heap allocated type subject to single ownership
  • class inline A defines a stack allocated type subject to single ownership
  • class copy A defines a stack allocated, immutable value type that is copied upon a move (i.e. the old class inline A setup)

Relevant issues

TODO

  • Swap the inline keyword with the copy keyword
  • Rename inline_* diagnostics tests to copy_*
  • Ensure inline types are subject to move and not copy semantics
  • Disallow assigning fields new values for both inline and copy types
  • Generate a dropper for inline types but not copy types
  • Add inline enum support
    • Using inline for Option results in a shape missing compiler panic
      • This seems to happen when nesting inline or copy types (e.g. Option[Option[Int]])
      • If you nest an empty copy type, we seem to trigger an LLVM SEGV, probably due to the size not being correct
    • With that fixed, we now seem to generate duplicate symbol names for different classes
      • It seems that two different types (e.g. Option[A] and Option[B]) result in the same final symbol names, suggesting we're perhaps not taking into account shapes of sub types?
    • Fix drop error when running the standard library tests
      • We seem to generate a specialization key that includes stack shapes that store unspecialized ClassInstance types, seemingly resulting in the wrong methods being used for calls
  • Handle inline and copy types with a size of zero (= no fields)
    • Enforce a minimum size of 1 bit at the LLVM level
    • Ensure such values can in fact be passed around
  • Generate an $increment method for inline types, and call this when borrowing an inline type
    • This method calls $increment on any inline types stored in self, and for heap types directly increments the borrow count
    • This method must be an inline method
  • Generate a $decrement method for inline types, and call this when dropping a borrow of an inline type
    • This method calls $decrement on any inline types stored in self, and for heap types directly decrements the borrow count
    • This method must be an inline method
  • Reuse logic between GenerateDropper and GenerateInlineMethods
  • Handle cloning inline types at the MIR level
  • Add the shapes StackRef and StackMut for borrows of inline types
  • Allow fn mut methods for inline types, as heap values can still be mutated in place as expected
  • Don't collapse ref T and mut T into T for inline types, only do that for copy types
  • Specialize the StackRef and StackMut shapes such that they call $increment/$decrement
  • Add inko fmt tests
  • Add diagnostic tests
  • Figure out why making Result an inline type results in a segfault when running the standard library tests
  • Figure out why making std.sys.Stdout an inline type crashes the std.sys tests
  • Figure out why making std.stdio.Stdout an inline type crashes the test suite
  • Go over the standard library types and mark them as inline where appropriate, commit this separately from the main set of changes

After the necessary code changes are made:

  • Add Tree sitter support for the copy keyword: inko-lang/tree-sitter-inko@1419efb
  • Add Vim syntax support for the copy keyword
  • Add VS Code syntax support for the copy keyword
  • Update the documentation

@yorickpeterse yorickpeterse added feature New things to add to Inko, such as a new standard library module performance Changes related to improving performance compiler Changes related to the compiler labels Dec 3, 2024
@yorickpeterse yorickpeterse added this to the 0.18.0 milestone Dec 3, 2024
@yorickpeterse yorickpeterse self-assigned this Dec 3, 2024
@yorickpeterse yorickpeterse force-pushed the stack-types branch 5 times, most recently from d5a99e0 to d3cff96 Compare December 6, 2024 22:14
@yorickpeterse

This comment was marked as resolved.

@yorickpeterse yorickpeterse force-pushed the stack-types branch 3 times, most recently from 9ecc573 to 6db033d Compare December 7, 2024 23:31
@yorickpeterse

This comment was marked as resolved.

@yorickpeterse yorickpeterse force-pushed the stack-types branch 2 times, most recently from 4da407c to a08ee42 Compare December 8, 2024 22:37
@yorickpeterse

This comment was marked as resolved.

@yorickpeterse yorickpeterse force-pushed the stack-types branch 2 times, most recently from 3878e72 to 382f82d Compare December 9, 2024 23:27
@yorickpeterse yorickpeterse marked this pull request as ready for review December 9, 2024 23:28
@yorickpeterse yorickpeterse force-pushed the stack-types branch 3 times, most recently from 7f2dd93 to 66dc241 Compare December 10, 2024 19:42
@yorickpeterse

This comment was marked as resolved.

@yorickpeterse

This comment was marked as resolved.

@yorickpeterse yorickpeterse force-pushed the stack-types branch 4 times, most recently from 1601664 to b43ef93 Compare December 13, 2024 21:44
@yorickpeterse

This comment was marked as outdated.

@yorickpeterse

This comment was marked as resolved.

Commit 8ca46bf introduces the ability to define stack allocated value
types. This commit extends support to also allow defining of stack
allocated types containing heap types. This means there are now three
different kinds of allocation strategies:

- class A: heap allocated, subject to single ownership
- class inline A: stack allocated, subject to single ownership
- class copy A: stack allocated, immutable value type that's copied upon
  a move

When borrowing an `inline` type, the compiler copies the stack allocated
portion and increments the borrow count for any heap values stored
within. When dropping this copy, the borrow count is reduces. This means
that borrowing an `inline` type is equivalent to borrowing all interior
heap values, just without the need for doing so manually. This approach
is inspired by Swift, which takes a similar approach using (atomic)
reference counting.

This fixes #780.

Changelog: added
This adds the InvalidFileDescriptor constructor to the std.io.Error
type, which is mapped to the EBADF error code.

Changelog: added
For types such as tuples, Option, Result, and various others, there's no
need to allocate them on the heap. In fact, for frequently used types
such as Option and Result this does nothing but harm performance. To
resolve this, various types are marked as `inline` such that they are
allocated on the stack.

IO types such as ReadOnlyFile and Stdout remain heap types for the time
being, as this allows casting them to e.g. the Write trait. This in turn
is useful if some deeply nested type needs to act on different Write
types, but you don't want to litter generic type arguments all over the
place.

Changelog: performance
@yorickpeterse yorickpeterse merged commit 52e4318 into main Dec 17, 2024
26 checks passed
@yorickpeterse yorickpeterse deleted the stack-types branch December 17, 2024 02:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler Changes related to the compiler feature New things to add to Inko, such as a new standard library module performance Changes related to improving performance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant