diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerState.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerState.cs
index 131d3b47b73..72b93dac45d 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerState.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/CompilerState.cs
@@ -215,7 +215,7 @@ internal static string GenerateCacheForFileList(ITaskItem[] fileItemList)
for (int i = 0; i < iCount; i++)
{
- iHashCode += fileItemList[i].ItemSpec.GetHashCode();
+ iHashCode += GetNonRandomizedHashCode(fileItemList[i].ItemSpec);
}
StringBuilder sb = new StringBuilder();
@@ -251,6 +251,49 @@ private static string GenerateStringFromFileNames(ITaskItem[] fileItemList)
return fileNames;
}
+ //
+ // Generates a stable hash code value for strings.
+ // In .NET Core the hash values for the same string can be different between
+ // subsequent program runs and cannot be used for caching here.
+ // Copied from String.Comparison.cs
+ //
+ private static unsafe int GetNonRandomizedHashCode(string str)
+ {
+ fixed (char* src = str)
+ {
+ Debug.Assert(src[str.Length] == '\0', "src[str.Length] == '\\0'");
+ Debug.Assert(((int)src) % 4 == 0, "Managed string should start at 4 bytes boundary");
+
+ uint hash1 = (5381 << 16) + 5381;
+ uint hash2 = hash1;
+
+ uint* ptr = (uint*)src;
+ int length = str.Length;
+
+ while (length > 2)
+ {
+ length -= 4;
+ // Where length is 4n-1 (e.g. 3,7,11,15,19) this additionally consumes the null terminator
+ hash1 = (RotateLeft(hash1, 5) + hash1) ^ ptr[0];
+ hash2 = (RotateLeft(hash2, 5) + hash2) ^ ptr[1];
+ ptr += 2;
+ }
+
+ if (length > 0)
+ {
+ // Where length is 4n-3 (e.g. 1,5,9,13,17) this additionally consumes the null terminator
+ hash2 = (RotateLeft(hash2, 5) + hash2) ^ ptr[0];
+ }
+
+ return (int)(hash1 + (hash2 * 1566083941));
+ }
+ }
+
+ private static uint RotateLeft(uint value, int offset)
+ {
+ return (value << offset) | (value >> (32 - offset));
+ }
+
#endregion
#region internal properties
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.csproj b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.csproj
index 42e96249113..6fa459c1954 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.csproj
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.csproj
@@ -27,6 +27,7 @@
true
true
AnyCPU;x64
+ true