[Utils] Reoptimize equals of names based on interning of strings
diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/JvmClassName.java b/core/compiler.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/JvmClassName.java
index f5bdb7c..359e7f4 100644
--- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/JvmClassName.java
+++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/resolve/jvm/JvmClassName.java
@@ -19,7 +19,6 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.kotlin.name.ClassId;
 import org.jetbrains.kotlin.name.FqName;
-import org.jetbrains.kotlin.utils.StringInterner;
 
 public class JvmClassName {
     @NotNull
@@ -58,7 +57,7 @@
     private FqName fqName;
 
     private JvmClassName(@NotNull String internalName) {
-        this.internalName = StringInterner.interned(internalName);
+        this.internalName = internalName;
     }
 
     /**
@@ -111,7 +110,7 @@
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
-        return internalName == ((JvmClassName) o).internalName; // strings are interned
+        return internalName.equals(((JvmClassName) o).internalName);
     }
 
     @Override
diff --git a/core/compiler.common/src/org/jetbrains/kotlin/name/FqNameUnsafe.java b/core/compiler.common/src/org/jetbrains/kotlin/name/FqNameUnsafe.java
index 35c1311..4833d70 100644
--- a/core/compiler.common/src/org/jetbrains/kotlin/name/FqNameUnsafe.java
+++ b/core/compiler.common/src/org/jetbrains/kotlin/name/FqNameUnsafe.java
@@ -20,7 +20,6 @@
 import kotlin.jvm.functions.Function1;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
-import org.jetbrains.kotlin.utils.StringInterner;
 
 import java.util.Collections;
 import java.util.List;
@@ -49,16 +48,16 @@
     private transient Name shortName;
 
     FqNameUnsafe(@NotNull String fqName, @NotNull FqName safe) {
-        this.fqName = StringInterner.interned(fqName);
+        this.fqName = fqName;
         this.safe = safe;
     }
 
     public FqNameUnsafe(@NotNull String fqName) {
-        this.fqName = StringInterner.interned(fqName);
+        this.fqName = fqName;
     }
 
     private FqNameUnsafe(@NotNull String fqName, FqNameUnsafe parent, Name shortName) {
-        this.fqName = StringInterner.interned(fqName);
+        this.fqName = fqName;
         this.parent = parent;
         this.shortName = shortName;
     }
@@ -197,7 +196,7 @@
 
         FqNameUnsafe that = (FqNameUnsafe) o;
 
-        if (fqName != that.fqName) return false; // strings are interned
+        if (!fqName.equals(that.fqName)) return false;
 
         return true;
     }
diff --git a/core/compiler.common/src/org/jetbrains/kotlin/name/Name.java b/core/compiler.common/src/org/jetbrains/kotlin/name/Name.java
index 859627b..1423ec2 100644
--- a/core/compiler.common/src/org/jetbrains/kotlin/name/Name.java
+++ b/core/compiler.common/src/org/jetbrains/kotlin/name/Name.java
@@ -18,7 +18,6 @@
 
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
-import org.jetbrains.kotlin.utils.StringInterner;
 
 public final class Name implements Comparable<Name> {
     @NotNull
@@ -26,7 +25,7 @@
     private final boolean special;
 
     private Name(@NotNull String name, boolean special) {
-        this.name = StringInterner.interned(name);
+        this.name = name;
         this.special = special;
     }
 
@@ -117,7 +116,7 @@
         Name name1 = (Name) o;
 
         if (special != name1.special) return false;
-        if (name != name1.name) return false; // strings are interned
+        if (!name.equals(name1.name)) return false;
 
         return true;
     }
diff --git a/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/MemberSignature.kt b/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/MemberSignature.kt
index 056f2a7..2db9630 100644
--- a/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/MemberSignature.kt
+++ b/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/MemberSignature.kt
@@ -8,11 +8,14 @@
 import org.jetbrains.kotlin.metadata.deserialization.NameResolver
 import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
 import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMemberSignature
+import org.jetbrains.kotlin.utils.UniqueString
+import org.jetbrains.kotlin.utils.UniqueString.Companion.uniqueString
 
 // The purpose of this class is to hold a unique signature of either a method or a field, so that annotations on a member can be put
 // into a map indexed by these signatures
 @Suppress("DataClassPrivateConstructor")
-data class MemberSignature private constructor(val signature: String) {
+data class MemberSignature private constructor(private val signatureImpl: UniqueString) {
+    val signature get() = signatureImpl.value
     companion object {
         @JvmStatic
         fun fromMethod(nameResolver: NameResolver, signature: JvmProtoBuf.JvmMethodSignature): MemberSignature {
@@ -21,12 +24,12 @@
 
         @JvmStatic
         fun fromMethodNameAndDesc(name: String, desc: String): MemberSignature {
-            return MemberSignature(name + desc)
+            return MemberSignature(uniqueString(name + desc))
         }
 
         @JvmStatic
         fun fromFieldNameAndDesc(name: String, desc: String): MemberSignature {
-            return MemberSignature("$name#$desc")
+            return MemberSignature(uniqueString("$name#$desc"))
         }
 
         @JvmStatic
@@ -37,7 +40,7 @@
 
         @JvmStatic
         fun fromMethodSignatureAndParameterIndex(signature: MemberSignature, index: Int): MemberSignature {
-            return MemberSignature("${signature.signature}@$index")
+            return MemberSignature(uniqueString("${signature.signature}@$index"))
         }
     }
 }
diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/StringInterner.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/StringInterner.kt
index bf9e9fb..2db3f26 100644
--- a/core/util.runtime/src/org/jetbrains/kotlin/utils/StringInterner.kt
+++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/StringInterner.kt
@@ -7,9 +7,13 @@
  * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
  */
 
-object StringInterner {
-    private val cache = ConcurrentHashMap<String, String>()
+class UniqueString private constructor(val value: String) {
+    override fun toString(): String = value
 
-    @JvmStatic
-    fun interned(string: String): String = cache.getOrPut(string) { string }
-}
\ No newline at end of file
+    companion object {
+        private val cache = ConcurrentHashMap<String, UniqueString>()
+        fun uniqueString(value: String): UniqueString {
+            return cache.getOrPut(value) { UniqueString(value) }
+        }
+    }
+}