From db49143cdaa0ff3504531bd32297be9ecb9a2bc3 Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 12 Mar 2008 16:45:28 +0000 Subject: [PATCH] * configure.in (stdint.h): check if presence. * configure.in (uint32_t): check if defined. * string.c (hash): fix for portability. [ruby-dev:34020] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15760 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 8 ++++ configure.in | 14 ++++++- string.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++--- version.h | 6 +-- 4 files changed, 125 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05f8170fff..6487b72ead 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Thu Mar 13 01:45:25 2008 Nobuyoshi Nakada + + * configure.in (stdint.h): check if presence. + + * configure.in (uint32_t): check if defined. + + * string.c (hash): fix for portability. [ruby-dev:34020] + Wed Mar 12 17:33:34 2008 Nobuyoshi Nakada * object.c (rb_cstr_to_dbl): fix for a mere underscore. diff --git a/configure.in b/configure.in index c17821011f..a33b5a9fc7 100644 --- a/configure.in +++ b/configure.in @@ -582,7 +582,7 @@ AC_CHECK_HEADERS(stdlib.h string.h unistd.h limits.h sys/file.h sys/ioctl.h sys/ fcntl.h sys/fcntl.h sys/select.h sys/time.h sys/times.h sys/param.h\ syscall.h pwd.h grp.h a.out.h utime.h memory.h direct.h sys/resource.h \ sys/mkdev.h sys/utime.h xti.h netinet/in_systm.h float.h ieeefp.h pthread.h \ - ucontext.h intrinsics.h langinfo.h locale.h) + ucontext.h intrinsics.h langinfo.h locale.h stdint.h) dnl Check additional types. AC_CHECK_SIZEOF(rlim_t, 0, [ @@ -620,6 +620,18 @@ AC_CHECK_TYPES(struct timespec) AC_CHECK_TYPE(fd_mask, [AC_DEFINE(HAVE_RB_FD_INIT, 1)]) +test ${rb_cv_type_uint32_t+set} && ac_cv_type_uint32_t=yes +AC_CHECK_TYPE(uint32_t) +if test ${ac_cv_type_uint32_t} != yes; then + AC_CACHE_CHECK([unsigned 32bit int], + rb_cv_type_uint32_t, + [for type in short int long; do + AC_COMPILE_IFELSE(AC_LANG_BOOL_COMPILE_TRY([], [sizeof($type) == 4]), + [rb_cv_type_uint32_t=$type; break], []) + done]) + AC_DEFINE(uint32_t, $rb_cv_type_uint32_t) +fi + AC_CACHE_CHECK(for stack end address, rb_cv_stack_end_address, [rb_cv_stack_end_address=no for addr in __libc_stack_end _SEND; do diff --git a/string.c b/string.c index 71cc090859..e64d440b77 100644 --- a/string.c +++ b/string.c @@ -25,6 +25,10 @@ #include #endif +#if HAVE_STDINT_H +#include +#endif + VALUE rb_cString; VALUE rb_cSymbol; @@ -1685,6 +1689,13 @@ rb_str_concat(VALUE str1, VALUE str2) return rb_str_append(str1, str2); } +#if defined __i386__ || defined _M_IX86 || defined __ia64 +#define UNALIGNED_WORD_ACCESS 1 +#endif +#ifndef UNALIGNED_WORD_ACCESS +#define UNALIGNED_WORD_ACCESS 0 +#endif + /* MurmurHash described in http://murmurhash.googlepages.com/ */ unsigned int hash(const unsigned char * data, int len, unsigned int h) @@ -1694,22 +1705,106 @@ hash(const unsigned char * data, int len, unsigned int h) h += 0xdeadbeef; - while(len >= 4) { - h += *(unsigned int *)data; - h *= m; - h ^= h >> r; + if (len >= 4) { +#if !UNALIGNED_WORD_ACCESS + int align = (VALUE)data & 3; + if (align) { + uint32_t t = 0, d = 0; + int sl, sr, pack; - data += 4; - len -= 4; + switch (align) { +#ifdef WORDS_BIGENDIAN + case 1: t |= data[2]; + case 2: t |= data[1] << 8; + case 3: t |= data[0] << 16; +#else + case 1: t |= data[2] << 16; + case 2: t |= data[1] << 8; + case 3: t |= data[0]; +#endif + } + +#ifdef WORDS_BIGENDIAN + t >>= (8 * align) - 8; +#else + t <<= (8 * align); +#endif + + data += 4-align; + len -= 4-align; + + sl = 8 * (4-align); + sr = 8 * align; + + while (len >= 4) { + d = *(uint32_t *)data; +#ifdef WORDS_BIGENDIAN + t = (t << sr) | (d >> sl); +#else + t = (t >> sr) | (d << sl); +#endif + h += t; + h *= m; + h ^= h >> r; + t = d; + + data += 4; + len -= 4; + } + + pack = len < align ? len : align; + d = 0; + switch (pack) { +#ifdef WORDS_BIGENDIAN + case 3: d |= data[2] << 8; + case 2: d |= data[1] << 16; + case 1: d |= data[0] << 24; + case 0: + h += (t << sr) | (d >> sl); +#else + case 3: d |= data[2] << 16; + case 2: d |= data[1] << 8; + case 1: d |= data[0]; + case 0: + h += (t >> sr) | (d << sl); +#endif + h *= m; + h ^= h >> r; + } + + data += pack; + len -= pack; + } + else +#endif + { + do { + h += *(uint32_t *)data; + h *= m; + h ^= h >> r; + + data += 4; + len -= 4; + } while (len >= 4); + } } switch(len) { +#ifdef WORDS_BIGENDIAN + case 3: + h += data[2] << 8; + case 2: + h += data[1] << 16; + case 1: + h += data[0] << 24; +#else case 3: h += data[2] << 16; case 2: h += data[1] << 8; case 1: h += data[0]; +#endif h *= m; h ^= h >> r; }; diff --git a/version.h b/version.h index fb3967317e..032939d883 100644 --- a/version.h +++ b/version.h @@ -1,7 +1,7 @@ #define RUBY_VERSION "1.9.0" -#define RUBY_RELEASE_DATE "2008-03-12" +#define RUBY_RELEASE_DATE "2008-03-13" #define RUBY_VERSION_CODE 190 -#define RUBY_RELEASE_CODE 20080312 +#define RUBY_RELEASE_CODE 20080313 #define RUBY_PATCHLEVEL 0 #define RUBY_VERSION_MAJOR 1 @@ -9,7 +9,7 @@ #define RUBY_VERSION_TEENY 0 #define RUBY_RELEASE_YEAR 2008 #define RUBY_RELEASE_MONTH 3 -#define RUBY_RELEASE_DAY 12 +#define RUBY_RELEASE_DAY 13 #ifdef RUBY_EXTERN RUBY_EXTERN const char ruby_version[];