Skip to content

Removing the magic from dotty.runtime.Arrays #1167

Closed
@sjrd

Description

@sjrd

dotty.runtime.Arrays has a bunch of magic methods, including the very magic newRefArray, which is one of the 3 methods that stay generic after erasure.

It is very easy to get rid of this complexity, by given an actual parameter of type Class[T] to newRefArray:

def newRefArray[T <: AnyRef](componentType: Class[T], length: Int): Array[T]

The back-end still needs to know about this magic method, and "assume" that componentType is a Literal(Constant(tpe)) (i.e., crash if it isn't). But then the method does not need to be generic anymore after erasure, which is a substantial win, IMO.

We can remove even more magic by given actual bodies to all the newXArray method, leveraging java.lang.reflect.Array.newInstance:

def newRefArray[T <: AnyRef](componentType: Class[T], length: Int): Array[T] =
  java.lang.reflect.Array.newInstance(componentType, length).asInstanceOf[Array[T]]

def newByteArray(length: Int): Array[Byte] =
  java.lang.reflect.Array.newInstance(classOf[Byte], length).asInstanceOf[Array[Byte]]

...

def newUnitArray(length: Int): Array[Unit] =
  java.lang.reflect.Array.newInstance(classOf[BoxedUnit], length).asInstanceOf[Array[Unit]]

and now the back-end does not need to treat these methods specially. Their user-space implementation is perfectly correct.

Of course, on the JVM, that implementation is inefficient, so the JVM back-end would still specialize them. But other back-ends need not have the same problem. For example, Scala.js does not need to specialize those to get full speed, because Array.newInstance is intrisified by the optimizer when the componentType is a literal classOf.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions