chibi-scheme/lib/scheme
Alexei Lozovsky af60b8d937
Fix unaligned access in bytevector-{u,s}{16,32,64}-{ref,set!}
Native code implementing bytevector accessors uses the following access
pattern:

    *(intNN_t*)(base+offset)

This can result in so called "unaligned memory access" if the offset is
not a multiple of 2, 4, 8, or if the base address has not been allocated
at an aligned address (unlikely).

Most popular modern architectures--x86 and ARMs--allow unaligned memory
accesses on the instruction level but they are typically performed a bit
slower than properly aligned accesses.

On the other hand, there are architectures which do not allow unaligned
memory accesses. Each load or store of a value longer than 1 byte should
use properly aligned address on those architectures. That is, u16 should
be loaded from even addresses, s32 should only be stored at an address
which is a multiple of 4, and f64 (aka double) can be located only at
addresses which are multiple of 8. If the address is not aligned, CPU
raises an exception which typically results in the process being killed
by the operating system with a SIGBUS signal.

SPARC is one of those architectures which are strict with alignment. The
current access pattern in bytevector native code can result in unaligned
accesses, which in turn results in crashes. This issue has been found in
this way: Chibi test suite includes some tests for unaligned accesses
and it failed on SPARC.

In order to avoid unaligned accesses, loads and stores need to be
performed a bit differently, doing 'type punning' in a safe way, not
just casting pointers which breaks strict aliasing rules.

The most portable and efficient way to do this is to use memcpy().
Compilers know about this trick and generate very efficient code here,
avoiding the function call and using the most efficient instructions.
(Obviously, only when optimizations are enabled.)

That is, given

    static inline uint32_t ref_u32(const void* p) {
      uint32_t v;
      memcpy(&v, p, sizeof(v));
      return v;
    }

on x86 this will be compiled into a single "movl" instruction because
x86 allows unaligned accesses, similar with ARM where this becomes
a single "ldr" instruction. However, on RISC-V--another platform with
strict alignment rules--this code compiles into 4 "lbu" instructions
fetching 4 bytes, then some more arithmetic to stitch those bytes into
a single 32-bit value.
2020-11-30 16:46:44 +09:00
..
char fix case folding, update to unicode 13 2020-06-04 22:08:07 +09:00
mapping replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
time don't start thread checking for leap seconds if env var is unspecified 2018-12-28 23:40:55 +08:00
vector replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
base.sld let[rec]-syntax should not splice 2016-02-22 23:05:12 +09:00
bitwise.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
box.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
bytevector-test.sld fixing scheme bytevector for 32bit arch 2020-07-28 15:09:40 +09:00
bytevector.sld adding (scheme bytevector) 2020-05-31 23:24:51 +09:00
bytevector.stub Fix unaligned access in bytevector-{u,s}{16,32,64}-{ref,set!} 2020-11-30 16:46:44 +09:00
case-lambda.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
char.sld fix case folding, update to unicode 13 2020-06-04 22:08:07 +09:00
charset.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
comparator.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
complex.sld Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
cxr.scm Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
cxr.sld Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
define-values.scm Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
digit-value.scm Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
division.scm renaming centered/ balanced/ 2017-04-01 22:14:29 +09:00
division.sld renaming centered/ balanced/ 2017-04-01 22:14:29 +09:00
ephemeron.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
eval.sld Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
extras.scm error on recursive includes (issue #557) 2020-06-16 11:44:10 +09:00
file.sld Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
fixnum.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
flonum.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
generator.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
hash-table.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
ideque.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
ilist.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
inexact.scm Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
inexact.sld Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
lazy.sld make-promise is idempotent (issue #625) 2020-04-10 17:17:29 +09:00
list-queue.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
list.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
load.sld Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
lseq.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
mapping.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
misc-macros.scm guard should use raise-continuable (issue #661) 2020-06-19 17:48:29 +09:00
process-context.sld (chibi win32 process-win32): New library 2017-12-13 19:04:04 +09:00
r5rs.sld Update r5rs.sld 2016-04-07 16:36:19 +02:00
read.sld Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
red.sld extending (scheme red) 2018-01-24 23:54:09 +09:00
regex.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
repl.sld Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
rlist.sld extending (scheme red) 2018-01-24 23:54:09 +09:00
set.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
show.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
small.sld Adding (scheme process-context) to (scheme small). 2016-01-13 21:59:59 +09:00
sort.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
stream.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
text.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
time.c Win32: Port/Stub-out libraries 2017-11-06 04:10:28 +09:00
time.sld Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00
vector.sld replace define-library-alias with define-library + alias-for 2020-06-04 23:55:37 +09:00
write.sld Forgot to install regexp (patch from Lorenzo) 2015-01-26 08:06:59 +09:00