diff options
author | Simon Ochsenreither <simon@ochsenreither.de> | 2015-09-02 19:01:37 +0200 |
---|---|---|
committer | Simon Ochsenreither <simon@ochsenreither.de> | 2016-02-03 10:42:21 +0100 |
commit | cd0211cf0fb755281c7607bf6a172df306b5686f (patch) | |
tree | f0c049a38ae9f16d192edff6887e0d428ab13b74 /src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala | |
parent | bbd890bf907c00f17df39eb4bc656b30d4317b9a (diff) | |
download | scala-cd0211cf0fb755281c7607bf6a172df306b5686f.tar.gz scala-cd0211cf0fb755281c7607bf6a172df306b5686f.tar.bz2 scala-cd0211cf0fb755281c7607bf6a172df306b5686f.zip |
SI-9315 Desugar string concat to java.lang.StringBuilder ...
... instead of scala.collection.mutable.StringBuilder to benefit from
JVM optimizations. Unfortunately primitives are already boxed in erasure
when they end up in this part of the backend.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala index 4a10756468..328a8187c8 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala @@ -40,7 +40,7 @@ abstract class BCodeIdiomatic extends SubComponent { if (emitStackMapFrame) asm.ClassWriter.COMPUTE_FRAMES else 0 ) - val StringBuilderClassName = "scala/collection/mutable/StringBuilder" + lazy val JavaStringBuilderClassName = jlStringBuilderRef.internalName val EMPTY_STRING_ARRAY = Array.empty[String] val EMPTY_INT_ARRAY = Array.empty[Int] @@ -184,10 +184,10 @@ abstract class BCodeIdiomatic extends SubComponent { * can-multi-thread */ final def genStartConcat(pos: Position): Unit = { - jmethod.visitTypeInsn(Opcodes.NEW, StringBuilderClassName) + jmethod.visitTypeInsn(Opcodes.NEW, JavaStringBuilderClassName) jmethod.visitInsn(Opcodes.DUP) invokespecial( - StringBuilderClassName, + JavaStringBuilderClassName, INSTANCE_CONSTRUCTOR_NAME, "()V", pos @@ -198,21 +198,23 @@ abstract class BCodeIdiomatic extends SubComponent { * can-multi-thread */ final def genStringConcat(el: BType, pos: Position): Unit = { - - val jtype = - if (el.isArray || el.isClass) ObjectRef - else el + val jtype = el match { + case ct: ClassBType if ct.isSubtypeOf(StringRef).get => StringRef + case ct: ClassBType if ct.isSubtypeOf(jlStringBufferRef).get => jlStringBufferRef + case ct: ClassBType if ct.isSubtypeOf(jlCharSequenceRef).get => jlCharSequenceRef + case rt: RefBType => ObjectRef + case pt: PrimitiveBType => pt // Currently this ends up being boxed in erasure + } val bt = MethodBType(List(jtype), jlStringBuilderRef) - - invokevirtual(StringBuilderClassName, "append", bt.descriptor, pos) + invokevirtual(JavaStringBuilderClassName, "append", bt.descriptor, pos) } /* * can-multi-thread */ final def genEndConcat(pos: Position): Unit = { - invokevirtual(StringBuilderClassName, "toString", "()Ljava/lang/String;", pos) + invokevirtual(JavaStringBuilderClassName, "toString", "()Ljava/lang/String;", pos) } /* |