Skip to content

Commit 7d4d675

Browse files
committed
[WIP] Fix O3+bus errors by assigning memory range with memcpy+new
This patch is to resolve bus errors in case of the O3 of clang (issue #5844). Note that we cannot use malloc library call "clib deprecates" of ./src/inc/clrhost.h. When we enable the -O2/-O3 optimization levels of the clang language (from clang 3.5 to latest version that was released on Jun-13-2016), we have got the +3000 BUS Errors from the coreCLR's unit tests. We can easily monitor SIGBUS signals (e.g., "misaligned memory access") with /proc/cpu/alignment facility of kernel-space. Using "echo 2 > /proc/cpu/alignment" makes Linux kernel fixes theproblems but the performance of the application will be degraded. * source: http://lxr.free-electrons.com/source/Documentation/arm/mem_alignment According to ARM information center(infocenter.arm.com), By default, the ARM compiler expects normal C and C++ pointers to point to an aligned word in memory. A type qualifier __packed is provided to enable unaligned pointer access. If you want to define a pointer to a word that can be at any address (that is, that can be at a non-natural alignment), you must specify this using the __packed qualifier when defining the pointer: __packed int *pi; // pointer to unaligned int However, clang/llvm does not support the __packed qualifier such as __attribute__((packed)) or __attribute__((packed, aligned(4))) In -O0 (debugging) the innermost block is emitted as the following assembly, which works properly: ldr r1, [r0, dotnet#24] ldr r2, [r0, dotnet#20] In -O2 (release) however the compiler realizes these fields are adjacent and generates this assembly: ldrdeq r2, r3, [r0, dotnet#20] Unfortunately ldrdb instruction always generates an alignment fault (in practice). It seems that clang uses ldrb instructions algthough Gcc uses ldr because armv7 supports unalign ldr instruction. Basically, RISC-based ARM architecture requires aligned access with 4byte reads. So, let's use memcpy(2) in into a properly aligned buffer instead of the packing attribute. Note: If architecture (e.g., linux/arm emulator) does not support unaligned ldr, this issue will be not generated with -O2/-O3 optimization levels. * source: Indicating unaligned access to Clang for ARM compatibility http://stackoverflow.com/questions/9185811/indicating-unaligned-access-to-clang-for-arm-compatibility * source: How does the ARM Compiler support unaligned accesses? http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html Signed-off-by: Geunsik Lim <geunsik.lim@samsung.com>
1 parent d4fc9b7 commit 7d4d675

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

src/jit/compiler.hpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2121

2222
#include "compilerbitsettraits.hpp"
2323

24+
#include <cstdlib>
25+
2426
/*
2527
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2628
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -759,11 +761,21 @@ inline
759761

760762
inline
761763
signed __int32 getI4LittleEndian(const BYTE * ptr)
762-
{ return *(UNALIGNED signed __int32*)ptr; }
764+
{
765+
signed __int32 *buffer = new signed __int32;
766+
if (buffer)
767+
memcpy(buffer, ptr, 4); // 4 bytes
768+
return *buffer;
769+
}
763770

764771
inline
765772
signed __int64 getI8LittleEndian(const BYTE * ptr)
766-
{ return *(UNALIGNED signed __int64*)ptr; }
773+
{
774+
signed __int64 *buffer = new signed __int64;
775+
if (buffer)
776+
memcpy(buffer, ptr, 8); // 8 bytes
777+
return *buffer;
778+
}
767779

768780
inline
769781
float getR4LittleEndian(const BYTE * ptr)

0 commit comments

Comments
 (0)