ruby-trunk-changes r42655 - r42672

今日は Process.clock_gettime に関する実装の最適化やリファクタリング、Array の共有化にまつわる RGenGC の不具合修正、64bit 版 Windows での win32ole の型に関する修正などがありました。

nobu:r42655 2013-08-23 11:07:20 +0900

win32/Makefile.sub で生成する config.h に SIZEOF_CLOCK_T の定義を追加しています。 r42651 で configure でチェックするようにしたので Windows 版も追随しています。

svn:r42656 2013-08-23 11:07:25 +0900

version.h の日付更新。

nobu:r42657 2013-08-23 11:17:25 +0900

process.c の rb_clock_gettime() で VC での警告を除去するため明示的なキャストを追加しています。

ko1:r42658 2013-08-23 11:27:32 +0900

Array を dup した時など同じバッファを共有するときに作成される Array オブジェクトの共有数が 1 であることをチェックするマクロ ARY_SHARED_OCCUPIED() というマクロを array.c に追加してこれを使うようにリファクタリングしています。

nobu:r42659 2013-08-23 17:17:43 +0900

ext/win32ole/win32ole.c の ole_method_docinfo_from_type() という関数の戻り値が誤って VALUE になっていたので HRESULT に修正しています。

nobu:r42660 2013-08-23 17:17:47 +0900

拡張ライブラリ win32ole の WIN32OLE_TYPELIB#name と WIN32OLE_TYPELIB#path で WC2VSTR() で生成した文字列をさらにコピーしていたのでそのまま返すようにしています。 cWIN32OLE_enc へのエンコーディング変換が不要だったということでしょうか。

nobu:r42661 2013-08-23 17:17:50 +0900

拡張ライブラリ win32ole の x64-mswin64 でのコンパイル警告除去のため size_t を渡す rb_str_cat() や rb_enc_str_new() を使うかわりに、サイズを渡さない rb_str_cat2() や rb_str_new_cstr() を使うように書き換えています。

nobu:r42662 2013-08-23 17:17:53 +0900

size_t と long のサイズが異なる環境での対応として拡張ライブラリ win32ole の WIN32OLE#method_missing のメソッド名が long で表現できるサイズ以上だったら例外を発生させるようにして、キャストを追加しています。

nobu:r42663 2013-08-23 17:17:56 +0900

拡張ライブラリ win32ole でもうひとつコンパイラ警告除去のために明示的なキャストを追加しています。

nobu:r42664 2013-08-23 17:17:59 +0900

拡張ライブラリ win32ole の ole_wc2mb() という文字列の変換関数にバッファの確保に使う関数を引数で指定できるようにして ole_wc2mb_alloc() という関数として切り出し、ole_wc2vstr() でこれを使いまわして、こちらでは String オブジェクトのバッファにそのまま格納するようにして余分なバッファの利用を減らしています。

ko1:r42665 2013-08-23 18:42:18 +0900

dup した時などに共有する配列を作るのですが、r37581, r37582, r37583, r37584 あたりで入った、Array#push,unshift などで共有 Array を参照している Array が1つしか無い時に共有されている(と言ってもひとつからしか参照されていないのですが) Array を直接操作することで不要なコピー等を省く最適化のため、共有されている配列の操作への Write Barrier の挿入位置が適切でなくなる場合があるという問題があり、共有配列は shady にするようにしています。また共有配列を作る時のバッファのコピー等で不要な Write Barrier つきの操作をしていたのをやめています。

akr:r42666 2013-08-23 19:44:33 +0900

process.c にユークリッドの互除法で最大公約数を求める関数 gcd_ul() を導入して クロック数などを double で目的の単位に計算する時に事前に除算の分子、分母を約分しておくことで先に分子が大きな数になるのを防いでいるみたいです。 double で絶対値が大きくなって精度が落ちるのを避けるためではないかと思われます。

akr:r42667 2013-08-23 20:53:12 +0900

r42666 で除算する数の設定に間違っていたのを修正しているのと、変数の宣言を必要なブロック内に移動する変更です。

akr:r42668 2013-08-23 21:06:02 +0900

r42666 で導入した関数群で使う整数の型を timetick_int_t という型を利用するようにしています。 long long が利用できる場合は long long を使うようにしてオーバフローしにくくしているようです。

akr:r42669 2013-08-23 21:46:06 +0900

r42666 と同様に Process.clock_gettime の戻り値を目的の単位に計算するところで、(a*b)/(c*d) のような形の式で分子の因数と分母の因数全てについて先に約分するようにすることで、より効果的に乗算の結果の絶対値を減らすようにしています。

nobu:r42670 2013-08-23 22:07:59 +0900

r42651 の追加で configure で clock_t のサイズをチェックする時に time.h を include するようにしています。

nobu:r42671 2013-08-23 22:12:46 +0900

process.c の初期化時に呼ばれる関数 Init_process() で rb_intern() を rb_intern_const() にすりかえるようにマクロ定義を追加しています。 rb_intern() は gcc 拡張が使える時には引数が定数の時に複数回評価しても static 変数に結果をキャッシュするようなマクロとして定義されるのですが、これを無効にするようにしているようです。初期化時にしか呼ばれないのでキャッシュが無駄だから不要なメモリ領域を使わないようにするためかと思います。

akr:r42672 2013-08-23 22:25:12 +0900

process.c の rb_clock_gettime() で警告によりコンパイルエラーになっていたところに明示的なキャストを追加しています。