From: nobu.nakada@... Date: 2002-03-12T14:26:58+09:00 Subject: [ruby-dev:16339] Re: Oni Guruma imported into our repository なかだです。 At Tue, 12 Mar 2002 13:27:41 +0900, K.Kosako wrote: > > alignmentの制約の厳しいアーキテクチャでは、これはSIGBUSかなにか > > になりそうな気がします。 (snip) > GNU regexでも整数の読み書きでserializeしているので、 > まずい環境もあるのかなあと思っていたのですが、 > やはり問題ですか。 mc68000はさすがにもう使われてないでしょうが(X68kなら現役?)、一 般にRISCではalignmentされてない(ハーフ)ワードアクセスはできませ ん。エミュレートしてくれるOSもありますが、速度的なペナルティは 桁違いです。 > 修正するにしても、僅かでも速度を落としたくないので、 > 問題になるアーキテクチャでだけserializeするように > コンパイル時点で判定できれば良いのですが、そのような > 方法はないでしょうか? コンパイラによりますが、たとえばgccなら__i386__、VCなら_M_IX86 というプリプロセッサマクロが定義されています。こういったもので チマチマと判定してやるしかないような気がします。 #if defined __i386__ || defined _M_IX86 /* intel x86 */ # define UNALIGNED_WORD_ACCESS 1 #elif defined __mc68020__ /* motorola 68020 or later */ # define UNALIGNED_WORD_ACCESS 1 #endif #ifdef UNALIGNED_WORD_ACCESS #define GET_RELADDR_INC(addr,p) do{\ addr = *((RelAddrType* )(p));\ (p) += SIZE_RELADDR;\ } while(0) #else #define GET_2BYTE_INC(addr, p) do{\ addr = (unsigned short)((UChar)(p)[0] << CHAR_BIT) | (UChar)(p)[1];\ (p) += 2;\ } while(0) #define GET_4BYTE_INC(addr, p) do{\ addr = (unsigned int)((UChar)(p)[0] << 3*CHAR_BIT) | \ (unsigned int)((UChar)(p)[1] << 2*CHAR_BIT) | \ (unsigned int)((UChar)(p)[2] << CHAR_BIT) | \ (UChar)(p)[3];\ (p) += 2;\ } while(0) #define GET_RELADDR_INC(addr,p) GET_2BYTE_INC(addr, p) #endif あるいは、configureでSIGBUSをトラップすれば、上記のエミュレート するようなシステムでも判定できるかも知れませんが、実際にそうい う環境は使ったことがないのでよく分かりません。 AC_CACHE_CHECK(for unaligned word access, rb_cv_unaligned_word_access, [AC_TRY_RUN([ #include #include int main() { char buf[2*sizeof(int)]; signal(SIGBUS, exit); *(int volatile *)(buf+1) = 0; return *(int volatile *)(buf+1); } ], rb_cv_unaligned_word_access=yes, rb_cv_unaligned_word_access=no, rb_cv_unaligned_word_access=no)]) -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦