Permalink
Browse files

[gc] Don't do unaligned loads in mono_gc_memmove ().

This caused problems on S390x, at least.
  • Loading branch information...
1 parent e8cc677 commit a4dc17108b4722bbe43a04dae687950bbb2117a6 @schani schani committed Jul 18, 2011
Showing with 53 additions and 19 deletions.
  1. +11 −0 mono/metadata/gc.c
  2. +42 −19 mono/tests/bug-705140.cs
View
@@ -1543,6 +1543,17 @@ void
mono_gc_memmove (void *dest, const void *src, size_t size)
{
/*
+ * If dest and src are differently aligned with respect to
+ * pointer size then it makes no sense to do aligned copying.
+ * In fact, we would end up with unaligned loads which is
+ * incorrect on some architectures.
+ */
+ if ((char*)dest - (char*)align_down (dest) != (char*)src - (char*)align_down (src)) {
+ memmove (dest, src, size);
+ return;
+ }
+
+ /*
* A bit of explanation on why we align only dest before doing word copies.
* Pointers to managed objects must always be stored in word aligned addresses, so
* even if dest is misaligned, src will be by the same amount - this ensure proper atomicity of reads.
View
@@ -5,30 +5,53 @@ namespace BufferTest
{
class Test
{
- public static int Main (string[] args)
- {
- int size = 32;
- byte[] array = new byte[size];
+ const byte TotalLength = 32;
-
- for (byte i = 0; i < size; i++) array[i] = i;
-
- Buffer.BlockCopy (array, 4, array, 5, 20);
-
- for (byte i = 0; i < size; i++) {
- byte expected;
- if (i > 4 && i < 25)
- expected = (byte)(i - 1);
+ public static byte Expected (byte dest, byte src, int len, byte i)
+ {
+ if (i >= dest && i < dest + len)
+ return (byte) (src + (i - dest));
else
- expected = i;
- if (array [i] != expected) {
- Console.WriteLine ("error at " + i + " expected " + expected + " but got " + array [i]);
- return 1;
+ return i;
+ }
+
+ public static bool TestMove (byte dest, byte src, int len)
+ {
+ byte[] array = new byte [TotalLength];
+ for (byte i = 0; i < TotalLength; ++i)
+ array [i] = i;
+ Buffer.BlockCopy (array, src, array, dest, len);
+ for (byte i = 0; i < TotalLength; ++i)
+ {
+ if (array [i] != Expected (dest, src, len, i)) {
+ Console.WriteLine ("when copying " + len + " from " + src + " to " + dest + ": expected ");
+ for (byte j = 0; j < TotalLength; ++j)
+ Console.Write ("" + Expected (dest, src, len, j) + " ");
+ Console.WriteLine ();
+ Console.WriteLine ("got");
+ for (byte j = 0; j < TotalLength; ++j)
+ Console.Write ("" + array [j] + " ");
+ Console.WriteLine ();
+ return false;
+ }
}
+ return true;
}
- return 0;
- }
+ public static int Main (string[] args)
+ {
+ bool failed = false;
+ for (byte i = 0; i < TotalLength; ++i) {
+ for (byte j = 0; j < TotalLength; ++j) {
+ byte max = (byte) (TotalLength - Math.Max (i, j));
+ for (byte l = 0; l < max; ++l) {
+ if (!TestMove (i, j, l))
+ failed = true;
+ }
+ }
+ }
+ return failed ? 1 : 0;
+ }
}
}

0 comments on commit a4dc171

Please sign in to comment.