-
Notifications
You must be signed in to change notification settings - Fork 3.1k
@nullOut annotation #10959
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
base: 2.13.x
Are you sure you want to change the base?
@nullOut annotation #10959
Conversation
|
😎🆒 |
|
I don't understand Seth's emojis so ❤️ and 🚀. |
|
I took another look at
scala> val ll: LazyList[Int] = 1 #:: 2 #:: 3 #:: ll
val ll: LazyList[Int] = LazyList(<not computed>)
scala> ll.mkString
val res0: String = 123<cycle>Even though that could be considered an inconsistency, it seems desired (scala/collection-strawman#550, scala/bug#8680). Cycle detection uses the 2x/1x iterator idea (Floyd's Algorithm). So for a very long non-cyclic LazyList, the slow pointer points to the middle of the list when the fast one reaches the end. So at least half of the list cannot be GC'd. I don't see how we could fix it. |
260cea2 to
8f785ec
Compare
|
@-ing @NthPortal and @scala/collections |
NthPortal
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
neat! I don't know enough the compiler to be confident in saying anything about the implementation, but it look decent to me
|
Hello, optimizer! |
8f785ec to
d783f87
Compare
8fd5c74 to
4fa73fe
Compare
`this: @nullOut` or `local: @nullOut` sets the local variable slot to `null` after loading the value on the stack. Mixin forwarders, static mixin accessors and bridges set the receiver local to `null` if the target method is annotated `@nullOut`, for example. Co-authored-by: Stefan Zeiger <[email protected]>
Needs a restarr to work! The forwarder / alias `IterableOnceOps./:` uses `@nullOut` to clear the `this` reference before calling `foldLeft`. The annotation is also on the method itself to ensure mixin forwarders (generated in the subclass) and the static mixin accessor (generated in the trait) null out the receiver before invoking `/:`. After removing `LazyList.foldLeft`, it inherits the implementation from LinearSeqOps. That method again uses `@nullOut` twice, once to clear `this` when it's no longer needed, and once on the method for the generated accessors. I think we should *not* use `@nullOut` everywhere in the standard library, only on methods that cannot be overridden in LazyList, like `/:`. `@nullOut` works correctly on `mkString` too, but unfortunately the `addString` override in LazyList prevents GC of processed elements due to cycle detection.
4fa73fe to
a4216e5
Compare
Includes changes from #10937.
Continuation of #7990.
this: @nullOutorlocal: @nullOutsets the local variable slot tonullafter loading the value on the stack.Mixin forwarders, static mixin accessors and bridges set the receiver
local to
nullif the target method is annotated@nullOut.As a test, use
@nullOutfor the forwarder / aliasIterableOnceOps./:.It uses
@nullOutto clearthe
thisreference before callingfoldLeft. The annotation isalso on the method itself to ensure mixin forwarders (generated in
the subclass) and the static mixin accessor (generated in the trait)
null out the receiver before invoking
/:.After removing
LazyList.foldLeft, it inherits the implementationfrom LinearSeqOps. That method again uses
@nullOuttwice, onceto clear
thiswhen it's no longer needed, and once on the methodfor the generated accessors.
I think we should not use
@nullOuteverywhere in the standardlibrary, only on methods that cannot be overridden in LazyList.
So, for final methods like
/:ormkString.