Prefer using Array.Length as upper for loop limit (dotnet/coreclr#8923)
authormikedn <onemihaid@hotmail.com>
Thu, 12 Jan 2017 20:59:10 +0000 (22:59 +0200)
committerDan Moseley <danmose@microsoft.com>
Thu, 12 Jan 2017 20:59:10 +0000 (12:59 -0800)
The JIT can't eliminate range checks if it can't "see" Length and uses loop cloning which generates a lot of code. Even in cases where not all range checks can be eliminated and loop cloning is used anyway it's still preferable to have fewer range checks.

For example, SortExceptions is ~140 bytes shorter after this change, despite the fact that loop cloning is still being used.

Commit migrated from https://github.com/dotnet/coreclr/commit/01a9eaaa14fc3de8f11eafa6155af8ce4e44e9e9

src/coreclr/src/mscorlib/src/System/MulticastDelegate.cs
src/coreclr/src/mscorlib/src/System/Reflection/Assembly.cs
src/coreclr/src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs
src/coreclr/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs
src/coreclr/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs
src/coreclr/src/mscorlib/src/System/Reflection/MdImport.cs
src/coreclr/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs

index a7b244c..aa3271c 100644 (file)
@@ -466,10 +466,9 @@ namespace System
             {
                 // Create an array of delegate copies and each
                 //    element into the array
-                int invocationCount = (int)_invocationCount;
-                del = new Delegate[invocationCount];
+                del = new Delegate[(int)_invocationCount];
                 
-                for (int i = 0; i < invocationCount; i++)
+                for (int i = 0; i < del.Length; i++)
                     del[i] = (Delegate)invocationList[i];
             }
             return del;
index 677e4aa..2efd48d 100644 (file)
@@ -573,11 +573,10 @@ namespace System.Reflection
         {
             Module[] m = GetModules(false);
 
-            int iNumModules = m.Length;
             int iFinalLength = 0;
-            Type[][] ModuleTypes = new Type[iNumModules][];
+            Type[][] ModuleTypes = new Type[m.Length][];
 
-            for (int i = 0; i < iNumModules; i++)
+            for (int i = 0; i < ModuleTypes.Length; i++)
             {
                 ModuleTypes[i] = m[i].GetTypes();
                 iFinalLength += ModuleTypes[i].Length;
@@ -585,7 +584,7 @@ namespace System.Reflection
 
             int iCurrent = 0;
             Type[] ret = new Type[iFinalLength];
-            for (int i = 0; i < iNumModules; i++)
+            for (int i = 0; i < ModuleTypes.Length; i++)
             {
                 int iLength = ModuleTypes[i].Length;
                 Array.Copy(ModuleTypes[i], 0, ret, iCurrent, iLength);
@@ -1515,13 +1514,14 @@ namespace System.Reflection
         public override FileStream[] GetFiles(bool getResourceModules)
         {
             Module[] m = GetModules(getResourceModules);
-            int iLength = m.Length;
-            FileStream[] fs = new FileStream[iLength];
+            FileStream[] fs = new FileStream[m.Length];
 
-            for(int i = 0; i < iLength; i++)
+            for (int i = 0; i < fs.Length; i++)
+            {
                 fs[i] = new FileStream(((RuntimeModule)m[i]).GetFullyQualifiedName(),
                                        FileMode.Open,
                                        FileAccess.Read, FileShare.Read, FileStream.DefaultBufferSize, false);
+            }
 
             return fs;
         }
index 9e1d829..ed3ab07 100644 (file)
@@ -520,22 +520,18 @@ namespace System.Reflection.Emit
                                                 Type[] parameterTypes,
                                                 Type[] optionalParameterTypes)
         {
-            int cParams;
-            int i;
-            SignatureHelper sig;
-            if (parameterTypes == null)
-                cParams = 0;
-            else
-                cParams = parameterTypes.Length;
-            sig = SignatureHelper.GetMethodSigHelper(call, returnType);
-            for (i = 0; i < cParams; i++)
-                sig.AddArgument(parameterTypes[i]);
+            SignatureHelper sig = SignatureHelper.GetMethodSigHelper(call, returnType);
+            if (parameterTypes != null)
+            {
+                foreach (Type t in parameterTypes)
+                    sig.AddArgument(t);
+            }
             if (optionalParameterTypes != null && optionalParameterTypes.Length != 0)
             {
                 // add the sentinel
                 sig.AddSentinel();
-                for (i = 0; i < optionalParameterTypes.Length; i++)
-                    sig.AddArgument(optionalParameterTypes[i]);
+                foreach (Type t in optionalParameterTypes)
+                    sig.AddArgument(t);
             }
             return sig;
         }
index 716e85a..b7d7e3f 100644 (file)
@@ -388,20 +388,17 @@ namespace System.Reflection.Emit
             // Just a cheap insertion sort.  We don't expect many exceptions (<10), where InsertionSort beats QuickSort.
             // If we have more exceptions than this in real life, we should consider moving to a QuickSort.
 
-            int least;
-            __ExceptionInfo temp;
-            int length = exceptions.Length;
-            for (int i =0; i < length; i++)
+            for (int i = 0; i < exceptions.Length; i++)
             {
-                least = i;
-                for (int j =i + 1; j < length; j++)
+                int least = i;
+                for (int j = i + 1; j < exceptions.Length; j++)
                 {
                     if (exceptions[least].IsInner(exceptions[j]))
                     {
                         least = j;
                     }
                 }
-                temp = exceptions[i];
+                __ExceptionInfo temp = exceptions[i];
                 exceptions[i] = exceptions[least];
                 exceptions[least] = temp;
             }
index 00ca23f..e080134 100644 (file)
@@ -404,12 +404,11 @@ namespace System.Reflection.Emit
                 if (parameters == null)
                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidConstructorInfo"));
 
-                int count = parameters.Length;
-                Type[] parameterTypes = new Type[count];
-                Type[][] requiredCustomModifiers = new Type[count][];
-                Type[][] optionalCustomModifiers = new Type[count][];
+                Type[] parameterTypes = new Type[parameters.Length];
+                Type[][] requiredCustomModifiers = new Type[parameters.Length][];
+                Type[][] optionalCustomModifiers = new Type[parameters.Length][];
 
-                for (int i = 0; i < count; i++)
+                for (int i = 0; i < parameters.Length; i++)
                 {
                     if (parameters[i] == null)
                         throw new ArgumentException(Environment.GetResourceString("Argument_InvalidConstructorInfo"));
@@ -603,12 +602,14 @@ namespace System.Reflection.Emit
         internal SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
             Type[] parameterTypes, IEnumerable<Type> optionalParameterTypes, int cGenericParameters) 
         {
-            int cParams = (parameterTypes == null) ? 0 : parameterTypes.Length;
             SignatureHelper sig = SignatureHelper.GetMethodSigHelper(this, call, returnType, cGenericParameters);
 
-            for (int i = 0; i < cParams; i++)
+            if (parameterTypes != null)
             {
-                sig.AddArgument(parameterTypes[i]);
+                foreach (Type t in parameterTypes)
+                {
+                    sig.AddArgument(t);
+                }
             }
 
             if (optionalParameterTypes != null) {
index bbdf948..dc6b726 100644 (file)
@@ -408,7 +408,7 @@ namespace System.Reflection
                 return null;
 
             char[] c = new char[length];
-            for (int i = 0; i < length; i ++)
+            for (int i = 0; i < c.Length; i ++)
             {
 #if ALIGN_ACCESS
                 c[i] = (char)Marshal.ReadInt16( (IntPtr) (((char*)name) + i) );
index 7455967..2c19d98 100644 (file)
@@ -594,7 +594,7 @@ namespace System.Runtime.CompilerServices
                 // Reallocate both buckets and entries and rebuild the bucket and entries from scratch.
                 // This serves both to scrub entries with expired keys and to put the new entries in the proper bucket.
                 int[] newBuckets = new int[newSize];
-                for (int bucketIndex = 0; bucketIndex < newSize; bucketIndex++)
+                for (int bucketIndex = 0; bucketIndex < newBuckets.Length; bucketIndex++)
                 {
                     newBuckets[bucketIndex] = -1;
                 }