Skip to content

Commit 1314f39

Browse files
committed
Fix scala#6833: Inline IArray.applys
1 parent 4e62869 commit 1314f39

File tree

3 files changed

+66
-19
lines changed

3 files changed

+66
-19
lines changed

compiler/test/dotty/tools/backend/jvm/ArrayApplyOptTest.scala

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,45 +21,84 @@ class ArrayApplyOptTest extends DottyBytecodeTest {
2121
test("Array[Double]()", newArray0Opcodes(T_DOUBLE))
2222
test("Array[Char]()", newArray0Opcodes(T_CHAR))
2323
test("Array[T]()", newArray0Opcodes(T_INT))
24+
25+
test("IArray[String]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/String"), TypeOp(CHECKCAST, "[Ljava/lang/String;"), Op(POP), Op(RETURN)))
26+
test("IArray[Unit]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), TypeOp(CHECKCAST, "[Lscala/runtime/BoxedUnit;"), Op(POP), Op(RETURN)))
27+
test("IArray[Object]()", List(Op(ICONST_0), TypeOp(ANEWARRAY, "java/lang/Object"), TypeOp(CHECKCAST, "[Ljava/lang/Object;"), Op(POP), Op(RETURN)))
28+
test("IArray[Boolean]()", newArray0Opcodes(T_BOOLEAN, List(TypeOp(CHECKCAST, "[Z"))))
29+
test("IArray[Byte]()", newArray0Opcodes(T_BYTE, List(TypeOp(CHECKCAST, "[B"))))
30+
test("IArray[Short]()", newArray0Opcodes(T_SHORT, List(TypeOp(CHECKCAST, "[S"))))
31+
test("IArray[Int]()", newArray0Opcodes(T_INT, List(TypeOp(CHECKCAST, "[I"))))
32+
test("IArray[Long]()", newArray0Opcodes(T_LONG, List(TypeOp(CHECKCAST, "[J"))))
33+
test("IArray[Float]()", newArray0Opcodes(T_FLOAT, List(TypeOp(CHECKCAST, "[F"))))
34+
test("IArray[Double]()", newArray0Opcodes(T_DOUBLE, List(TypeOp(CHECKCAST, "[D"))))
35+
test("IArray[Char]()", newArray0Opcodes(T_CHAR, List(TypeOp(CHECKCAST, "[C"))))
36+
test("IArray[T]()", newArray0Opcodes(T_INT, List(TypeOp(CHECKCAST, "[I"))))
2437
}
2538

2639
@Test def testArrayGenericApply= {
2740
def opCodes(tpe: String) =
2841
List(Op(ICONST_2), TypeOp(ANEWARRAY, tpe), Op(DUP), Op(ICONST_0), Ldc(LDC, "a"), Op(AASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, "b"), Op(AASTORE), Op(POP), Op(RETURN))
2942
test("""Array("a", "b")""", opCodes("java/lang/String"))
3043
test("""Array[Object]("a", "b")""", opCodes("java/lang/Object"))
44+
45+
def opCodes2(tpe: String) =
46+
List(Op(ICONST_2), TypeOp(ANEWARRAY, tpe), Op(DUP), Op(ICONST_0), Ldc(LDC, "a"), Op(AASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, "b"), Op(AASTORE), TypeOp(CHECKCAST, s"[L$tpe;"), Op(POP), Op(RETURN))
47+
test("""IArray("a", "b")""", opCodes2("java/lang/String"))
48+
test("""IArray[Object]("a", "b")""", opCodes2("java/lang/Object"))
3149
}
3250

33-
@Test def testArrayApplyBoolean =
51+
@Test def testArrayApplyBoolean = {
3452
test("Array(true, false)", newArray2Opcodes(T_BOOLEAN, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(BASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_0), Op(BASTORE))))
53+
test("IArray(true, false)", newArray2Opcodes(T_BOOLEAN, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(BASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_0), Op(BASTORE), TypeOp(CHECKCAST, "[Z"))))
54+
}
3555

36-
@Test def testArrayApplyByte =
56+
@Test def testArrayApplyByte = {
3757
test("Array[Byte](1, 2)", newArray2Opcodes(T_BYTE, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(BASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(BASTORE))))
58+
test("IArray[Byte](1, 2)", newArray2Opcodes(T_BYTE, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(BASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(BASTORE), TypeOp(CHECKCAST, "[B"))))
59+
}
3860

39-
@Test def testArrayApplyShort =
61+
@Test def testArrayApplyShort = {
4062
test("Array[Short](1, 2)", newArray2Opcodes(T_SHORT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(SASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(SASTORE))))
63+
test("IArray[Short](1, 2)", newArray2Opcodes(T_SHORT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(SASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(SASTORE), TypeOp(CHECKCAST, "[S"))))
64+
}
4165

4266
@Test def testArrayApplyInt = {
4367
test("Array(1, 2)", newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE))))
68+
test("IArray(1, 2)", newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE), TypeOp(CHECKCAST, "[I"))))
69+
4470
test("""Array[T](t, t)""", newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Field(GETSTATIC, "Foo$", "MODULE$", "LFoo$;"), Invoke(INVOKEVIRTUAL, "Foo$", "t", "()I", false), Op(IASTORE), Op(DUP), Op(ICONST_1), Field(GETSTATIC, "Foo$", "MODULE$", "LFoo$;"), Invoke(INVOKEVIRTUAL, "Foo$", "t", "()I", false), Op(IASTORE))))
71+
test("""IArray[T](t, t)""", newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Field(GETSTATIC, "Foo$", "MODULE$", "LFoo$;"), Invoke(INVOKEVIRTUAL, "Foo$", "t", "()I", false), Op(IASTORE), Op(DUP), Op(ICONST_1), Field(GETSTATIC, "Foo$", "MODULE$", "LFoo$;"), Invoke(INVOKEVIRTUAL, "Foo$", "t", "()I", false), Op(IASTORE), TypeOp(CHECKCAST, "[I"))))
4572
}
4673

47-
@Test def testArrayApplyLong =
74+
@Test def testArrayApplyLong = {
4875
test("Array(2L, 3L)", newArray2Opcodes(T_LONG, List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2), Op(LASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3), Op(LASTORE))))
76+
test("IArray(2L, 3L)", newArray2Opcodes(T_LONG, List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2), Op(LASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3), Op(LASTORE), TypeOp(CHECKCAST, "[J"))))
77+
}
4978

50-
@Test def testArrayApplyFloat =
79+
@Test def testArrayApplyFloat = {
5180
test("Array(2.1f, 3.1f)", newArray2Opcodes(T_FLOAT, List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2.1f), Op(FASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3.1f), Op(FASTORE))))
81+
test("IArray(2.1f, 3.1f)", newArray2Opcodes(T_FLOAT, List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2.1f), Op(FASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3.1f), Op(FASTORE), TypeOp(CHECKCAST, "[F"))))
82+
}
5283

53-
@Test def testArrayApplyDouble =
84+
@Test def testArrayApplyDouble = {
5485
test("Array(2.2d, 3.2d)", newArray2Opcodes(T_DOUBLE, List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2.2d), Op(DASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3.2d), Op(DASTORE))))
86+
test("IArray(2.2d, 3.2d)", newArray2Opcodes(T_DOUBLE, List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2.2d), Op(DASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3.2d), Op(DASTORE), TypeOp(CHECKCAST, "[D"))))
87+
}
5588

56-
@Test def testArrayApplyChar =
89+
@Test def testArrayApplyChar = {
5790
test("Array('x', 'y')", newArray2Opcodes(T_CHAR, List(Op(DUP), Op(ICONST_0), IntOp(BIPUSH, 120), Op(CASTORE), Op(DUP), Op(ICONST_1), IntOp(BIPUSH, 121), Op(CASTORE))))
91+
test("IArray('x', 'y')", newArray2Opcodes(T_CHAR, List(Op(DUP), Op(ICONST_0), IntOp(BIPUSH, 120), Op(CASTORE), Op(DUP), Op(ICONST_1), IntOp(BIPUSH, 121), Op(CASTORE), TypeOp(CHECKCAST, "[C"))))
92+
}
5893

59-
@Test def testArrayApplyUnit =
94+
@Test def testArrayApplyUnit = {
6095
test("Array[Unit]((), ())", List(Op(ICONST_2), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(DUP),
6196
Op(ICONST_0), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(DUP),
6297
Op(ICONST_1), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(POP), Op(RETURN)))
98+
test("IArray[Unit]((), ())", List(Op(ICONST_2), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(DUP),
99+
Op(ICONST_0), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(DUP),
100+
Op(ICONST_1), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), TypeOp(CHECKCAST, "[Lscala/runtime/BoxedUnit;"), Op(POP), Op(RETURN)))
101+
}
63102

64103
@Test def testArrayInlined = test(
65104
"""{
@@ -77,6 +116,14 @@ class ArrayApplyOptTest extends DottyBytecodeTest {
77116
newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE)))
78117
)
79118

119+
@Test def testArrayInlined3 = test(
120+
"""{
121+
| inline def array[T](xs: =>T*) given (ct: =>scala.reflect.ClassTag[T]): Array[T] = Array(xs: _*)
122+
| array(1, 2)
123+
|}""".stripMargin,
124+
newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE), TypeOp(CHECKCAST, "[I")))
125+
)
126+
80127
private def newArray0Opcodes(tpe: Int, init: List[Any] = Nil): List[Any] =
81128
Op(ICONST_0) :: IntOp(NEWARRAY, tpe) :: init ::: Op(POP) :: Op(RETURN) :: Nil
82129

library/src-bootstrapped/scala/IArray.scala

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,16 @@ object IArray {
5050

5151
/** An immutable array with given elements.
5252
*/
53-
def apply[T: ClassTag](xs: T*): IArray[T] = Array(xs: _*).asInstanceOf
54-
def apply(x: Boolean, xs: Boolean*): IArray[Boolean] = Array(x, xs: _*).asInstanceOf
55-
def apply(x: Byte, xs: Byte*): IArray[Byte] = Array(x, xs: _*).asInstanceOf
56-
def apply(x: Short, xs: Short*): IArray[Short] = Array(x, xs: _*).asInstanceOf
57-
def apply(x: Char, xs: Char*): IArray[Char] = Array(x, xs: _*).asInstanceOf
58-
def apply(x: Int, xs: Int*): IArray[Int] = Array(x, xs: _*).asInstanceOf
59-
def apply(x: Long, xs: Long*): IArray[Long] = Array(x, xs: _*).asInstanceOf
60-
def apply(x: Float, xs: Float*): IArray[Float] = Array(x, xs: _*).asInstanceOf
61-
def apply(x: Double, xs: Double*): IArray[Double] = Array(x, xs: _*).asInstanceOf
62-
def apply(x: Unit, xs: Unit*): IArray[Unit] = Array(x, xs: _*).asInstanceOf
53+
inline def apply[T](xs: =>T*) given (ct: =>ClassTag[T]): IArray[T] = Array(xs: _*).asInstanceOf
54+
inline def apply(x: =>Boolean, xs: =>Boolean*): IArray[Boolean] = Array(x, xs: _*).asInstanceOf
55+
inline def apply(x: =>Byte, xs: =>Byte*): IArray[Byte] = Array(x, xs: _*).asInstanceOf
56+
inline def apply(x: =>Short, xs: =>Short*): IArray[Short] = Array(x, xs: _*).asInstanceOf
57+
inline def apply(x: =>Char, xs: =>Char*): IArray[Char] = Array(x, xs: _*).asInstanceOf
58+
inline def apply(x: =>Int, xs: =>Int*): IArray[Int] = Array(x, xs: _*).asInstanceOf
59+
inline def apply(x: =>Long, xs: =>Long*): IArray[Long] = Array(x, xs: _*).asInstanceOf
60+
inline def apply(x: =>Float, xs: =>Float*): IArray[Float] = Array(x, xs: _*).asInstanceOf
61+
inline def apply(x: =>Double, xs: =>Double*): IArray[Double] = Array(x, xs: _*).asInstanceOf
62+
inline def apply(x: =>Unit, xs: =>Unit*): IArray[Unit] = Array(x, xs: _*).asInstanceOf
6363

6464
/** Concatenates all arrays into a single immutable array.
6565
*

tests/run/iarrays.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ object Test extends App {
3535
def flatten[T: ClassTag](ys: IArray[IArray[T]]) = {
3636
var len = 0
3737
for (i <- 0 until ys.length) len += ys(i).length
38-
val flat = new Array[T](len)
38+
val flat: collection.mutable.Seq[T] = new Array[T](len) // FIXME remove collection.mutable.Seq[T]
3939
var k = 0
4040
for (i <- 0 until ys.length) {
4141
for (j <- 0 until ys(i).length) {

0 commit comments

Comments
 (0)