色々良かった。
個人的に印象に残ったのは、首藤さんのJITの話。「最近はドロドロとした最適化は必要なくなってきた」とかいうような話を底辺で支えてるのは、ソフトウェア的に一番ドロドロとした技術なんだなー、とか、そういうようなことを。
色々良かった。
個人的に印象に残ったのは、首藤さんのJITの話。「最近はドロドロとした最適化は必要なくなってきた」とかいうような話を底辺で支えてるのは、ソフトウェア的に一番ドロドロとした技術なんだなー、とか、そういうようなことを。
使った資料置いときます。
http://morihyphen.hp.infoseek.co.jp/g++eh/page.html
宣伝が邪魔なら
http://morihyphen.hp.infoseek.co.jp/g++eh/b20-g++eh.zip
ネタばらし、というのを嫌う人もいるらしいのだけど、僕はそういうのを書いたり読んだりするのが好きなんで適当に。
ここ何年か、ネタをやる度に失敗し続けてたので、「こんなネタでいいのか…?」とか、非常に心配だったんだけど、会場の雰囲気が良かったので、まあなんとかなった。
プロジェクタに映らなかったのは謎。マウスの挙動を見る限りウィンドウは出てたように見えたんだけど。結局あれはWindowsで。屈辱。
クールビズは当日の朝思い付いた。「w_oは非推奨です」をやる予定だったんだけど、微妙だと思ってたのでクールビズを採用。
「とゆーのは全部嘘です」は最初に思い付いたネタだったかな…あー、「キャッチボールはできません」のほうが先だったかもしれない。
僕には説明できないので適当に飛ばしたとこその1。「unwindは何」の「色々仕組み」。
コードをちょびちょび説明するのをどうしようかな…って悩んでたんだけど、方法を思い付かなかったので「読めません」。で済ますことに。
僕には説明できないので適当に飛ばしたとこその2。DWARF2全体的に。
プログラミング言語DWARF2は外部との入出力の部分が非常に弱いので、そこらへんが厳しい…かもしれない。
「Cで捕まえる」のコードは、
extern void throw_func( void ); void func() { asm(".region_begin:"); throw_func(); asm(".region_end:"); puts("kokoniha konai"); asm(".handler_begin:"); puts("catch!!!!"); asm(".handler_end:"); } asm(".func_end:"); asm("\t\n" "\t.size _Z5func3v, .-_Z5func3v\n" "\t.section .gcc_except_table\n" "\t.align 4\n" ".func_lsda:\n" "\t.byte 0xff # @LPStart format (omit)\n" "\t.byte 0x0 # @TType format (absolute)\n" "\t.uleb128 .ttd_end - .ttd_start # @TType base offset\n" ".ttd_start:\n" "\t.byte 0x1 # call-site format (uleb128)\n" "\t.uleb128 .call_site_end-.call_site_begin # Call-site table length\n" ".call_site_begin:\n" "\t.uleb128 .region_begin - func # region 0 start\n" "\t.uleb128 .region_end-.region_begin # length\n" "\t.uleb128 .handler_begin - func # landing pad\n" "\t.uleb128 0x1 # action\n" ".call_site_end:\n" "\t.byte 0x1 # Action record table\n" "\t.byte 0x0\n" "\t.align 4\n" "\t.long _ZTIi\n" ".ttd_end:\n" "\t\n"); __asm__ ( "\t.section .eh_frame, \"a\", @progbits\n" "\t.cie:\n" "\t.long .cie_end-.cie_begin\n" "\t.cie_begin:\n" "\t.long 0\n" "\t.byte 1\n" "\t.ascii \"zPL\\0\" # CIE Augmentation\n" "\t.uleb128 1\n" "\t.sleb128 -4\n" "\t.byte 8\n" "\t.uleb128 0x6 # Augmentation size\n" "\t.byte 0x0 # Personality (absolute)\n" "\t.long __gxx_personality_v0\n" "\t.byte 0x0 # LSDA Encoding (absolute)\n" "\t.uleb128 0\n" "\t.byte 0xc # DW_CFA_def_cfa\n" "\t.uleb128 0x4\n" "\t.uleb128 0x4\n" "\t.byte 0x88 # DW_CFA_offset, column 0x8\n" "\t.uleb128 0x1\n" "\t.align 4\n" "\t.cie_end:\n" ); __asm__ ( ".fde:\n" "\t.long .fde_end-.fde_begin\n" ".fde_begin:\n" "\t.long .fde_begin-.cie\n" "\t.long func\n" "\t.long .func_end - func\n" "\t.uleb128 0x4 # Augmentation size\n" "\t.long .func_lsda # Language Specific Data Area\n" "\t.byte 0xe # DW_CFA_def_cfa_offset\n" "\t.uleb128 0x8\n" "\t.byte 0x85 # DW_CFA_offset, column 0x5\n" "\t.uleb128 0x2\n" "\t.byte 0xd # DW_CFA_def_cfa_register\n" "\t.uleb128 0x5\n" "\t.align 4\n" "\t.fde_end:\n");
こんな感じ。__asm__はCじゃないとか(Cだとラベル間のオフセットが定数にならない)。スタティックリンクじゃないと動かない(何故)とか。後始末をちゃんとしてないとか。投げたオブジェクトはリーク。
あんな大人数の前で喋ったの始めて…とか思ったけど、中学生のときに、なんか、そんなことがあったような。あれは嫌な思い出に近いけど。
今確認したことをいくつか。
C++の関数からCの関数呼んで、さらにそこからC++の関数を呼んだ場合、要するに間にC関数を挟んだ場合、例外は投げられない、と、確認せずに適当に言ったのが少し不安だったのだけど、間違ってなかったので安心。
いやー、でも、こういうのって、問題にならないのかな…。コールバックとか使ってたら問題になりそうなんだけど。危険そうだから、という理由で、無意識のうちに避けてしまっているのかもしれない。C++仕様ではどうなってるのかな…
お。こんなオプションが。
-funwind-tables 巻き戻しを行なう例外補足用テーブルを生成する
あと、継承関係があるときのcatch判定は、魔術等は全然無くて、type_infoで地道に判定してるように見えます。これの効率は…ちょっとわからないですが。