Skip to content

Commit 84a974c

Browse files
committed
Fix scala#6833: Inline IArray.applys
1 parent 7795cb7 commit 84a974c

File tree

2 files changed

+83
-27
lines changed

2 files changed

+83
-27
lines changed

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

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,45 +21,93 @@ 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, TypeOp(CHECKCAST, "[Z") :: Nil))
29+
test("IArray[Byte]()", newArray0Opcodes(T_BYTE, TypeOp(CHECKCAST, "[B") :: Nil))
30+
test("IArray[Short]()", newArray0Opcodes(T_SHORT, TypeOp(CHECKCAST, "[S") :: Nil))
31+
test("IArray[Int]()", newArray0Opcodes(T_INT, TypeOp(CHECKCAST, "[I") :: Nil))
32+
test("IArray[Long]()", newArray0Opcodes(T_LONG, TypeOp(CHECKCAST, "[J") :: Nil))
33+
test("IArray[Float]()", newArray0Opcodes(T_FLOAT, TypeOp(CHECKCAST, "[F") :: Nil))
34+
test("IArray[Double]()", newArray0Opcodes(T_DOUBLE, TypeOp(CHECKCAST, "[D") :: Nil))
35+
test("IArray[Char]()", newArray0Opcodes(T_CHAR, TypeOp(CHECKCAST, "[C") :: Nil))
36+
test("IArray[T]()", newArray0Opcodes(T_INT, TypeOp(CHECKCAST, "[I") :: Nil))
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 =
34-
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))))
51+
@Test def testArrayApplyBoolean = {
52+
val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(BASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_0), Op(BASTORE))
53+
test("Array(true, false)", newArray2Opcodes(T_BOOLEAN, init))
54+
test("IArray(true, false)", newArray2Opcodes(T_BOOLEAN, init :+ TypeOp(CHECKCAST, "[Z")))
55+
}
3556

36-
@Test def testArrayApplyByte =
37-
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))))
57+
@Test def testArrayApplyByte = {
58+
val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(BASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(BASTORE))
59+
test("Array[Byte](1, 2)", newArray2Opcodes(T_BYTE, init))
60+
test("IArray[Byte](1, 2)", newArray2Opcodes(T_BYTE, init :+ TypeOp(CHECKCAST, "[B")))
61+
}
3862

39-
@Test def testArrayApplyShort =
40-
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 def testArrayApplyShort = {
64+
val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(SASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(SASTORE))
65+
test("Array[Short](1, 2)", newArray2Opcodes(T_SHORT, init))
66+
test("IArray[Short](1, 2)", newArray2Opcodes(T_SHORT, init :+ TypeOp(CHECKCAST, "[S")))
67+
}
4168

4269
@Test def testArrayApplyInt = {
43-
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))))
44-
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))))
70+
val init = List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE))
71+
test("Array(1, 2)", newArray2Opcodes(T_INT, init))
72+
test("IArray(1, 2)", newArray2Opcodes(T_INT, init :+ TypeOp(CHECKCAST, "[I")))
73+
74+
val init2 = 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))
75+
test("""Array[T](t, t)""", newArray2Opcodes(T_INT, init2))
76+
test("""IArray[T](t, t)""", newArray2Opcodes(T_INT, init2 :+ TypeOp(CHECKCAST, "[I")))
4577
}
4678

47-
@Test def testArrayApplyLong =
48-
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))))
79+
@Test def testArrayApplyLong = {
80+
val init = List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2), Op(LASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3), Op(LASTORE))
81+
test("Array(2L, 3L)", newArray2Opcodes(T_LONG, init))
82+
test("IArray(2L, 3L)", newArray2Opcodes(T_LONG, init :+ TypeOp(CHECKCAST, "[J")))
83+
}
4984

50-
@Test def testArrayApplyFloat =
51-
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))))
85+
@Test def testArrayApplyFloat = {
86+
val init = List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2.1f), Op(FASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3.1f), Op(FASTORE))
87+
test("Array(2.1f, 3.1f)", newArray2Opcodes(T_FLOAT, init))
88+
test("IArray(2.1f, 3.1f)", newArray2Opcodes(T_FLOAT, init :+ TypeOp(CHECKCAST, "[F")))
89+
}
5290

53-
@Test def testArrayApplyDouble =
54-
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))))
91+
@Test def testArrayApplyDouble = {
92+
val init = List(Op(DUP), Op(ICONST_0), Ldc(LDC, 2.2d), Op(DASTORE), Op(DUP), Op(ICONST_1), Ldc(LDC, 3.2d), Op(DASTORE))
93+
test("Array(2.2d, 3.2d)", newArray2Opcodes(T_DOUBLE, init))
94+
test("IArray(2.2d, 3.2d)", newArray2Opcodes(T_DOUBLE, init :+ TypeOp(CHECKCAST, "[D")))
95+
}
5596

56-
@Test def testArrayApplyChar =
57-
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))))
97+
@Test def testArrayApplyChar = {
98+
val init = List(Op(DUP), Op(ICONST_0), IntOp(BIPUSH, 120), Op(CASTORE), Op(DUP), Op(ICONST_1), IntOp(BIPUSH, 121), Op(CASTORE))
99+
test("Array('x', 'y')", newArray2Opcodes(T_CHAR, init))
100+
test("IArray('x', 'y')", newArray2Opcodes(T_CHAR, init :+ TypeOp(CHECKCAST, "[C")))
101+
}
58102

59-
@Test def testArrayApplyUnit =
103+
@Test def testArrayApplyUnit = {
60104
test("Array[Unit]((), ())", List(Op(ICONST_2), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(DUP),
61105
Op(ICONST_0), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(DUP),
62106
Op(ICONST_1), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(POP), Op(RETURN)))
107+
test("IArray[Unit]((), ())", List(Op(ICONST_2), TypeOp(ANEWARRAY, "scala/runtime/BoxedUnit"), Op(DUP),
108+
Op(ICONST_0), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), Op(DUP),
109+
Op(ICONST_1), Field(GETSTATIC, "scala/runtime/BoxedUnit", "UNIT", "Lscala/runtime/BoxedUnit;"), Op(AASTORE), TypeOp(CHECKCAST, "[Lscala/runtime/BoxedUnit;"), Op(POP), Op(RETURN)))
110+
}
63111

64112
@Test def testArrayInlined = test(
65113
"""{
@@ -77,6 +125,14 @@ class ArrayApplyOptTest extends DottyBytecodeTest {
77125
newArray2Opcodes(T_INT, List(Op(DUP), Op(ICONST_0), Op(ICONST_1), Op(IASTORE), Op(DUP), Op(ICONST_1), Op(ICONST_2), Op(IASTORE)))
78126
)
79127

128+
@Test def testArrayInlined3 = test(
129+
"""{
130+
| inline def array[T](xs: =>T*) given (ct: =>scala.reflect.ClassTag[T]): Array[T] = Array(xs: _*)
131+
| array(1, 2)
132+
|}""".stripMargin,
133+
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")))
134+
)
135+
80136
private def newArray0Opcodes(tpe: Int, init: List[Any] = Nil): List[Any] =
81137
Op(ICONST_0) :: IntOp(NEWARRAY, tpe) :: init ::: Op(POP) :: Op(RETURN) :: Nil
82138

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
*

0 commit comments

Comments
 (0)