-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Fix and extend Array.apply varargs optimization #9356
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
Conversation
Found a long standing bug in the existing optimization in the process! |
|
969d2f1
to
971374c
Compare
The existing optimization for `Array.apply[T]` overreaches by assuming that the `ArrayValue` carrying the varargs will have the same element type as the implicit class tag. However, this is not the case when the type argument is a generic type: ``` scala> def foo[T <: AnyRef : reflect.ClassTag](t: T) = Array.apply[T](t); foo[String]("") java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String; ... 32 elided ``` This PR limits the existing optimization to cases where: - The class tag is an implicit arg - The class tag is materialized (not found via normal implicit search) The second criterion excludes the call above. A new, fallback optimization is provided that avoids a temporary array and collection wrapper by emitting: ``` val arr = classTag.newArray(N) ScalaRunTime.arrayUpdate(arr, N, elemN) ... arr } ```
971374c
to
7d81f22
Compare
|
@lrytz I've reworked this a little. |
This comment has been minimized.
This comment has been minimized.
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.
LGTM
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.
I assume I was tagged as reviewer for the interaction with Scala.js. Don't worry: Scala.js runs before cleanup
, so this PR won't affect Scala.js.
Incidentally, I would like it if this particular optimization for Array.apply
would happen earlier in the pipeline, so that we could benefit from it for free. Currently we replicate it in our back-end. ;)
Earlier in the pipeline actually sounds good as we could detect whether the
type argument was concrete or not. At least worth proposing for dotc.
|
Detect in a more straightforward manner, I should say.
…On Sun, 6 Dec 2020 at 20:09, Jason Zaugg ***@***.***> wrote:
Earlier in the pipeline actually sounds good as we could detect whether
the type argument was concrete or not. At least worth proposing for dotc.
|
@retronym is this ready for merge, or do you want to explore the possibility of moving this to earlier in the pipeline here in Scala 2? |
I'm happy enough with the solution here, so booking the progress! |
regression? see scala/scala-dev#760 |
The existing optimization for
Array.apply[T]
overreaches by assuming that theArrayValue
carrying the varargs will have the same element type as the implicit class tag. However, this is not the case when the type argument is a generic type:This PR limits the existing optimization to cases where:
The second criterion excludes the call above.
A new, fallback optimization is provided that avoids a temporary
array and collection wrapper by emitting:
Fixes scala/bug#11882