Add runtime string concat options. Some renaming

This commit is contained in:
Mikhael Bogdanov
2020-09-29 08:47:06 +02:00
parent 04012951c1
commit c329c22630
20 changed files with 97 additions and 24 deletions
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.codegen;
import com.google.common.collect.Sets;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.ArrayUtil;
@@ -52,7 +51,6 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
@@ -495,12 +493,12 @@ public class DescriptorAsmUtil {
return index;
}
public static void genInvokeAppendMethod(@NotNull StringAppendGenerator generator, @NotNull Type type, @Nullable KotlinType kotlinType) {
public static void genInvokeAppendMethod(@NotNull StringConcatGenerator generator, @NotNull Type type, @Nullable KotlinType kotlinType) {
genInvokeAppendMethod(generator, type, kotlinType, null);
}
public static void genInvokeAppendMethod(
@NotNull StringAppendGenerator generator,
@NotNull StringConcatGenerator generator,
@NotNull Type type,
@Nullable KotlinType kotlinType,
@Nullable KotlinTypeMapper typeMapper
@@ -925,7 +925,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
else {
return StackValue.operation(type, v -> {
StringAppendGenerator generator = StringAppendGenerator.Companion.create(state, v);
StringConcatGenerator generator = StringConcatGenerator.Companion.create(state, v);
generator.genStringBuilderConstructorIfNeded();
invokeAppendForEntries(generator, entries);
generator.genToString();
@@ -934,7 +934,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
private void invokeAppendForEntries(StringAppendGenerator generator, List<StringTemplateEntry> entries) {
private void invokeAppendForEntries(StringConcatGenerator generator, List<StringTemplateEntry> entries) {
for (StringTemplateEntry entry : entries) {
if (entry instanceof StringTemplateEntry.Expression) {
invokeAppend(generator, ((StringTemplateEntry.Expression) entry).expression);
@@ -4300,7 +4300,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
public void invokeAppend(StringAppendGenerator generator, KtExpression expr) {
public void invokeAppend(StringConcatGenerator generator, KtExpression expr) {
expr = KtPsiUtil.safeDeparenthesize(expr);
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr);
@@ -102,7 +102,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
mv.visitCode();
StringAppendGenerator generator = StringAppendGenerator.Companion.create(generationState, iv);
StringConcatGenerator generator = StringConcatGenerator.Companion.create(generationState, iv);
generator.genStringBuilderConstructorIfNeded();
boolean first = true;
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.codegen
import com.google.common.collect.Sets
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.JvmRuntimeStringConcat
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
import org.jetbrains.org.objectweb.asm.Handle
@@ -16,14 +16,14 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import java.lang.StringBuilder
class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAdapter) {
class StringConcatGenerator(val mode: JvmRuntimeStringConcat, val mv: InstructionAdapter) {
private val template = StringBuilder("")
private val paramTypes = arrayListOf<Type>()
@JvmOverloads
fun genStringBuilderConstructorIfNeded(swap: Boolean = false) {
if (useInvokeDynamic) return
if (mode.isDynamic) return
mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder")
mv.dup()
mv.invokespecial("java/lang/StringBuilder", "<init>", "()V", false)
@@ -33,7 +33,7 @@ class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAd
}
fun addCharConstant(value: Char) {
if (!useInvokeDynamic) {
if (!mode.isDynamic) {
mv.iconst(value.toInt())
invokeAppend(Type.CHAR_TYPE)
} else {
@@ -42,7 +42,7 @@ class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAd
}
fun addStringConstant(value: String) {
if (!useInvokeDynamic) {
if (!mode.isDynamic) {
mv.aconst(value)
invokeAppend(JAVA_STRING_TYPE)
} else {
@@ -51,7 +51,7 @@ class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAd
}
fun invokeAppend(type: Type) {
if (!useInvokeDynamic) {
if (!mode.isDynamic) {
mv.invokevirtual(
"java/lang/StringBuilder",
"append",
@@ -71,7 +71,7 @@ class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAd
}
fun genToString() {
if (!useInvokeDynamic) {
if (!mode.isDynamic) {
mv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
} else {
//if state was flushed in `invokeAppend` do nothing
@@ -114,7 +114,7 @@ class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAd
}
fun create(state: GenerationState, mv: InstructionAdapter) =
StringAppendGenerator(/*TODO: add flag*/state.target.bytecodeVersion >= JvmTarget.JVM_9.bytecodeVersion, mv)
StringConcatGenerator(state.runtimeStringConcat, mv)
}
}
@@ -39,7 +39,7 @@ class Concat : IntrinsicMethod() {
arguments: List<KtExpression>,
receiver: StackValue
): Type {
val generator = StringAppendGenerator.create(codegen.state, v)
val generator = StringConcatGenerator.create(codegen.state, v)
if (element is KtBinaryExpression && element.operationReference.getReferencedNameElementType() == KtTokens.PLUS) {
// LHS + RHS
generator.genStringBuilderConstructorIfNeded()
@@ -59,7 +59,7 @@ class Concat : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable =
object : IntrinsicCallable(method) {
lateinit var generator: StringAppendGenerator
lateinit var generator: StringConcatGenerator
override fun invokeMethodWithArguments(
resolvedCall: ResolvedCall<*>,
receiver: StackValue,
@@ -83,8 +83,8 @@ class Concat : IntrinsicMethod() {
}
override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap, state: GenerationState) {
generator = StringAppendGenerator.create(state, v)
if (!generator.useInvokeDynamic) {
generator = StringConcatGenerator.create(state, v)
if (!generator.mode.isDynamic) {
v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, JAVA_STRING_TYPE, "java/lang/StringBuilder")
v.invokespecial("java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false)
} else {
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.codegen.intrinsics
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
@@ -25,19 +24,19 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
class StringPlus : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable =
object : IntrinsicCallable(method) {
private lateinit var generator: StringAppendGenerator
private lateinit var generator: StringConcatGenerator
override fun invokeMethodWithArguments(
resolvedCall: ResolvedCall<*>,
receiver: StackValue,
codegen: ExpressionCodegen
): StackValue {
generator = StringAppendGenerator.create(codegen.state, codegen.v)
generator = StringConcatGenerator.create(codegen.state, codegen.v)
return super.invokeMethodWithArguments(resolvedCall, receiver, codegen)
}
override fun genInvokeInstruction(v: InstructionAdapter) {
if (!generator.useInvokeDynamic) {
if (!generator.mode.isDynamic) {
v.invokestatic(
IntrinsicMethods.INTRINSICS_CLASS_NAME, "stringPlus",
"(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false
@@ -191,6 +191,10 @@ class GenerationState private constructor(
val languageVersionSettings = configuration.languageVersionSettings
val target = configuration.get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT
val runtimeStringConcat =
if (target.bytecodeVersion >= JvmTarget.JVM_9.bytecodeVersion)
configuration.get(JVMConfigurationKeys.RUNTIME_STRING_CONCAT) ?: JvmRuntimeStringConcat.DISABLE
else JvmRuntimeStringConcat.DISABLE
val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
val classBuilderMode: ClassBuilderMode = builderFactory.classBuilderMode