[JVM] Introduce StringRef type for captured string variables
Previously captured string variables were represented as
`ObjectRef<String>`. After the 'captured vars optimization', these
variables were assigned the type `Object`, which could lead to confusion
when debugging an application as the effective type of such variable is
`String`. This commit adds a new `Ref` type for captured
strings - `StringRef`. This makes it possible to put these variables as
`String`s in LVT after the 'captured vars optimization'.
^KT-70527 fixed
diff --git a/compiler/backend.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java b/compiler/backend.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java
index b88b646..4c6cbf5 100644
--- a/compiler/backend.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java
+++ b/compiler/backend.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java
@@ -70,6 +70,7 @@
private static final String REF_TYPE_PREFIX = "kotlin/jvm/internal/Ref$";
public static final Type OBJECT_REF_TYPE = Type.getObjectType(REF_TYPE_PREFIX + "ObjectRef");
+ public static final Type STRING_REF_TYPE = Type.getObjectType(REF_TYPE_PREFIX + "StringRef");
public static final Type ENUM_ENTRIES = Type.getObjectType("kotlin/enums/EnumEntries");
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/CapturedVarsOptimizationMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/CapturedVarsOptimizationMethodTransformer.kt
index 773204d..d91fd4a 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/CapturedVarsOptimizationMethodTransformer.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/CapturedVarsOptimizationMethodTransformer.kt
@@ -227,6 +227,7 @@
internal val REF_TYPE_TO_ELEMENT_TYPE = HashMap<String, Type>().apply {
put(AsmTypes.OBJECT_REF_TYPE.internalName, AsmTypes.OBJECT_TYPE)
+ put(AsmTypes.STRING_REF_TYPE.internalName, AsmTypes.JAVA_STRING_TYPE)
PrimitiveType.entries.forEach {
put(AsmTypes.sharedTypeForPrimitive(it).internalName, AsmTypes.valueTypeForPrimitive(it))
}
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt
index 3768c8b..18a3e77 100644
--- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SharedVariablesLowering.kt
@@ -45,7 +45,7 @@
*
* becomes
*
- * var x = ObjectRef<String>()
+ * var x = StringRef()
* x.element = "a"
* run {
* x.element = "b"
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSharedVariablesManager.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSharedVariablesManager.kt
index 56cbfcd..73c35cb 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSharedVariablesManager.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSharedVariablesManager.kt
@@ -61,7 +61,17 @@
primitiveType.classifierOrFail to RefProvider(refClass, primitiveType)
}
- private val objectRefProvider = run {
+ private val stringRefProvider = run {
+ val refClass = irFactory.addClass(refNamespaceClass) {
+ origin = IrDeclarationOrigin.IR_BUILTINS_STUB
+ name = Name.identifier("StringRef")
+ }.apply {
+ createThisReceiverParameter()
+ }
+ RefProvider(refClass, irBuiltIns.stringType)
+ }
+
+ val objectRefProvider = run {
val refClass = irFactory.addClass(refNamespaceClass) {
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
name = Name.identifier("ObjectRef")
@@ -76,10 +86,11 @@
}
fun getProvider(valueType: IrType): RefProvider =
- if (valueType.isPrimitiveType())
- primitiveRefProviders.getValue(valueType.classifierOrFail)
- else
- objectRefProvider
+ when {
+ valueType.isPrimitiveType() -> primitiveRefProviders.getValue(valueType.classifierOrFail)
+ valueType.isString() -> stringRefProvider
+ else -> objectRefProvider
+ }
override fun declareSharedVariable(originalDeclaration: IrVariable): IrVariable {
val valueType = originalDeclaration.type
diff --git a/compiler/testData/codegen/box/coroutines/bridges/lambdaWithLongReceiver.ir.txt b/compiler/testData/codegen/box/coroutines/bridges/lambdaWithLongReceiver.ir.txt
index 58fd007..452bde5 100644
--- a/compiler/testData/codegen/box/coroutines/bridges/lambdaWithLongReceiver.ir.txt
+++ b/compiler/testData/codegen/box/coroutines/bridges/lambdaWithLongReceiver.ir.txt
@@ -19,17 +19,17 @@
final class LambdaWithLongReceiverKt$box$1 {
// source: 'lambdaWithLongReceiver.kt'
enclosing method LambdaWithLongReceiverKt.box()Ljava/lang/String;
- synthetic final field $res: kotlin.jvm.internal.Ref$ObjectRef
+ synthetic final field $res: kotlin.jvm.internal.Ref$StringRef
field L$0: java.lang.Object
field label: int
inner (anonymous) class LambdaWithLongReceiverKt$box$1
inner (anonymous) class LambdaWithLongReceiverKt$box$1$1
- method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.coroutines.Continuation): void
+ method <init>(p0: kotlin.jvm.internal.Ref$StringRef, p1: kotlin.coroutines.Continuation): void
public final method create(p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation
public synthetic bridge method invoke(p0: java.lang.Object): java.lang.Object
public final method invoke(p0: kotlin.coroutines.Continuation): java.lang.Object
public final method invokeSuspend(p0: java.lang.Object): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
@kotlin.Metadata
@@ -39,5 +39,5 @@
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
public final static @org.jetbrains.annotations.Nullable method call(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
diff --git a/compiler/testData/codegen/box/coroutines/bridges/lambdaWithMultipleParameters.ir.txt b/compiler/testData/codegen/box/coroutines/bridges/lambdaWithMultipleParameters.ir.txt
index 8e0c96a..770da94 100644
--- a/compiler/testData/codegen/box/coroutines/bridges/lambdaWithMultipleParameters.ir.txt
+++ b/compiler/testData/codegen/box/coroutines/bridges/lambdaWithMultipleParameters.ir.txt
@@ -23,17 +23,17 @@
final class LambdaWithMultipleParametersKt$box$1 {
// source: 'lambdaWithMultipleParameters.kt'
enclosing method LambdaWithMultipleParametersKt.box()Ljava/lang/String;
- synthetic final field $res: kotlin.jvm.internal.Ref$ObjectRef
+ synthetic final field $res: kotlin.jvm.internal.Ref$StringRef
field L$0: java.lang.Object
field label: int
inner (anonymous) class LambdaWithMultipleParametersKt$box$1
inner (anonymous) class LambdaWithMultipleParametersKt$box$1$1
- method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.coroutines.Continuation): void
+ method <init>(p0: kotlin.jvm.internal.Ref$StringRef, p1: kotlin.coroutines.Continuation): void
public final method create(p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation
public synthetic bridge method invoke(p0: java.lang.Object): java.lang.Object
public final method invoke(p0: kotlin.coroutines.Continuation): java.lang.Object
public final method invokeSuspend(p0: java.lang.Object): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
@kotlin.Metadata
@@ -43,5 +43,5 @@
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
public final static @org.jetbrains.annotations.Nullable method call(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function7, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
diff --git a/compiler/testData/codegen/box/coroutines/suspendConversion/onInlineArgument.fir.txt b/compiler/testData/codegen/box/coroutines/suspendConversion/onInlineArgument.fir.txt
index ed47ac6..8f32698 100644
--- a/compiler/testData/codegen/box/coroutines/suspendConversion/onInlineArgument.fir.txt
+++ b/compiler/testData/codegen/box/coroutines/suspendConversion/onInlineArgument.fir.txt
@@ -4,15 +4,15 @@
// source: 'onInlineArgument.kt'
enclosing method OnInlineArgumentKt.box()Ljava/lang/String;
synthetic final field $lambda: kotlin.jvm.functions.Function1
- synthetic final field $test: kotlin.jvm.internal.Ref$ObjectRef
+ synthetic final field $test: kotlin.jvm.internal.Ref$StringRef
field label: int
inner (anonymous) class OnInlineArgumentKt$box$1
- method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function1, p2: kotlin.coroutines.Continuation): void
+ method <init>(p0: kotlin.jvm.internal.Ref$StringRef, p1: kotlin.jvm.functions.Function1, p2: kotlin.coroutines.Continuation): void
public final method create(p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation
public synthetic bridge method invoke(p0: java.lang.Object): java.lang.Object
public final method invoke(p0: kotlin.coroutines.Continuation): java.lang.Object
public final method invokeSuspend(p0: java.lang.Object): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
@kotlin.Metadata
@@ -23,5 +23,5 @@
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
private final static method runS$$forInline(p0: kotlin.jvm.functions.Function2, p1: kotlin.coroutines.Continuation): java.lang.Object
public final static @org.jetbrains.annotations.Nullable method runS(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine.ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine.ir.txt
index 6d91d55..b2f8feb 100644
--- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine.ir.txt
+++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine.ir.txt
@@ -3,17 +3,17 @@
final class InlineWithoutStateMachineKt$box$1 {
// source: 'inlineWithoutStateMachine.kt'
enclosing method InlineWithoutStateMachineKt.box()Ljava/lang/String;
- synthetic final field $result: kotlin.jvm.internal.Ref$ObjectRef
+ synthetic final field $result: kotlin.jvm.internal.Ref$StringRef
field L$0: java.lang.Object
field L$1: java.lang.Object
field label: int
inner (anonymous) class InlineWithoutStateMachineKt$box$1
- method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.coroutines.Continuation): void
+ method <init>(p0: kotlin.jvm.internal.Ref$StringRef, p1: kotlin.coroutines.Continuation): void
public final method create(p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation
public synthetic bridge method invoke(p0: java.lang.Object): java.lang.Object
public final method invoke(p0: kotlin.coroutines.Continuation): java.lang.Object
public final method invokeSuspend(p0: java.lang.Object): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
@kotlin.Metadata
@@ -26,5 +26,5 @@
public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object
private final static method suspendThere$$forInline(p0: java.lang.String, p1: kotlin.coroutines.Continuation): java.lang.Object
public final static @org.jetbrains.annotations.Nullable method suspendThere(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
diff --git a/compiler/testData/codegen/box/jvm8/defaults/enable/privateFunWithDefaultArg.ir.txt b/compiler/testData/codegen/box/jvm8/defaults/enable/privateFunWithDefaultArg.ir.txt
index 0a3dc43..22b1a1b 100644
--- a/compiler/testData/codegen/box/jvm8/defaults/enable/privateFunWithDefaultArg.ir.txt
+++ b/compiler/testData/codegen/box/jvm8/defaults/enable/privateFunWithDefaultArg.ir.txt
@@ -10,17 +10,17 @@
final class Foo$bar$1 {
// source: 'privateFunWithDefaultArg.kt'
enclosing method Foo.bar()Ljava/lang/String;
- synthetic final field $result: kotlin.jvm.internal.Ref$ObjectRef
+ synthetic final field $result: kotlin.jvm.internal.Ref$StringRef
field L$0: java.lang.Object
field label: int
synthetic final field this$0: Foo
inner (anonymous) class Foo$bar$1
- method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: Foo, p2: kotlin.coroutines.Continuation): void
+ method <init>(p0: kotlin.jvm.internal.Ref$StringRef, p1: Foo, p2: kotlin.coroutines.Continuation): void
public final method create(p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation
public synthetic bridge method invoke(p0: java.lang.Object): java.lang.Object
public final method invoke(p0: kotlin.coroutines.Continuation): java.lang.Object
public final method invokeSuspend(p0: java.lang.Object): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
@kotlin.Metadata
@@ -35,7 +35,7 @@
public synthetic static method fooSuspend$default(p0: Foo, p1: java.lang.String, p2: kotlin.coroutines.Continuation, p3: int, p4: java.lang.Object): java.lang.Object
private method fooSuspend(p0: java.lang.String, p1: kotlin.coroutines.Continuation): java.lang.Object
public final inner class Foo$DefaultImpls
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
@kotlin.Metadata
diff --git a/compiler/testData/codegen/box/jvm8/defaults/noCompatibility/privateFunWithDefaultArg.ir.txt b/compiler/testData/codegen/box/jvm8/defaults/noCompatibility/privateFunWithDefaultArg.ir.txt
index e883fca..c23f889 100644
--- a/compiler/testData/codegen/box/jvm8/defaults/noCompatibility/privateFunWithDefaultArg.ir.txt
+++ b/compiler/testData/codegen/box/jvm8/defaults/noCompatibility/privateFunWithDefaultArg.ir.txt
@@ -3,17 +3,17 @@
final class Foo$bar$1 {
// source: 'privateFunWithDefaultArg.kt'
enclosing method Foo.bar()Ljava/lang/String;
- synthetic final field $result: kotlin.jvm.internal.Ref$ObjectRef
+ synthetic final field $result: kotlin.jvm.internal.Ref$StringRef
field L$0: java.lang.Object
field label: int
synthetic final field this$0: Foo
inner (anonymous) class Foo$bar$1
- method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: Foo, p2: kotlin.coroutines.Continuation): void
+ method <init>(p0: kotlin.jvm.internal.Ref$StringRef, p1: Foo, p2: kotlin.coroutines.Continuation): void
public final method create(p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation
public synthetic bridge method invoke(p0: java.lang.Object): java.lang.Object
public final method invoke(p0: kotlin.coroutines.Continuation): java.lang.Object
public final method invokeSuspend(p0: java.lang.Object): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
@kotlin.Metadata
@@ -26,7 +26,7 @@
private method foo(p0: java.lang.String): java.lang.String
public synthetic static method fooSuspend$default(p0: Foo, p1: java.lang.String, p2: kotlin.coroutines.Continuation, p3: int, p4: java.lang.Object): java.lang.Object
private method fooSuspend(p0: java.lang.String, p1: kotlin.coroutines.Continuation): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
@kotlin.Metadata
diff --git a/compiler/testData/codegen/box/jvm8/defaults/noCompatibility/withCompatibility/suspend.txt b/compiler/testData/codegen/box/jvm8/defaults/noCompatibility/withCompatibility/suspend.txt
index 29091a9..41fcd35 100644
--- a/compiler/testData/codegen/box/jvm8/defaults/noCompatibility/withCompatibility/suspend.txt
+++ b/compiler/testData/codegen/box/jvm8/defaults/noCompatibility/withCompatibility/suspend.txt
@@ -3,17 +3,17 @@
final class SuspendKt$box$1 {
// source: 'suspend.kt'
enclosing method SuspendKt.box()Ljava/lang/String;
- synthetic final field $result: kotlin.jvm.internal.Ref$ObjectRef
+ synthetic final field $result: kotlin.jvm.internal.Ref$StringRef
field L$0: java.lang.Object
field L$1: java.lang.Object
field label: int
inner (anonymous) class SuspendKt$box$1
- method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.coroutines.Continuation): void
+ method <init>(p0: kotlin.jvm.internal.Ref$StringRef, p1: kotlin.coroutines.Continuation): void
public final method create(p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation
public synthetic bridge method invoke(p0: java.lang.Object): java.lang.Object
public final method invoke(p0: kotlin.coroutines.Continuation): java.lang.Object
public final method invokeSuspend(p0: java.lang.Object): java.lang.Object
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
@kotlin.Metadata
@@ -22,7 +22,7 @@
inner (anonymous) class SuspendKt$box$1
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
- public final inner class kotlin/jvm/internal/Ref$ObjectRef
+ public final inner class kotlin/jvm/internal/Ref$StringRef
}
@kotlin.Metadata
diff --git a/compiler/testData/codegen/bytecodeText/capturedVarsOptimization/capturedValInLambdaInitializedInside.kt b/compiler/testData/codegen/bytecodeText/capturedVarsOptimization/capturedValInLambdaInitializedInside.kt
index efee7b8..2e62ce8 100644
--- a/compiler/testData/codegen/bytecodeText/capturedVarsOptimization/capturedValInLambdaInitializedInside.kt
+++ b/compiler/testData/codegen/bytecodeText/capturedVarsOptimization/capturedValInLambdaInitializedInside.kt
@@ -2,12 +2,17 @@
fun box(): String {
val x: String
+ val y: Any
run {
x = "OK"
- val y = x
+ y = Any()
+ val a = x
+ val b = y
}
return x
}
// 2 ObjectRef
// 1 INNERCLASS kotlin.jvm.internal.Ref\$ObjectRef kotlin.jvm.internal.Ref ObjectRef
+// 1 LOCALVARIABLE x Ljava/lang/String;
+// 1 INNERCLASS kotlin.jvm.internal.Ref\$StringRef kotlin.jvm.internal.Ref StringRef
diff --git a/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt b/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt
index d1783ba..8f536d4 100644
--- a/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt
+++ b/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt
@@ -51,7 +51,7 @@
/* 1 load in the catch (e: Throwable) { throw e } block which is implicitly wrapped around try/finally */
// 1 ALOAD 3\s+ATHROW
/* 1 load in result = s */
-// 1 ALOAD 3\s+PUTFIELD kotlin/jvm/internal/Ref\$ObjectRef\.element
+// 1 ALOAD 3\s+PUTFIELD kotlin/jvm/internal/Ref\$StringRef\.element
/* 1 load in spill */
// 1 ALOAD 3\s+PUTFIELD VarValueConflictsWithTableSameSortKt\$box\$1\.L\$1 : Ljava/lang/Object;
/* 2 loads in println(s) */
diff --git a/compiler/testData/codegen/bytecodeText/kt10259.kt b/compiler/testData/codegen/bytecodeText/kt10259.kt
index 6947f70..2ace841 100644
--- a/compiler/testData/codegen/bytecodeText/kt10259.kt
+++ b/compiler/testData/codegen/bytecodeText/kt10259.kt
@@ -26,4 +26,4 @@
// 8 INNERCLASS
// 3 INNERCLASS Kt10259Kt\$box\$1\$lam1\$1 null null
// 2 INNERCLASS Kt10259Kt\$box\$1\$lam1\$1\$lam2\$1
-// 3 INNERCLASS kotlin.jvm.internal.Ref\$ObjectRef kotlin.jvm.internal.Ref ObjectRef
+// 3 INNERCLASS kotlin.jvm.internal.Ref\$StringRef kotlin.jvm.internal.Ref StringRef
diff --git a/compiler/testData/codegen/bytecodeText/kt10259_2.kt b/compiler/testData/codegen/bytecodeText/kt10259_2.kt
index 13e96b1..3a48ded 100644
--- a/compiler/testData/codegen/bytecodeText/kt10259_2.kt
+++ b/compiler/testData/codegen/bytecodeText/kt10259_2.kt
@@ -19,5 +19,5 @@
// 2 INNERCLASS Kt10259_2Kt\$test\$1\$1
// 2 INNERCLASS Kt10259_2Kt\$box\$\$inlined\$test\$1\s
// 2 INNERCLASS Kt10259_2Kt\$box\$\$inlined\$test\$1\$1
-// 1 INNERCLASS kotlin.jvm.internal.Ref\$ObjectRef kotlin.jvm.internal.Ref ObjectRef
+// 1 INNERCLASS kotlin.jvm.internal.Ref\$StringRef kotlin.jvm.internal.Ref StringRef
// 10 INNERCLASS
diff --git a/compiler/testData/codegen/bytecodeText/kt10259_3.kt b/compiler/testData/codegen/bytecodeText/kt10259_3.kt
index 4bd702d..8c38293 100644
--- a/compiler/testData/codegen/bytecodeText/kt10259_3.kt
+++ b/compiler/testData/codegen/bytecodeText/kt10259_3.kt
@@ -36,4 +36,4 @@
// 2 INNERCLASS Kt10259_3Kt\$box\$\$inlined\$test\$1\$1 null null
// 3 INNERCLASS Kt10259_3Kt\$test\$1 null null
// 2 INNERCLASS Kt10259_3Kt\$test\$1\$1 null null
-// 3 INNERCLASS kotlin.jvm.internal.Ref\$ObjectRef kotlin.jvm.internal.Ref ObjectRef
+// 3 INNERCLASS kotlin.jvm.internal.Ref\$StringRef kotlin.jvm.internal.Ref StringRef
diff --git a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Ref.java b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Ref.java
index 4765b02..7058c08 100644
--- a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Ref.java
+++ b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Ref.java
@@ -19,6 +19,15 @@
}
}
+ public static final class StringRef implements Serializable {
+ public String element;
+
+ @Override
+ public String toString() {
+ return element;
+ }
+ }
+
public static final class ByteRef implements Serializable {
public byte element;