From 864926ee2e7a4b44012a5c2f9c68bd490dd7b0f6 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 7 Oct 2015 15:36:03 +0300 Subject: [PATCH] Don't always write JVM method signatures to metadata When the trivial type mapping (implemented in JvmProtoBufUtil) from ProtoBuf.Type instances works fine, don't write the signature since it can be loaded by exactly the same trivial type mapping --- .../serialization/JvmSerializerExtension.java | 85 +++++++++++++--- .../serialization/jvm/DebugJvmProtoBuf.java | 98 +++++-------------- .../src/jvm_descriptors.proto | 4 +- ...tBinaryClassAnnotationAndConstantLoader.kt | 14 ++- .../kotlin/load/kotlin/MemberSignature.kt | 5 + .../kotlin/serialization/jvm/JvmProtoBuf.java | 96 +++++------------- .../serialization/jvm/JvmProtoBufUtil.kt | 65 ++++++++++++ .../jvm/internal/KDeclarationContainerImpl.kt | 52 +++------- .../reflect/jvm/internal/KFunctionImpl.kt | 8 +- .../reflect/jvm/internal/KPropertyImpl.kt | 6 +- .../reflect/jvm/internal/RuntimeTypeMapper.kt | 49 +++++----- .../jps/incremental/ProtoCompareGenerated.kt | 18 +++- 12 files changed, 259 insertions(+), 241 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java index 8ceaceed003..1d1421a91b4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java @@ -25,11 +25,13 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.kotlin.load.java.lazy.types.RawTypeCapabilities; +import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.serialization.AnnotationSerializer; import org.jetbrains.kotlin.serialization.ProtoBuf; import org.jetbrains.kotlin.serialization.SerializerExtension; import org.jetbrains.kotlin.serialization.StringTable; import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf; +import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil; import org.jetbrains.kotlin.types.JetType; import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.commons.Method; @@ -85,7 +87,10 @@ public class JvmSerializerExtension extends SerializerExtension { public void serializeConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull ProtoBuf.Constructor.Builder proto) { Method method = bindings.get(METHOD_FOR_FUNCTION, descriptor); if (method != null) { - proto.setExtension(JvmProtoBuf.constructorSignature, new SignatureSerializer().methodSignature(method)); + JvmProtoBuf.JvmMethodSignature signature = new SignatureSerializer().methodSignature(descriptor, method); + if (signature != null) { + proto.setExtension(JvmProtoBuf.constructorSignature, signature); + } } saveImplClassName(descriptor, proto); @@ -95,7 +100,10 @@ public class JvmSerializerExtension extends SerializerExtension { public void serializeFunction(@NotNull FunctionDescriptor descriptor, @NotNull ProtoBuf.Function.Builder proto) { Method method = bindings.get(METHOD_FOR_FUNCTION, descriptor); if (method != null) { - proto.setExtension(JvmProtoBuf.methodSignature, new SignatureSerializer().methodSignature(method)); + JvmProtoBuf.JvmMethodSignature signature = new SignatureSerializer().methodSignature(descriptor, method); + if (signature != null) { + proto.setExtension(JvmProtoBuf.methodSignature, signature); + } } saveImplClassName(descriptor, proto); @@ -129,9 +137,9 @@ public class JvmSerializerExtension extends SerializerExtension { JvmProtoBuf.JvmPropertySignature signature = signatureSerializer.propertySignature( fieldName, fieldDesc, isStaticInOuter, - syntheticMethod != null ? signatureSerializer.methodSignature(syntheticMethod) : null, - getterMethod != null ? signatureSerializer.methodSignature(getterMethod) : null, - setterMethod != null ? signatureSerializer.methodSignature(setterMethod) : null + syntheticMethod != null ? signatureSerializer.methodSignature(null, syntheticMethod) : null, + getterMethod != null ? signatureSerializer.methodSignature(null, getterMethod) : null, + setterMethod != null ? signatureSerializer.methodSignature(null, setterMethod) : null ); proto.setExtension(JvmProtoBuf.propertySignature, signature); @@ -153,12 +161,67 @@ public class JvmSerializerExtension extends SerializerExtension { } private class SignatureSerializer { - @NotNull - public JvmProtoBuf.JvmMethodSignature methodSignature(@NotNull Method method) { - return JvmProtoBuf.JvmMethodSignature.newBuilder() - .setName(stringTable.getStringIndex(method.getName())) - .setDesc(stringTable.getStringIndex(method.getDescriptor())) - .build(); + @Nullable + public JvmProtoBuf.JvmMethodSignature methodSignature(@Nullable FunctionDescriptor descriptor, @NotNull Method method) { + JvmProtoBuf.JvmMethodSignature.Builder builder = JvmProtoBuf.JvmMethodSignature.newBuilder(); + if (descriptor == null || !descriptor.getName().asString().equals(method.getName())) { + builder.setName(stringTable.getStringIndex(method.getName())); + } + if (descriptor == null || requiresSignature(descriptor, method.getDescriptor())) { + builder.setDesc(stringTable.getStringIndex(method.getDescriptor())); + } + return builder.hasName() || builder.hasDesc() ? builder.build() : null; + } + + // We don't write those signatures which can be trivially reconstructed from already serialized data + // TODO: make JvmStringTable implement NameResolver and use JvmProtoBufUtil#getJvmMethodSignature instead + private boolean requiresSignature(@NotNull FunctionDescriptor descriptor, @NotNull String desc) { + StringBuilder sb = new StringBuilder(); + sb.append("("); + ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter(); + if (receiverParameter != null) { + String receiverDesc = mapTypeDefault(receiverParameter.getValue().getType()); + if (receiverDesc == null) return true; + sb.append(receiverDesc); + } + + for (ValueParameterDescriptor valueParameter : descriptor.getValueParameters()) { + String paramDesc = mapTypeDefault(valueParameter.getType()); + if (paramDesc == null) return true; + sb.append(paramDesc); + } + + sb.append(")"); + + JetType returnType = descriptor.getReturnType(); + String returnTypeDesc = returnType == null ? "V" : mapTypeDefault(returnType); + if (returnTypeDesc == null) return true; + sb.append(returnTypeDesc); + + return !sb.toString().equals(desc); + } + + @Nullable + private String mapTypeDefault(@NotNull JetType type) { + ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor(); + if (!(classifier instanceof ClassDescriptor)) return null; + ClassId classId = classId((ClassDescriptor) classifier); + return classId == null ? null : JvmProtoBufUtil.mapClassIdDefault(classId); + } + + @Nullable + private ClassId classId(@NotNull ClassDescriptor descriptor) { + DeclarationDescriptor container = descriptor.getContainingDeclaration(); + if (container instanceof PackageFragmentDescriptor) { + return ClassId.topLevel(((PackageFragmentDescriptor) container).getFqName().child(descriptor.getName())); + } + else if (container instanceof ClassDescriptor) { + ClassId outerClassId = classId((ClassDescriptor) container); + return outerClassId == null ? null : outerClassId.createNestedClassId(descriptor.getName()); + } + else { + return null; + } } @NotNull diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/jvm/DebugJvmProtoBuf.java b/compiler/tests/org/jetbrains/kotlin/serialization/jvm/DebugJvmProtoBuf.java index cb26d0e07a5..4860be4957e 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/jvm/DebugJvmProtoBuf.java +++ b/compiler/tests/org/jetbrains/kotlin/serialization/jvm/DebugJvmProtoBuf.java @@ -2164,19 +2164,19 @@ public final class DebugJvmProtoBuf { public interface JvmMethodSignatureOrBuilder extends com.google.protobuf.MessageOrBuilder { - // required int32 name = 1; + // optional int32 name = 1; /** - * required int32 name = 1; + * optional int32 name = 1; */ boolean hasName(); /** - * required int32 name = 1; + * optional int32 name = 1; */ int getName(); - // required int32 desc = 2; + // optional int32 desc = 2; /** - * required int32 desc = 2; + * optional int32 desc = 2; * *
      * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2184,7 +2184,7 @@ public final class DebugJvmProtoBuf {
      */
     boolean hasDesc();
     /**
-     * required int32 desc = 2;
+     * optional int32 desc = 2;
      *
      * 
      * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2293,27 +2293,27 @@ public final class DebugJvmProtoBuf {
     }
 
     private int bitField0_;
-    // required int32 name = 1;
+    // optional int32 name = 1;
     public static final int NAME_FIELD_NUMBER = 1;
     private int name_;
     /**
-     * required int32 name = 1;
+     * optional int32 name = 1;
      */
     public boolean hasName() {
       return ((bitField0_ & 0x00000001) == 0x00000001);
     }
     /**
-     * required int32 name = 1;
+     * optional int32 name = 1;
      */
     public int getName() {
       return name_;
     }
 
-    // required int32 desc = 2;
+    // optional int32 desc = 2;
     public static final int DESC_FIELD_NUMBER = 2;
     private int desc_;
     /**
-     * required int32 desc = 2;
+     * optional int32 desc = 2;
      *
      * 
      * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2323,7 +2323,7 @@ public final class DebugJvmProtoBuf {
       return ((bitField0_ & 0x00000002) == 0x00000002);
     }
     /**
-     * required int32 desc = 2;
+     * optional int32 desc = 2;
      *
      * 
      * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2342,14 +2342,6 @@ public final class DebugJvmProtoBuf {
       byte isInitialized = memoizedIsInitialized;
       if (isInitialized != -1) return isInitialized == 1;
 
-      if (!hasName()) {
-        memoizedIsInitialized = 0;
-        return false;
-      }
-      if (!hasDesc()) {
-        memoizedIsInitialized = 0;
-        return false;
-      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -2563,14 +2555,6 @@ public final class DebugJvmProtoBuf {
       }
 
       public final boolean isInitialized() {
-        if (!hasName()) {
-          
-          return false;
-        }
-        if (!hasDesc()) {
-          
-          return false;
-        }
         return true;
       }
 
@@ -2593,22 +2577,22 @@ public final class DebugJvmProtoBuf {
       }
       private int bitField0_;
 
-      // required int32 name = 1;
+      // optional int32 name = 1;
       private int name_ ;
       /**
-       * required int32 name = 1;
+       * optional int32 name = 1;
        */
       public boolean hasName() {
         return ((bitField0_ & 0x00000001) == 0x00000001);
       }
       /**
-       * required int32 name = 1;
+       * optional int32 name = 1;
        */
       public int getName() {
         return name_;
       }
       /**
-       * required int32 name = 1;
+       * optional int32 name = 1;
        */
       public Builder setName(int value) {
         bitField0_ |= 0x00000001;
@@ -2617,7 +2601,7 @@ public final class DebugJvmProtoBuf {
         return this;
       }
       /**
-       * required int32 name = 1;
+       * optional int32 name = 1;
        */
       public Builder clearName() {
         bitField0_ = (bitField0_ & ~0x00000001);
@@ -2626,10 +2610,10 @@ public final class DebugJvmProtoBuf {
         return this;
       }
 
-      // required int32 desc = 2;
+      // optional int32 desc = 2;
       private int desc_ ;
       /**
-       * required int32 desc = 2;
+       * optional int32 desc = 2;
        *
        * 
        * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2639,7 +2623,7 @@ public final class DebugJvmProtoBuf {
         return ((bitField0_ & 0x00000002) == 0x00000002);
       }
       /**
-       * required int32 desc = 2;
+       * optional int32 desc = 2;
        *
        * 
        * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2649,7 +2633,7 @@ public final class DebugJvmProtoBuf {
         return desc_;
       }
       /**
-       * required int32 desc = 2;
+       * optional int32 desc = 2;
        *
        * 
        * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2662,7 +2646,7 @@ public final class DebugJvmProtoBuf {
         return this;
       }
       /**
-       * required int32 desc = 2;
+       * optional int32 desc = 2;
        *
        * 
        * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -3663,24 +3647,6 @@ public final class DebugJvmProtoBuf {
           return false;
         }
       }
-      if (hasSyntheticMethod()) {
-        if (!getSyntheticMethod().isInitialized()) {
-          memoizedIsInitialized = 0;
-          return false;
-        }
-      }
-      if (hasGetter()) {
-        if (!getGetter().isInitialized()) {
-          memoizedIsInitialized = 0;
-          return false;
-        }
-      }
-      if (hasSetter()) {
-        if (!getSetter().isInitialized()) {
-          memoizedIsInitialized = 0;
-          return false;
-        }
-      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -3968,24 +3934,6 @@ public final class DebugJvmProtoBuf {
             return false;
           }
         }
-        if (hasSyntheticMethod()) {
-          if (!getSyntheticMethod().isInitialized()) {
-            
-            return false;
-          }
-        }
-        if (hasGetter()) {
-          if (!getGetter().isInitialized()) {
-            
-            return false;
-          }
-        }
-        if (hasSetter()) {
-          if (!getSetter().isInitialized()) {
-            
-            return false;
-          }
-        }
         return true;
       }
 
@@ -4672,7 +4620,7 @@ public final class DebugJvmProtoBuf {
       "ce_char\030\005 \003(\005B\002\020\001\"E\n\tOperation\022\010\n\004NONE\020\000" +
       "\022\030\n\024INTERNAL_TO_CLASS_ID\020\001\022\024\n\020DESC_TO_CL" +
       "ASS_ID\020\002\"<\n\022JvmMethodSignature\022\022\n\004name\030\001" +
-      " \002(\005B\004\230\265\030\001\022\022\n\004desc\030\002 \002(\005B\004\230\265\030\001\"^\n\021JvmFie" +
+      " \001(\005B\004\230\265\030\001\022\022\n\004desc\030\002 \001(\005B\004\230\265\030\001\"^\n\021JvmFie" +
       "ldSignature\022\022\n\004name\030\001 \002(\005B\004\230\265\030\001\022\022\n\004desc\030" +
       "\002 \002(\005B\004\230\265\030\001\022!\n\022is_static_in_outer\030\003 \001(\010:" +
       "\005false\"\316\002\n\024JvmPropertySignature\022H\n\005field",
diff --git a/core/descriptor.loader.java/src/jvm_descriptors.proto b/core/descriptor.loader.java/src/jvm_descriptors.proto
index f65226f8864..71694ebba75 100644
--- a/core/descriptor.loader.java/src/jvm_descriptors.proto
+++ b/core/descriptor.loader.java/src/jvm_descriptors.proto
@@ -62,10 +62,10 @@ message StringTableTypes {
 }
 
 message JvmMethodSignature {
-  required int32 name = 1 [(string_id_in_table) = true];
+  optional int32 name = 1 [(string_id_in_table) = true];
 
   // JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
-  required int32 desc = 2 [(string_id_in_table) = true];
+  optional int32 desc = 2 [(string_id_in_table) = true];
 }
 
 message JvmFieldSignature {
diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt
index 6e0045b2922..2e4b7874bb9 100644
--- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt
+++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt
@@ -24,7 +24,11 @@ import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.serialization.ProtoBuf
 import org.jetbrains.kotlin.serialization.deserialization.*
 import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
-import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.*
+import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.index
+import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.methodImplClassName
+import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.propertyImplClassName
+import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.propertySignature
+import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
 import org.jetbrains.kotlin.storage.StorageManager
 import org.jetbrains.kotlin.types.JetType
 import java.util.*
@@ -297,11 +301,11 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader {
-                MemberSignature.fromMethod(nameResolver, proto.getExtension(constructorSignature))
+            proto is ProtoBuf.Constructor -> {
+                MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmConstructorSignature(proto, nameResolver) ?: return null)
             }
-            proto is ProtoBuf.Function && proto.hasExtension(methodSignature) -> {
-                MemberSignature.fromMethod(nameResolver, proto.getExtension(methodSignature))
+            proto is ProtoBuf.Function -> {
+                MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver) ?: return null)
             }
             proto is ProtoBuf.Property && proto.hasExtension(propertySignature) -> {
                 val signature = proto.getExtension(propertySignature)
diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/MemberSignature.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/MemberSignature.kt
index 83a7240755f..b6e976ee7f3 100644
--- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/MemberSignature.kt
+++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/MemberSignature.kt
@@ -33,6 +33,11 @@ data class MemberSignature private constructor(private val signature: String) {
             return MemberSignature(name + desc)
         }
 
+        @JvmStatic
+        public fun fromMethodNameAndDesc(namePlusDesc: String): MemberSignature {
+            return MemberSignature(namePlusDesc)
+        }
+
         @JvmStatic
         public fun fromFieldNameAndDesc(name: String, desc: String): MemberSignature {
             return MemberSignature(name + "#" + desc)
diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBuf.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBuf.java
index ca8ca511abd..672d4e959cd 100644
--- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBuf.java
+++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBuf.java
@@ -1860,19 +1860,19 @@ public final class JvmProtoBuf {
   public interface JvmMethodSignatureOrBuilder
       extends com.google.protobuf.MessageLiteOrBuilder {
 
-    // required int32 name = 1;
+    // optional int32 name = 1;
     /**
-     * required int32 name = 1;
+     * optional int32 name = 1;
      */
     boolean hasName();
     /**
-     * required int32 name = 1;
+     * optional int32 name = 1;
      */
     int getName();
 
-    // required int32 desc = 2;
+    // optional int32 desc = 2;
     /**
-     * required int32 desc = 2;
+     * optional int32 desc = 2;
      *
      * 
      * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -1880,7 +1880,7 @@ public final class JvmProtoBuf {
      */
     boolean hasDesc();
     /**
-     * required int32 desc = 2;
+     * optional int32 desc = 2;
      *
      * 
      * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -1968,27 +1968,27 @@ public final class JvmProtoBuf {
     }
 
     private int bitField0_;
-    // required int32 name = 1;
+    // optional int32 name = 1;
     public static final int NAME_FIELD_NUMBER = 1;
     private int name_;
     /**
-     * required int32 name = 1;
+     * optional int32 name = 1;
      */
     public boolean hasName() {
       return ((bitField0_ & 0x00000001) == 0x00000001);
     }
     /**
-     * required int32 name = 1;
+     * optional int32 name = 1;
      */
     public int getName() {
       return name_;
     }
 
-    // required int32 desc = 2;
+    // optional int32 desc = 2;
     public static final int DESC_FIELD_NUMBER = 2;
     private int desc_;
     /**
-     * required int32 desc = 2;
+     * optional int32 desc = 2;
      *
      * 
      * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -1998,7 +1998,7 @@ public final class JvmProtoBuf {
       return ((bitField0_ & 0x00000002) == 0x00000002);
     }
     /**
-     * required int32 desc = 2;
+     * optional int32 desc = 2;
      *
      * 
      * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2017,14 +2017,6 @@ public final class JvmProtoBuf {
       byte isInitialized = memoizedIsInitialized;
       if (isInitialized != -1) return isInitialized == 1;
 
-      if (!hasName()) {
-        memoizedIsInitialized = 0;
-        return false;
-      }
-      if (!hasDesc()) {
-        memoizedIsInitialized = 0;
-        return false;
-      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -2196,14 +2188,6 @@ public final class JvmProtoBuf {
       }
 
       public final boolean isInitialized() {
-        if (!hasName()) {
-          
-          return false;
-        }
-        if (!hasDesc()) {
-          
-          return false;
-        }
         return true;
       }
 
@@ -2226,22 +2210,22 @@ public final class JvmProtoBuf {
       }
       private int bitField0_;
 
-      // required int32 name = 1;
+      // optional int32 name = 1;
       private int name_ ;
       /**
-       * required int32 name = 1;
+       * optional int32 name = 1;
        */
       public boolean hasName() {
         return ((bitField0_ & 0x00000001) == 0x00000001);
       }
       /**
-       * required int32 name = 1;
+       * optional int32 name = 1;
        */
       public int getName() {
         return name_;
       }
       /**
-       * required int32 name = 1;
+       * optional int32 name = 1;
        */
       public Builder setName(int value) {
         bitField0_ |= 0x00000001;
@@ -2250,7 +2234,7 @@ public final class JvmProtoBuf {
         return this;
       }
       /**
-       * required int32 name = 1;
+       * optional int32 name = 1;
        */
       public Builder clearName() {
         bitField0_ = (bitField0_ & ~0x00000001);
@@ -2259,10 +2243,10 @@ public final class JvmProtoBuf {
         return this;
       }
 
-      // required int32 desc = 2;
+      // optional int32 desc = 2;
       private int desc_ ;
       /**
-       * required int32 desc = 2;
+       * optional int32 desc = 2;
        *
        * 
        * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2272,7 +2256,7 @@ public final class JvmProtoBuf {
         return ((bitField0_ & 0x00000002) == 0x00000002);
       }
       /**
-       * required int32 desc = 2;
+       * optional int32 desc = 2;
        *
        * 
        * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2282,7 +2266,7 @@ public final class JvmProtoBuf {
         return desc_;
       }
       /**
-       * required int32 desc = 2;
+       * optional int32 desc = 2;
        *
        * 
        * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2295,7 +2279,7 @@ public final class JvmProtoBuf {
         return this;
       }
       /**
-       * required int32 desc = 2;
+       * optional int32 desc = 2;
        *
        * 
        * JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -3164,24 +3148,6 @@ public final class JvmProtoBuf {
           return false;
         }
       }
-      if (hasSyntheticMethod()) {
-        if (!getSyntheticMethod().isInitialized()) {
-          memoizedIsInitialized = 0;
-          return false;
-        }
-      }
-      if (hasGetter()) {
-        if (!getGetter().isInitialized()) {
-          memoizedIsInitialized = 0;
-          return false;
-        }
-      }
-      if (hasSetter()) {
-        if (!getSetter().isInitialized()) {
-          memoizedIsInitialized = 0;
-          return false;
-        }
-      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -3391,24 +3357,6 @@ public final class JvmProtoBuf {
             return false;
           }
         }
-        if (hasSyntheticMethod()) {
-          if (!getSyntheticMethod().isInitialized()) {
-            
-            return false;
-          }
-        }
-        if (hasGetter()) {
-          if (!getGetter().isInitialized()) {
-            
-            return false;
-          }
-        }
-        if (hasSetter()) {
-          if (!getSetter().isInitialized()) {
-            
-            return false;
-          }
-        }
         return true;
       }
 
diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBufUtil.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBufUtil.kt
index f62a1bd7065..7f261c7ca8e 100644
--- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBufUtil.kt
+++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/serialization/jvm/JvmProtoBufUtil.kt
@@ -17,10 +17,15 @@
 package org.jetbrains.kotlin.serialization.jvm
 
 import com.google.protobuf.ExtensionRegistryLite
+import org.jetbrains.kotlin.builtins.KotlinBuiltIns
 import org.jetbrains.kotlin.load.kotlin.JvmNameResolver
+import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
+import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
 import org.jetbrains.kotlin.serialization.ClassData
 import org.jetbrains.kotlin.serialization.PackageData
 import org.jetbrains.kotlin.serialization.ProtoBuf
+import org.jetbrains.kotlin.serialization.deserialization.NameResolver
 import java.io.ByteArrayInputStream
 
 public object JvmProtoBufUtil {
@@ -53,4 +58,64 @@ public object JvmProtoBufUtil {
         val packageProto = ProtoBuf.Package.parseFrom(input, EXTENSION_REGISTRY)
         return PackageData(nameResolver, packageProto)
     }
+
+    // returns JVM signature in the format: "equals(Ljava/lang/Object;)Z"
+    fun getJvmMethodSignature(proto: ProtoBuf.FunctionOrBuilder, nameResolver: NameResolver): String? {
+        val signature =
+                if (proto.hasExtension(JvmProtoBuf.methodSignature)) proto.getExtension(JvmProtoBuf.methodSignature) else null
+        val name = if (signature != null && signature.hasName()) signature.name else proto.name
+        val desc = if (signature != null && signature.hasDesc()) {
+            nameResolver.getString(signature.desc)
+        }
+        else {
+            val parameterTypes =
+                    (if (proto.hasReceiverType()) listOf(proto.receiverType) else listOf()) + proto.valueParameterList.map { it.type }
+
+            val parametersDesc = parameterTypes.map { mapTypeDefault(it, nameResolver) ?: return null }
+            val returnTypeDesc = mapTypeDefault(proto.returnType, nameResolver) ?: return null
+
+            parametersDesc.joinToString(separator = "", prefix = "(", postfix = ")") + returnTypeDesc
+        }
+        return nameResolver.getString(name) + desc
+    }
+
+    fun getJvmConstructorSignature(proto: ProtoBuf.ConstructorOrBuilder, nameResolver: NameResolver): String? {
+        val signature =
+                if (proto.hasExtension(JvmProtoBuf.constructorSignature)) proto.getExtension(JvmProtoBuf.constructorSignature) else null
+        val desc = if (signature != null && signature.hasDesc()) {
+            nameResolver.getString(signature.desc)
+        }
+        else {
+            proto.valueParameterList.map {
+                mapTypeDefault(it.type, nameResolver) ?: return null
+            }.joinToString(separator = "", prefix = "(", postfix = ")V")
+        }
+        return "" + desc
+    }
+
+    private fun mapTypeDefault(type: ProtoBuf.Type, nameResolver: NameResolver): String? {
+        return if (type.hasClassName()) mapClassIdDefault(nameResolver.getClassId(type.className)) else null
+    }
+
+    @JvmStatic
+    fun mapClassIdDefault(classId: ClassId): String {
+        val internalName = classId.asString().replace('.', '$')
+        val simpleName = internalName.removePrefix("kotlin/")
+        if (simpleName != internalName) {
+            for (jvmPrimitive in JvmPrimitiveType.values()) {
+                val primitiveType = jvmPrimitive.primitiveType
+                if (simpleName == primitiveType.typeName.asString()) return jvmPrimitive.desc
+                if (simpleName == primitiveType.arrayTypeName.asString()) return "[" + jvmPrimitive.desc
+            }
+
+            if (simpleName == KotlinBuiltIns.FQ_NAMES.unit.shortName().asString()) return "V"
+        }
+
+        val javaClassId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(classId.asSingleFqName().toUnsafe())
+        if (javaClassId != null) {
+            return "L" + javaClassId.asString().replace('.', '$') + ";"
+        }
+
+        return "L$internalName;"
+    }
 }
diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt
index 9c9d3944683..a56d38f39cb 100644
--- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt
+++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt
@@ -156,79 +156,49 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
             }
 
     // TODO: check resulting method's return type
-    fun findMethodBySignature(
-            signature: JvmProtoBuf.JvmMethodSignature,
-            nameResolver: NameResolver,
-            declared: Boolean
-    ): Method? {
-        val name = nameResolver.getString(signature.name)
+    fun findMethodBySignature(name: String, desc: String, declared: Boolean): Method? {
         if (name == "") return null
 
-        val parameterTypes = loadParameterTypes(nameResolver, signature)
-
         // Method for a top level function should be the one from the package facade.
         // This is likely to change after the package part reform.
-        val owner = jClass
-
-        return owner.tryGetMethod(name, parameterTypes, declared)
+        return jClass.tryGetMethod(name, loadParameterTypes(desc), declared)
     }
 
-    fun findDefaultMethod(
-            signature: JvmProtoBuf.JvmMethodSignature,
-            nameResolver: NameResolver,
-            isMember: Boolean,
-            declared: Boolean
-    ): Method? {
-        val name = nameResolver.getString(signature.name)
+    fun findDefaultMethod(name: String, desc: String, isMember: Boolean, declared: Boolean): Method? {
         if (name == "") return null
 
         val parameterTypes = arrayListOf>()
         if (isMember) {
             parameterTypes.add(jClass)
         }
-        addParametersAndMasks(parameterTypes, nameResolver, signature)
+        addParametersAndMasks(parameterTypes, desc)
 
         return jClass.tryGetMethod(name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, parameterTypes, declared)
     }
 
-    fun findConstructorBySignature(
-            signature: JvmProtoBuf.JvmMethodSignature,
-            nameResolver: NameResolver,
-            declared: Boolean
-    ): Constructor<*>? {
-        if (nameResolver.getString(signature.name) != "") return null
-
-        return jClass.tryGetConstructor(loadParameterTypes(nameResolver, signature), declared)
+    fun findConstructorBySignature(desc: String, declared: Boolean): Constructor<*>? {
+        return jClass.tryGetConstructor(loadParameterTypes(desc), declared)
     }
 
-    fun findDefaultConstructor(
-            signature: JvmProtoBuf.JvmMethodSignature,
-            nameResolver: NameResolver,
-            declared: Boolean
-    ): Constructor<*>? {
-        if (nameResolver.getString(signature.name) != "") return null
-
+    fun findDefaultConstructor(desc: String, declared: Boolean): Constructor<*>? {
         val parameterTypes = arrayListOf>()
-        addParametersAndMasks(parameterTypes, nameResolver, signature)
+        addParametersAndMasks(parameterTypes, desc)
         parameterTypes.add(DEFAULT_CONSTRUCTOR_MARKER)
 
         return jClass.tryGetConstructor(parameterTypes, declared)
     }
 
-    private fun addParametersAndMasks(
-            result: MutableList>, nameResolver: NameResolver, signature: JvmProtoBuf.JvmMethodSignature
-    ) {
-        val valueParameters = loadParameterTypes(nameResolver, signature)
+    private fun addParametersAndMasks(result: MutableList>, desc: String) {
+        val valueParameters = loadParameterTypes(desc)
         result.addAll(valueParameters)
         repeat((valueParameters.size() + Integer.SIZE - 1) / Integer.SIZE) {
             result.add(Integer.TYPE)
         }
     }
 
-    private fun loadParameterTypes(nameResolver: NameResolver, signature: JvmProtoBuf.JvmMethodSignature): List> {
+    private fun loadParameterTypes(desc: String): List> {
         val classLoader = jClass.safeClassLoader
         val result = arrayListOf>()
-        val desc = nameResolver.getString(signature.desc)
 
         var i = 1
         while (desc[i] != ')') {
diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt
index 494658c07a4..c6698c860d4 100644
--- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt
+++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt
@@ -51,8 +51,8 @@ internal open class KFunctionImpl protected constructor(
     override val caller: FunctionCaller<*> by ReflectProperties.lazySoft {
         val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)
         val member: Member? = when (jvmSignature) {
-            is KotlinConstructor -> container.findConstructorBySignature(jvmSignature.signature, jvmSignature.nameResolver, isDeclared())
-            is KotlinFunction -> container.findMethodBySignature(jvmSignature.signature, jvmSignature.nameResolver, isDeclared())
+            is KotlinConstructor -> container.findConstructorBySignature(jvmSignature.constructorDesc, isDeclared())
+            is KotlinFunction -> container.findMethodBySignature(jvmSignature.methodName, jvmSignature.methodDesc, isDeclared())
             is JavaMethod -> jvmSignature.method
             is JavaConstructor -> jvmSignature.constructor
             is BuiltInFunction -> jvmSignature.getMember(container)
@@ -76,11 +76,11 @@ internal open class KFunctionImpl protected constructor(
         val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)
         val member: Member? = when (jvmSignature) {
             is KotlinFunction -> {
-                container.findDefaultMethod(jvmSignature.signature, jvmSignature.nameResolver,
+                container.findDefaultMethod(jvmSignature.methodName, jvmSignature.methodDesc,
                                             !Modifier.isStatic(caller.member.modifiers), isDeclared())
             }
             is KotlinConstructor -> {
-                container.findDefaultConstructor(jvmSignature.signature, jvmSignature.nameResolver, isDeclared())
+                container.findDefaultConstructor(jvmSignature.constructorDesc, isDeclared())
             }
             else -> {
                 // Java methods, Java constructors and built-ins don't have $default methods
diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt
index ededc1c41fc..1070937fd6e 100644
--- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt
+++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt
@@ -116,7 +116,11 @@ private fun KPropertyImpl.Accessor<*>.computeCallerForAccessor(isGetter: Boolean
             }
 
             val accessor = accessorSignature?.let { signature ->
-                property.container.findMethodBySignature(signature, jvmSignature.nameResolver, Visibilities.isPrivate(descriptor.visibility))
+                property.container.findMethodBySignature(
+                        jvmSignature.nameResolver.getString(signature.name),
+                        jvmSignature.nameResolver.getString(signature.desc),
+                        Visibilities.isPrivate(descriptor.visibility)
+                )
             }
 
             when {
diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt
index 5b071695bca..3dd5ae12754 100644
--- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt
+++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.serialization.deserialization.NameResolver
 import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
 import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
 import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
+import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
 import java.lang.reflect.Constructor
 import java.lang.reflect.Field
 import java.lang.reflect.Member
@@ -45,22 +46,17 @@ import kotlin.reflect.KotlinReflectionInternalError
 internal sealed class JvmFunctionSignature {
     abstract fun asString(): String
 
-    class KotlinFunction(
-            val proto: ProtoBuf.Function,
-            val signature: JvmProtoBuf.JvmMethodSignature,
-            val nameResolver: NameResolver
-    ) : JvmFunctionSignature() {
-        override fun asString(): String =
-                nameResolver.getString(signature.name) + nameResolver.getString(signature.desc)
+    class KotlinFunction(val signature: String) : JvmFunctionSignature() {
+        val methodName: String get() = signature.substringBefore('(')
+        val methodDesc: String get() = signature.substring(signature.indexOf('('))
+
+        override fun asString(): String = signature
     }
 
-    class KotlinConstructor(
-            val proto: ProtoBuf.Constructor,
-            val signature: JvmProtoBuf.JvmMethodSignature,
-            val nameResolver: NameResolver
-    ) : JvmFunctionSignature() {
-        override fun asString(): String =
-                nameResolver.getString(signature.name) + nameResolver.getString(signature.desc)
+    class KotlinConstructor(val signature: String) : JvmFunctionSignature() {
+        val constructorDesc: String get() = signature.substring(signature.indexOf('('))
+
+        override fun asString(): String = signature
     }
 
     class JavaMethod(val method: Method) : JvmFunctionSignature() {
@@ -132,19 +128,24 @@ internal object RuntimeTypeMapper {
 
         when (function) {
             is DeserializedCallableMemberDescriptor -> {
-                val proto = function.proto
-                if (proto is ProtoBuf.Function && proto.hasExtension(JvmProtoBuf.methodSignature)) {
-                    val signature = proto.getExtension(JvmProtoBuf.methodSignature)
-                    return JvmFunctionSignature.KotlinFunction(proto, signature, function.nameResolver)
+                mapIntrinsicFunctionSignature(function)?.let {
+                    return it
                 }
-                if (proto is ProtoBuf.Constructor && proto.hasExtension(JvmProtoBuf.constructorSignature)) {
-                    val signature = proto.getExtension(JvmProtoBuf.constructorSignature)
-                    return JvmFunctionSignature.KotlinConstructor(proto, signature, function.nameResolver)
+
+                val proto = function.proto
+                if (proto is ProtoBuf.Function) {
+                    JvmProtoBufUtil.getJvmMethodSignature(proto, function.nameResolver)?.let { signature ->
+                        return JvmFunctionSignature.KotlinFunction(signature)
+                    }
+                }
+                if (proto is ProtoBuf.Constructor) {
+                    JvmProtoBufUtil.getJvmConstructorSignature(proto, function.nameResolver)?.let { signature ->
+                        return JvmFunctionSignature.KotlinConstructor(signature)
+                    }
                 }
                 // If it's a deserialized function but has no JVM signature, it must be from built-ins
-                return mapIntrinsicFunctionSignature(function) ?:
-                       throw KotlinReflectionInternalError("Reflection on built-in Kotlin types is not yet fully supported. " +
-                                                           "No metadata found for $function")
+                throw KotlinReflectionInternalError("Reflection on built-in Kotlin types is not yet fully supported. " +
+                        "No metadata found for $function")
             }
             is JavaMethodDescriptor -> {
                 val method = ((function.source as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member ?:
diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/ProtoCompareGenerated.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/ProtoCompareGenerated.kt
index da4adbf258f..fb2c9754a14 100644
--- a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/ProtoCompareGenerated.kt
+++ b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/ProtoCompareGenerated.kt
@@ -330,9 +330,15 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
     }
 
     open fun checkEquals(old: JvmProtoBuf.JvmMethodSignature, new: JvmProtoBuf.JvmMethodSignature): Boolean {
-        if (!checkStringEquals(old.name, new.name)) return false
+        if (old.hasName() != new.hasName()) return false
+        if (old.hasName()) {
+            if (!checkStringEquals(old.name, new.name)) return false
+        }
 
-        if (!checkStringEquals(old.desc, new.desc)) return false
+        if (old.hasDesc() != new.hasDesc()) return false
+        if (old.hasDesc()) {
+            if (!checkStringEquals(old.desc, new.desc)) return false
+        }
 
         return true
     }
@@ -896,9 +902,13 @@ public fun ProtoBuf.ValueParameter.hashCode(stringIndexes: (Int) -> Int, fqNameI
 public fun JvmProtoBuf.JvmMethodSignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
     var hashCode = 1
 
-    hashCode = 31 * hashCode + stringIndexes(name)
+    if (hasName()) {
+        hashCode = 31 * hashCode + stringIndexes(name)
+    }
 
-    hashCode = 31 * hashCode + stringIndexes(desc)
+    if (hasDesc()) {
+        hashCode = 31 * hashCode + stringIndexes(desc)
+    }
 
     return hashCode
 }