ruby-trunk-changes r65806 - r65887

今日は主に Fiber の実装にアセンブリで書いた coroutine 実装を使うようにする変更がありました。
今日は全部で 82 commits になりました。

nobu: r65806 2018-11-19 22:21:48 +0900

r65805 のさらに続きで configre.ac の extra_warning という変数名を extra_warnflags に改名しています。うん、ちょっと気になってたのでした。

k0kubun: r65807 2018-11-19 22:33:07 +0900

MJIT の子プロセスでの有効化に関連して fork 前に MJIT worker thread を止める時に割り込み処理しないようにするため mjit.c の stop_worker() に引数を追加して、RUBY_VM_CHECK_INTS() の実行有無を指定できるようにして before_fork_ruby() からは実行しない指定で呼ぶようにしています。 [ruby-core:89877] [Bug #15320]

nobu: r65808 2018-11-19 22:43:44 +0900

Solaris の shell をサポートするため tool/mjit_archflag.sh で indent という変数に空白をセットする時にクオートした空白を使うようにしています。 [ruby-dev:50669] [Bug #15319]

k0kubun: r65809 2018-11-19 22:48:07 +0900

internal.h に MJIT が無効になるようにビルドされた時にも mjit_pause_without_ints() という inline 関数の定義を置いておくようにしています。

k0kubun: r65810 2018-11-19 23:00:49 +0900

ruby --help や configure --help などのメッセージで MJIT という名前を使っているところで単に JIT とするようにしています。 MJIT は実装の名前であって機能名(?)としては単に JIT と呼ぶことにしているようです。

k0kubun: r65811 2018-11-19 23:21:55 +0900

appveyor.yml で Bignum のテストを -j なしの make test-all のほうに移動しています。

nobu: r65812 2018-11-20 00:00:35 +0900

関数マクロ rb_scan_args_verify() は値を利用しないことを明示するため定義に (void) のキャストを追加しています。

svn: r65813 2018-11-20 00:00:37 +0900

version.h の日付更新。

k0kubun: r65814 2018-11-20 07:10:12 +0900

r65807 の mjit.c の stop_worker() に割り込み処理させないフラグを追加する変更は効果がなかったそうで revert されています。とりあえず失敗するテストは skip するようにしています。

k0kubun: r65815 2018-11-20 08:05:11 +0900

gcc 8 の -fcf-protection というオプションをつけていると MJIT で(つまり共有ライブラリで?) __builtin_longjmp() を使った大域脱出がエラーになるそうで、コンパイラが -fcf-protection オプションをサポートする時に __builtin_longjmp() が使えないように判定するように configre.ac を修正しています。 [ruby-core:89812] [Bug #15307]

k0kubun: r65816 2018-11-20 08:28:30 +0900

r65814 で skip するようにしたテストの skip 時のメッセージの修正。テスト自体は Process.daemon のテストですけどその前に IO.popen で fork する時にハングアップするらしいので、skip 理由が正しくわかるようにしています。

k0kubun: r65817 2018-11-20 09:04:19 +0900

引き続き fork 前の MJIT worker 停止のハングアップ修正。before_fork_ruby() で MJIT worker thread を停止していたのをやめて呼び元の rb_fork_ruby() や rb_daemon() から直接 mjit_pause() や mjit_resume() を呼ぶようにしています。fork 時には SIGCHLD の独自処理で導入された子プロセス処理も一時的に停止されているので before_fork_ruby() の位置では worker thread が正常に停止できない可能性があったみたいです。waitpid 処理を止める前に mjit_pause() し、再開後に mjit_resume() するようにしています。 [ruby-core:89877] [Bug #15320]

k0kubun: r65818 2018-11-20 09:07:36 +0900

thread.c の rb_thread_atfork() で mjit_child_after_fork() を呼んでるところのコメントを少し変更しています。

nobu: r65819 2018-11-20 09:39:07 +0900

r65815 の続きで -fcf-protection のオプションが実際に指定されているかどうかをチェックするようにしています。

k0kubun: r65820 2018-11-20 10:28:43 +0900

bootstraptest の Thread#join のテストが Windows 環境で通らないことがあるそうで bootstraptest/pending.rb に移動しています。socket の read でエラー? 別のテストの後始末漏れとかですかね。

k0kubun: r65821 2018-11-20 11:16:30 +0900

r65820 で Thread#join のテストを bootstraptest/pending.rb に移動してたのを revert して、bootstraptest/runner.rb で IO#read_nonblock から IO::WaitReadable が発生した時にリトライするような修正を入れています。 socket がデフォルトで nonblock になったので対応が必要になったんですね。

shugo: r65822 2018-11-20 12:01:55 +0900

標準添付ライブラリ monitor で mon_initialize が二重に呼ばれた時にインスタンス変数 @mon_mutex をチェックして例外発生させるようにしています。 [ruby-core:88504] [Feature #15000]

svn: r65823 2018-11-20 12:01:57 +0900

r65822 の新規追加ファイルの svn property 設定。 monitor ってテストがなかったんですよね。

kazu: r65824 2018-11-20 12:03:01 +0900

r65802 で IO#ungetbyte に範囲外の整数を渡した時の例外メッセージの指示子 %d の間に空白が入ってしまっていたのを修正。

kazu: r65825 2018-11-20 12:03:02 +0900

mjit.c のコメントの typo 修正。

nobu: r65826 2018-11-20 12:07:46 +0900

defs/gmake.mk に引数つきの rdoc というターゲットを追加して ri コマンドでドキュメントを検索できるようにしています。

shugo: r65827 2018-11-20 12:56:51 +0900

r65822 の monitor の修正で rubyspec が失敗するそうで revert しています。わざわざ mon_initialize を2回呼んだ時のテストがあったのか、と思ったけどよくみると initialize_copy からコピーしたオブジェクトで再初期化する時に mon_initialize を呼んだ時なので、この時は再度 Mutex を作るのが正しそう。なるほどー。難しいですね。

shyouhei: r65828 2018-11-20 13:51:09 +0900

数値を +1 する最適化命令 opt_succ の実装 vm_opt_succ() で VALUE の値をそのまま整数演算しているところで overflow する可能性があったので fix_succ() という関数を導入して 0xFF...FF の時と 0x7F...FF の時(Bignum になる)の時を分岐して明示的に処理するようにしています。

usa: r65829 2018-11-20 14:18:28 +0900

r65821 で bootstraptest の assert_finish() で IO::WaitReadable の時にリトライするようにしていましたが、この begin 節(後置 while つき)の外にも while ループがあってタイムアウトまで繰り返すようになっているので、Errno::EAGAIN が発生した時と同様に単に break するようにしています。

shyouhei: r65830 2018-11-20 14:58:12 +0900

r65828 のインデントの修正。

nobu: r65831 2018-11-20 15:13:42 +0900

defs/gmake.mk に test_???.rb とか test/??? というパラメーターつきターゲットを追加して、指定されたファイルのテストのみ実行するのを簡単に書けるように(?)しています。

normal: r65832 2018-11-20 16:27:28 +0900

rb_reserved_fd_p() で負の fd (不正な値)を渡された時に先にチェックして 0 (偽)を返すようにしています。中で比較してる timer_thread.low とかが -1 で初期化されてるので、これらをセットする前に呼ばれると誤って真を返す恐れがあるので、ということらしい。

nobu: r65833 2018-11-20 18:29:37 +0900

make btest と make btest-ruby の実行時にテストに BTESTS という環境変数の値をオプションとして渡すようにしています。

samuel: r65834 2018-11-20 18:59:10 +0900

coroutine/ というサブディレクトリに amd64/arm32/arm64/win32/win64 などのアーキテクチャ毎にアセンブラで書かれた coroutine_transfer という関数の実装を追加してこれを利用した fiber_setcontext() でのコンテキスト切り替えを行うようにしています。新しくコミッタになった(といってもコミット権の付与はだいぶ前だったそうですが) samuel によるコミットです。たぶん git で積み上げてたコミットをそのまま git-svn で入れたみたいなので、これ以降 fiber の再実装まわりのコミットが大量に続きます。このコミットもトップレベルに fiber_benchmark.rb というファイルがポンと置かれてたりするので整理してない試行錯誤がそのまま入ってると思われます。
また .gitignore の r55587 で追加されてた *.s を消してますが、これはコンパイラオプションの --save-temps=obj をつけた時の中間生成物を無視する用らしいので、こういうの(特定のファイル名以外のある拡張子のファイルは無視する)はどう書けるのかなぁ。

samuel: r65835 2018-11-20 18:59:14 +0900

r65834 ではソースは用意されているものの amd64 版固定で使うようになっていたので configure で amd64 版の時に coroutine 実装のヘッダを FIBER_USE_COROUTINE マクロに定義しておくようにしています。まだこの時点でも他のアーキテクチャはサポートされてなさそう。

samuel: r65836 2018-11-20 18:59:18 +0900

fiber_benchmark.rb を削除して書き直したベンチマークを benchmark/bm_vm2_fiber_chain.rb に追加しています。

svn: r65837 2018-11-20 18:59:19 +0900

r65836 の行末の空白を除去。

svn: r65838 2018-11-20 18:59:20 +0900

r65836 の新規追加ファイルの svn property 設定。

samuel: r65839 2018-11-20 18:59:23 +0900

amd64 版の coroutine_transfer() の戻り値設定の命令がコメントアウトされてたので戻しています。

samuel: r65840 2018-11-20 19:06:54 +0900

Makefile.in の .s ファイルのコンパイルのルールでビルドディレクトリを外にした時のために mkdir するコマンドを追加しています。

samuel: r65841 2018-11-20 19:06:58 +0900

ベンチマークスクリプト benchmark/bm_vm2_fiber_chain.rb の Fiber 生成部分をメソッドに切り出しています。コードの複雑度の問題で、とか書いてるのでなにか静的解析ツールを使ってチェックしてるのかも。

svn: r65842 2018-11-20 19:06:59 +0900

r65841 の行末の空白除去。空行でインデントを入れる設定になってるみたいですね。

samuel: r65843 2018-11-20 19:09:53 +0900

r65841 のベンチマークスクリプトリファクタリングで切り出したメソッドで未定義変数参照になってしまっていたので引数で引き回すように修正。

svn: r65844 2018-11-20 19:09:55 +0900

r65843 の行末の空白除去。

samuel: r65845 2018-11-20 19:13:51 +0900

benchmark/bm_vm2_fiber_chain.rb を benchmark/vm2_fiber_chain.rb に改名しています。

samuel: r65846 2018-11-20 19:13:55 +0900

cont_free() の変数 fib に const を付けてましたが const なしの引数に渡す必要があったので const を削っています。

samuel: r65847 2018-11-20 19:13:59 +0900

coroutine/ に x86 版の coroutine_transfer() の実装を追加しています。

svn: r65848 2018-11-20 19:14:03 +0900

r65847 のインデントのタブを空白に展開。

svn: r65849 2018-11-20 19:14:03 +0900

r65847 の新規追加ファイルの svn property 設定。

samuel: r65850 2018-11-20 19:16:29 +0900

coroutine/ の配下のヘッダの行コメントを /* */ のコメントへの変更とアセンブリソースファイルのコメントの typo 修正。

samuel: r65851 2018-11-20 19:16:34 +0900

benchmark/ 配下のベンチマークスクリプトは明示的に Benchmark を使って計測する必要はないので、他のスクリプトと同様に計測したい処理のみ書くようにしています。

svn: r65852 2018-11-20 19:16:35 +0900

r65851 の行末の空白除去。

samuel: r65853 2018-11-20 19:16:41 +0900

coroutine/*/Context.h で定義している関数の宣言に使う COROUTINE マクロに noreturn の attribute をつけうようにしています。

samuel: r65854 2018-11-20 19:16:45 +0900

Makefile.in の *.s ファイルのルールのコマンドにデバッグ用に実行するコマンドを echo で出力するコマンドを追加しています。

samuel: r65855 2018-11-20 19:16:49 +0900

r65854 の続きで *.s ファイルのアセンブルに $(AS) でなく $(CC) を利用するようにしてみています。

samuel: r65856 2018-11-20 19:16:54 +0900

coroutine/*/Context.h の coroutine_start() の宣言に COROUTINE() マクロを利用するようにしています。定義したけど使ってなかったのか。

samuel: r65857 2018-11-20 19:17:00 +0900

coroutine/ の配下のファイルの空行とかの整形のみ。

samuel: r65858 2018-11-20 19:17:04 +0900

FIBER_USE_COROUTINE が未定義で coroutine を使わないバージョンの実装を修正。足りない関数定義があったみたいです。

samuel: r65859 2018-11-20 19:17:08 +0900

benchmark/vm2_fiber_chain.rb をまた benchmark/fiber_chain.rb という名前に変更しています。

samuel: r65860 2018-11-20 19:17:12 +0900

行末の空白除去。一気に commit したからか直前じゃないコミットの変更に対する変更みたいですね。

samuel: r65861 2018-11-20 19:17:17 +0900

coroutine/*/Context.h で coroutine_initialize() と coroutine_destroy() の inline 関数の定義に static を付けるようにしています。duplicate symbol になるのを防ぐためとのこと。

svn: r65862 2018-11-20 19:17:19 +0900

r65861 のインデントのタブを空白に展開。

samuel: r65863 2018-11-20 19:17:24 +0900

cont.o から coroutine/*/Context.h への依存関係を追加しています。

samuel: r65864 2018-11-20 19:17:27 +0900

Makefile.in のコマンドを echo で出力するデバッグ用のコマンドを削除。まだ mkdir するコマンドは $(Q) をつけて変数 V の指定がなかったら実行コマンドをエコーバックしないようにしています。

samuel: r65865 2018-11-20 19:17:31 +0900

configure で coroutine 版の実装を使うのは Linux のみに限定しています。とコミットコメントにはあるけど x で終わる os 名なら使うというふうになっています。*nix 系とか思ってしまうけど x で終わる os 名確かに他にないかも…。

samuel: r65866 2018-11-20 19:17:35 +0900

とか思ってたら r65865 の続きで coroutine を使う条件の os 名は linux と明記するようにしています。なぜか mingw32 で amd64 を使ってしまうそうです。ふーむなぜだろう。

samuel: r65867 2018-11-20 19:17:39 +0900

coroutine/win{32,64} の実装を修正しています。 Windows TIB のサポートとのこと。TIB = Thread Information Block かな? それがなんなのかは知らないのですが。

samuel: r65868 2018-11-20 19:17:44 +0900

coroutine 実装の x64-mingw32 サポートのため configure の判定を追加(なぜか darwin での amd64 の判定も追加。darwin は最初にあったような気がしたけど)。また coroutine/win{32,64}/ の実装も修正しています。

samuel: r65869 2018-11-20 19:17:49 +0900

coroutine/win64/Context.h のコメント行に差分があるんですがどこかわからない。改行コードの変更かも。

samuel: r65870 2018-11-20 19:17:52 +0900

configure.ac のカンマが足りてなかったのを修正。

samuel: r65871 2018-11-20 19:17:56 +0900

configure.ac の x64-mingw32 の coroutine 対応の typo 修正。

samuel: r65872 2018-11-20 19:18:01 +0900

coroutine/win{32,64}/Context.h の構造体 coroutine_context の typedef 追加。

samuel: r65873 2018-11-20 19:18:04 +0900

Windows 版で Fiber のスタック領域確保/解放に malloc/free を使うようにしています。使ってなかったっけ、と思ったけど前から Windows 以外では mmap(2) を使ってましたね。そうかー Windows の時は native の Fiber を使ってたんだっけ。

samuel: r65874 2018-11-20 19:18:08 +0900

cont.c の preprocessor の分岐の変更ですが、すぐ次で再修正されています。

samuel: r65875 2018-11-20 19:18:12 +0900

cont.c の fiber_machine_stack_alloc() などの関数の定義を FIBER_USE_NATIVE から FIBER_ALLOCATE_STACK というマクロの定義で分岐するようにしています。coroutine を使う時もそうでない時も Windows 以外では使うので。 fiber_setcontext() も分岐内に入ってるっぽいけどこれはいいのかな。

samuel: r65876 2018-11-20 19:18:16 +0900

coroutine/win64/Context.s を追加。あれ win64 は最初からあったような、と思いましたがそれは Context.asm で、これは GAS スタイルで書かれたもので、MinGW 向けで gcc でビルドできるようにするためみたいです。

svn: r65877 2018-11-20 19:18:17 +0900

r65876 の新規追加ファイルの svn property 設定。

samuel: r65878 2018-11-20 19:18:21 +0900

やっぱり r65875 の preprocessor の分岐は範囲が広すぎたみたいで、fiber_machine_stack_alloc() の定義部分だけ FIBER_ALLOCATE_STACK でコントロールするように修正しています。

samuel: r65879 2018-11-20 19:18:25 +0900

coroutine の Windows 版(mswin) のビルド用のルールを win32/Makefile.sub に追加しています。

nobu: r65880 2018-11-20 19:29:03 +0900

  • .s や *.asm のビルド時に mkdir するルールを拡張子の一般的なルールから context/* のルールとして common.mk に定義しなおしています。

nobu: r65881 2018-11-20 19:43:41 +0900

cont.c の fiber_entry() の宣言に static を追加しています。

nobu: r65882 2018-11-20 19:51:27 +0900

r65878 で修正してた cont.c での preprocessor の分岐ですが FIBER_USE_NATIVE の定義有無ではなく、定義されている値が 0 かそれ以外かで分岐するのが正しいので #if を使うように修正。また #endif のコメントが修正漏れていたのでこちらも修正しています。

k0kubun: r65883 2018-11-20 20:18:59 +0900

mjit_worker.c の mjit_worker() で iseq->body->jit_func にセットする時に GC 中だと SEGV する恐れがあるみたいで、その前で GC 中だったら終了するまで待つコードを追加しています。うーん、どういう時にまずいのか思いつかない。

k0kubun: r65884 2018-11-20 20:24:30 +0900

r65880 の coroutine/* のビルドのための mkdir コマンドのルール変更で Travis-CI のビルドでうまくディレクトリが作れてなかったみたいで Makefile.in の *.s -> *.o のルールに mkdir を復活させています。

nobu: r65885 2018-11-20 20:45:13 +0900

common.mk で Context.s を直書きしてたのを拡張子に $(ASMEXT) を使うようにして、Makefile.in での ASMEXT の定義を S から s に変更しています。

k0kubun: r65886 2018-11-20 21:01:18 +0900

AppVeyor で大きな Array を使うテストがメモリが足りなくて動かないようなので exclude するテストに追加しています。

nobu: r65887 2018-11-20 21:02:29 +0900

r65880 の再修正。 r65884 で coroutine/*/ のビルド時の mkdir を復活さてましたがまた消して、coroutine/ の下の amd64 に決め打ちで書いてたルールをアーキテクチャ毎のディレクトリを指定するように変数を使うようにしているようです。