You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avro.apache.org by "ASF GitHub Bot (JIRA)" <ji...@apache.org> on 2018/12/10 18:32:00 UTC

[jira] [Commented] (AVRO-1952) Prevent JIT compilation in C#

    [ https://issues.apache.org/jira/browse/AVRO-1952?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16715321#comment-16715321 ] 

ASF GitHub Bot commented on AVRO-1952:
--------------------------------------

dkulp closed pull request #134: AVRO-1952: Prevent JIT compilation in C#
URL: https://github.com/apache/avro/pull/134
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/lang/csharp/src/apache/main/Specific/ObjectCreator.cs b/lang/csharp/src/apache/main/Specific/ObjectCreator.cs
index 5435adbc2..d1daa951a 100644
--- a/lang/csharp/src/apache/main/Specific/ObjectCreator.cs
+++ b/lang/csharp/src/apache/main/Specific/ObjectCreator.cs
@@ -1,4 +1,4 @@
-/**
+/**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -30,7 +30,7 @@ public sealed class ObjectCreator
         public static ObjectCreator Instance { get { return instance; } }
 
         /// <summary>
-        /// Static generic dictionary type used for creating new dictionary instances 
+        /// Static generic dictionary type used for creating new dictionary instances
         /// </summary>
         private Type GenericMapType = typeof(Dictionary<,>);
 
@@ -43,14 +43,12 @@ public sealed class ObjectCreator
         /// Static generic nullable type used for creating new nullable instances
         /// </summary>
         private Type GenericNullableType = typeof(Nullable<>);
-        
+
         private readonly Assembly execAssembly;
         private readonly Assembly entryAssembly;
         private readonly bool diffAssembly;
 
         public delegate object CtorDelegate();
-        private Type ctorType = typeof(CtorDelegate);
-        Dictionary<NameCtorKey, CtorDelegate> ctors;
 
         private ObjectCreator()
         {
@@ -61,8 +59,6 @@ private ObjectCreator()
 
             GenericMapType = typeof(Dictionary<,>);
             GenericListType = typeof(List<>);
-
-            ctors = new Dictionary<NameCtorKey, CtorDelegate>();
         }
 
         public struct NameCtorKey : IEquatable<NameCtorKey>
@@ -110,7 +106,7 @@ public override int GetHashCode()
         /// <param name="name">the object type to locate</param>
         /// <param name="throwError">whether or not to throw an error if the type wasn't found</param>
         /// <returns>the object type, or <c>null</c> if not found</returns>
-        private Type FindType(string name,bool throwError) 
+        private Type FindType(string name,bool throwError)
         {
             Type type;
 
@@ -149,7 +145,7 @@ private Type FindType(string name,bool throwError)
                     {
                         if (name == t.Name || name == t.FullName) type = t;
                     }
-                    
+
                     if (type != null)
                         break;
                 }
@@ -185,7 +181,7 @@ public Type GetType(Schema schema)
             case Schema.Type.Double:
                 return typeof(double);
             case Schema.Type.Bytes:
-                return typeof(byte[]); 
+                return typeof(byte[]);
             case Schema.Type.String:
                 return typeof(string);
             case Schema.Type.Union:
@@ -207,7 +203,7 @@ public Type GetType(Schema schema)
                             itemType = GetType(s1);
                         }
 
-                        if (null != itemType ) 
+                        if (null != itemType )
                         {
                             if (itemType.IsValueType && !itemType.IsEnum)
                             {
@@ -217,7 +213,7 @@ public Type GetType(Schema schema)
                                 }
                                 catch (Exception) { }
                             }
-                            
+
                             return itemType;
                         }
                     }
@@ -272,28 +268,6 @@ public Type GetType(string name, Schema.Type schemaType)
             return type;
         }
 
-        /// <summary>
-        /// Gets the default constructor for the specified type
-        /// </summary>
-        /// <param name="name">name of object for the type</param>
-        /// <param name="schemaType">schema type for the object</param>
-        /// <param name="type">type of the object</param>
-        /// <returns>Default constructor for the type</returns>
-        public CtorDelegate GetConstructor(string name, Schema.Type schemaType, Type type)
-        {
-            ConstructorInfo ctorInfo = type.GetConstructor(Type.EmptyTypes);
-            if (ctorInfo == null)
-                throw new AvroException("Class " + name + " has no default constructor");
-
-            DynamicMethod dynMethod = new DynamicMethod("DM$OBJ_FACTORY_" + name, typeof(object), null, type, true);
-            ILGenerator ilGen = dynMethod.GetILGenerator();
-            ilGen.Emit(OpCodes.Nop);
-            ilGen.Emit(OpCodes.Newobj, ctorInfo);
-            ilGen.Emit(OpCodes.Ret);
-
-            return (CtorDelegate)dynMethod.CreateDelegate(ctorType);
-        }
-
         /// <summary>
         /// Creates new instance of the given type
         /// </summary>
@@ -302,20 +276,7 @@ public CtorDelegate GetConstructor(string name, Schema.Type schemaType, Type typ
         /// <returns>new object of the given type</returns>
         public object New(string name, Schema.Type schemaType)
         {
-            NameCtorKey key = new NameCtorKey(name, schemaType);
-            
-            CtorDelegate ctor;
-            lock(ctors)
-            {
-                if (!ctors.TryGetValue(key, out ctor))
-                {
-                    Type type = GetType(name, schemaType);
-                    ctor = GetConstructor(name, schemaType, type);
-
-                    ctors.Add(key, ctor);
-                }
-            }
-            return ctor();
+            return Activator.CreateInstance(GetType(name, schemaType));
         }
     }
 }
diff --git a/lang/csharp/src/apache/main/Specific/SpecificDatumReader.cs b/lang/csharp/src/apache/main/Specific/SpecificDatumReader.cs
index 5611a9c89..0e7b743d4 100644
--- a/lang/csharp/src/apache/main/Specific/SpecificDatumReader.cs
+++ b/lang/csharp/src/apache/main/Specific/SpecificDatumReader.cs
@@ -77,12 +77,6 @@ protected override FixedAccess GetFixedAccess(FixedSchema readerSchema)
             return new SpecificFixedAccess(readerSchema);
         }
 
-        private static ObjectCreator.CtorDelegate GetConstructor(string name, Schema.Type schemaType)
-        {
-            var creator = ObjectCreator.Instance;
-            return creator.GetConstructor(name, schemaType, creator.GetType(name, schemaType));
-        }
-
         private class SpecificEnumAccess : EnumAccess
         {
             public object CreateEnum(object reuse, int ordinal)
@@ -93,16 +87,16 @@ public object CreateEnum(object reuse, int ordinal)
 
         private class SpecificRecordAccess : RecordAccess
         {
-            private ObjectCreator.CtorDelegate objCreator;
+            private string typeName;
 
             public SpecificRecordAccess(RecordSchema readerSchema)
             {
-                objCreator = GetConstructor(readerSchema.Fullname, Schema.Type.Record);
+                typeName = readerSchema.Fullname;
             }
 
             public object CreateRecord(object reuse)
             {
-                return reuse ?? objCreator();
+                return reuse ?? ObjectCreator.Instance.New(typeName, Schema.Type.Record);
             }
 
             public object GetField(object record, string fieldName, int fieldPos)
@@ -118,16 +112,16 @@ public void AddField(object record, string fieldName, int fieldPos, object field
 
         private class SpecificFixedAccess : FixedAccess
         {
-            private ObjectCreator.CtorDelegate objCreator;
+            private string typeName;
 
             public SpecificFixedAccess(FixedSchema readerSchema)
             {
-                objCreator = GetConstructor(readerSchema.Fullname, Schema.Type.Fixed);
+                typeName = readerSchema.Fullname;
             }
 
             public object CreateFixed(object reuse)
             {
-                return reuse ?? objCreator();
+                return reuse ?? ObjectCreator.Instance.New(typeName, Schema.Type.Fixed);
             }
 
             public byte[] GetFixedBuffer(object rec)
@@ -138,7 +132,7 @@ public byte[] GetFixedBuffer(object rec)
 
         private class SpecificArrayAccess : ArrayAccess
         {
-            private ObjectCreator.CtorDelegate objCreator;
+            private string typeName;
 
             public SpecificArrayAccess(ArraySchema readerSchema)
             {
@@ -146,8 +140,8 @@ public SpecificArrayAccess(ArraySchema readerSchema)
                 string type = Avro.CodeGen.getType(readerSchema, false, ref nEnum);
                 type = type.Remove(0, 6);              // remove IList<
                 type = type.Remove(type.Length - 1);   // remove >
-        
-                objCreator = GetConstructor(type, Schema.Type.Array);
+
+                typeName = type;
             }
 
             public object Create(object reuse)
@@ -164,7 +158,7 @@ public object Create(object reuse)
                     array.Clear();
                 }
                 else
-                    array = objCreator() as IList;
+                    array = ObjectCreator.Instance.New(typeName, Schema.Type.Array) as IList;
                 return array;
             }
 
@@ -190,7 +184,7 @@ public void AddElements( object array, int elements, int index, ReadItem itemRea
 
         private class SpecificMapAccess : MapAccess
         {
-            private ObjectCreator.CtorDelegate objCreator;
+            private string typeName;
 
             public SpecificMapAccess(MapSchema readerSchema)
             {
@@ -198,8 +192,8 @@ public SpecificMapAccess(MapSchema readerSchema)
                 string type = Avro.CodeGen.getType(readerSchema, false, ref nEnum);
                 type = type.Remove(0, 19);             // remove IDictionary<string,
                 type = type.Remove(type.Length - 1);   // remove >
-        
-                objCreator = GetConstructor(type, Schema.Type.Map);
+
+                typeName = type;
             }
 
             public object Create(object reuse)
@@ -214,7 +208,7 @@ public object Create(object reuse)
                     map.Clear();
                 }
                 else
-                    map = objCreator() as System.Collections.IDictionary;
+                    map = ObjectCreator.Instance.New(typeName, Schema.Type.Map) as System.Collections.IDictionary;
                 return map;
             }
 
@@ -229,4 +223,4 @@ public void AddElements(object mapObj, int elements, ReadItem itemReader, Decode
             }
         }
     }
-}
\ No newline at end of file
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


> Prevent JIT compilation in C#
> -----------------------------
>
>                 Key: AVRO-1952
>                 URL: https://issues.apache.org/jira/browse/AVRO-1952
>             Project: Apache Avro
>          Issue Type: Improvement
>          Components: csharp
>         Environment: Typical Unity (C#) development for mobile, iOS compilation.
>            Reporter: Yuki Kuwabara
>            Priority: Major
>
> C# code includes JIT API (Reflection.Emit) and it occurs error in iOS or other platform that does not support JIT compile.
> Reflection.Emit is used in very specific point and it can be replaced with different safe code.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)