WebKit について (コード)

WebKit のコードについて。 Google 社内のコードを見慣れてると、 WebKit のコードはまず、オープンソース的な感じというか、ありていに言うとコメントが圧倒的に少ないように感じます。特に内部についてわかってない人もわかるようなコメントを書く気は基本的に無いらしく、冗長気味なコメントを書くとむしろ削ってちょとレビューされたりします。偉い人死んだらどうするのかなー的な。

あとは関数名とかもイマイチなのが多いように思います。個人的な体験で一番印象的だったのは HTML parser 内にあった parseSpecial という関数でした。この special ってのは textarea, script, style, iframe なんかの中にあるタグが無視されるような種類のものを指していたのですが、 special って命名はアレだなぁ…と。そう思いつつ WebKit の人はみんな知ってる用語だったりするんかいなぁと思って bool specialTagParsed みたいな変数を作ったら、「special とかじゃわからんがな」と怒られて、「うんそうだねじゃあこっちの関数名もなおしとくね…」といじった記憶があります。

一方で省メモリや高速化なんかの点では、これはなかなかすごく頑張ってるように思います。まず省メモリについては、そこらじゅうで bit field が使われてるとかいう時点で既にアレです。あとは共有できるものはなるべく共有するというのもよくやられています。例えば RenderStyle というスタイル情報を保持する最終地点のようなオブジェクトは RenderObject というものが所有しているのですが、同じ指定がされてる RenderObject 同士は shared_ptr 的なもので共有しているなんていう基本的なものとか、同じ内容の文字列を Ruby のシンボルとかみたいに管理したりとか、そういう。後者はどういう実装になってるかよくわかってませんが。

もう少し変態的な省メモリ策としては、あまり使われないメンバ変数の駆逐があります。どんな Web サイトでもタグの数に比例して必要になるような基本的なクラスがいくつかあるのですが、そういったクラスにメンバ変数を足すのは、よほどのことが無い限り許してもらえないようです。

それじゃあ全てのサイトで使われるというわけではない、レアな新機能が実装できないじゃないか…と思うのですが、そういったことをやる時は定番のイディオムが WebKit の中にはあるようです。具体的には、オブジェクトのポインタから足したいメンバへの HashMap をグローバル変数として作って、そのレアな新機能が使われる時にだけその HashMap を使うというものです。これはまぁメンバ変数参照より遅いでしょうけど、まぁレアな機能だし別に良いということだと思います。まぁ問題は可読性が落ちることではありますが…例えばRenderBlock.cpp の先頭あたりを見るとそういう不幸な HashMap 群が見られます。

ああそうそう、こういうグローバル変数が lock もされずそこらじゅうで使われてることからわかるわけですが、 WebCore は基本的に thread unsafe です。ちょっと残念だなーという感じは否めませんね…

速度的に頑張ってるなーというのは設計的な意味で頑張ってるところもあるのかもしれないのですが、私はよく知りません。ただコンパイラでいう peephole optimization 的なのはよく見ます。わかりやすいところで言うと固定されてる背景とかが無いサイトならスクロールは大部分の領域を BitBlt して新しくあらわれるところだけ描画する、なんてのがあります。

あとはなんでしょうね。コメントが少ないのとも関係しますが、全体的にコードが難しいなぁと思います。例えば適当に拾ってきたこのコード。

  if (!oldEndOfInline &&
      (current == parent ||
       (!current->isFloating() && !current->isReplaced() && !current->isPositioned())))
      result = current->firstChild();

全体的にこういう何を条件としてるのかよくわからん && と || が大量に入ってる if が多いと思います。最初の方は isReplaced って何なんだろうなぁとか思いつつカンで読んでいました。ちなみに replaced はたぶん CSS 用語で img タグなんかみたいにサイズが外部要因で決まるような要素です。

そんなこんな

追記: そういえば Firefox は大昔にほんの少しだけ読んで放棄した時の印象で書くと、結構抽象化とかされてるんだけど、されすぎてて素人には何がなんだかわからんくなってる印象がありました。その点 WebKit は抽象化の程度が弱い印象があって、例えばひたすら if が続くとかそういうのが結構あって、単にこの関数で何が起きているかーとかいうことを逐次的に追うのは割と簡単かもしれません。ただ数百行ある関数とか多数で、ハイレベルな観点で読むというか、この関数はそもそも何をする関数なのかーとかそういうものはとても読みにくい印象。そのへんは良し悪しかなぁとか思います。

そのへんについて私がなんとなく思ってることについて: http://d.hatena.ne.jp/shinichiro_h/20070601#1180683355

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h