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

Proposal: Non-GC object allocations using annotation hints #2

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

WojciechMazur
Copy link
Contributor

A proposal to introduce an annotation-based hints for the compiler on how given object shall be allocated - either GC, stack or arena allocator (Zone)

Rendered proposal

Comment on lines +124 to +125
## Compatibility
The changes would require to include additional information to the NIR format about the allocation hints. These can be introduced in a backward compatible way to the NIR format, in the attached initial implementation we introduce a "normal" `nir.Op.{Class,Array}Alloc` instruction which don't have store any information in NIR about hints, and the alternative op-code for less-likely hinted allocation. The binary and source compatibility of Scala/JVM `nir` definitions would be broken as they're defined using case classes. We don't plan to introduce complexity of toolchain by introducing alternative `nir.Op` instructions.
Copy link

@kubukoz kubukoz Jan 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: how would this affect Scala 2? Would the annotations be no-ops or simply not available at all?

Would @gc be the default (as it is now)? Or would the annotations only have an effect if GC is disabled at build time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: how would this affect Scala 2? Would the annotations be no-ops or simply not available at all?

While prototyping I've observed that we should be able to support it also in Scala 2, the only limitation would be lack of inlining in it. All the annotations used in examples can be also applied in Scala 2.12 and 2.13. If for some reason we would not be able to apply some of annotations they would become no-op.

Would @gc be the default (as it is now)? Or would the annotations only have an effect if GC is disabled at build time?

Yes, the @gc would still be the default. Lack of annotation hint (directly or in the enclosing scope) would always result in allocating using GC. The main purpose of this annotation would be overriding to hint defined for enclosing scope.

locally{ 
  val x = new {} // No direct allocation hint, use enclosing block hint (@stack)
  @gc val y = new {} // Use explicit GC allocation instead of enclosing allocation
  locally {
    val z = new {} // No direct allocation hint, use enclosing block hint (@stack)
  }
}: @stack // Allocate everything in block on stack

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's nice, thanks!


The annotations can be only applied to local `val`/`var` statements or as the type annotation of an expression. It would be illegal to annotate a member of a class - their allocation is predefined by the caller of class constructor.

Custom allocations not involving GC are possible only because Scala Native has never introduced object finalizers - since we don't need to track which object would be collected by the GC and potentially require to run finalization code, we can safely allocate them on the stack or in the explicit zone allowing for the most optimal freeing of resources.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know enough about this, but based on the trickery used in https://github.com/scala-native/scala-native/blob/86551250b939bab687281bea0af81572d2638ab8/javalib/src/main/scala/java/nio/MappedByteBufferData.scala#L18-L35, isn't there some finalization logic regarding WeakReferences? Won't those require some special handling?

I assume WeakReferences allocated on the stack or zone won't have anything special, but what about the WeakReferenceRegistry?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, these are special. WeakReferences have a special handling which allows to internally add weak reference finalizer. Luckily these finalisers cannot be currently defined by the users (they're private to the javalib which does not produce JVM Bytecode required for Scalac compiler).
This might be on of a cases for which we might ignore user's allocation hint and give warning/error instead - this can be made easily at compile time.

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