2013年4月18日木曜日

Firefox OS on PandaBoard ES (3)

前回、USB miniコネクタのケーブルがないため先に進まなかったが、買ってきたので再トライ。

PandaBoardのOTG USBのコネクタにケーブルを接続して、PCに接続。するとホストOSであるWindows8でPandaBoardが認識されることが確認できた。確認はデバイスマネージャにデバイスが追加されることで確認したが、デバイス名にはGoogleという文字が。。。まあ、Android端末として起動しているからということか。。

VMware上のUbuntuからもlsusbを実行すると。。。

Bus 001 Device 012: ID 18d1:d002 Google Inc.

と出てくるのが確認できる。

次はこのページのREADMEのステップ2と3を実行する。ステップ1はビルドのシェルを実行した時点で完了しているのでスキップしていいとのこと。

USBを挿入せずに、PandaBoardをUSB OTG経由でPCに接続、そして電源投入。するとLEDが一つだけ点灯する。その後Ubuntuからlsusbを実行すると。。。

Bus 001 Device 031: ID 0451:d010 Texas Instruments, Inc.

と出てくるので、やはりGoogleとでるのはAndroidが起動していたからという事で落ち着いた。

早速、ステップ2のコマンド

> device/ti/panda/usbboot device/ti/panda/bootloader.bin

を実行すると。。。


using built-in 2ndstage.bin
reading ASIC ID
CHIP: 4440
IDEN: 0000000000000000000000000000000000000000
MPKH: 0000000000000000000000000000000000000000000000000000000000000000
CRC0: 229e85ba
CRC1: 00000000
sending 2ndstage to target... f0030002
waiting for 2ndstage response...

と出力されたまま、停止。。。。PandaBoardもさっきまで光っていたLEDも消えており、どうも失敗しているようにみえる。。。

再度、このページを確認すると以下の既知の問題についての説明があった。
USB ブートを使用した際の "waiting for OMAP4XXX..."
もし、このメッセージが表示されたら、全てのケーブルを PandaBoard から外してください。PandaBoard に接続するのは USB のみです。電源は接続しません。この状態で、sudo で usbboot を実行してください。
という訳で、PandaBoardにはUSBのみ接続して、今回はsudoを付加して


> sudo device/ti/panda/usbboot device/ti/panda/bootloader.bin



実行すると。。。。何も変わらない。。。時間がかかるだけなのか?時間がないので今日はこれでおしまい。


2013年4月17日水曜日

Firefox OS on PandaBoard ES (2)

前回、PandaBoard用のAndroidをLinaroのイメージを利用して作ったが、ハングするという問題があるが、USB通信させるために必要な設定が可能であるかを確認してみた。
その結果、必要な設定はAndroid側に必要なのではなく、開発PC側に必要だという事に気が付いた。。。^^;

そもそもこのページには
Under GNU/linux systems (and specifically under Ubuntu systems), regular users can't directly access USB devices by default. The system needs to be configured to allow such access.
と書いてあるわけで、そのシステム(=GNU/linux)は設定される必要がある、ときちんと書いてあるのだが、読み飛ばしていたため、勝手な解釈をしてしまっていた訳だ。真夜中のクラブ活動的なところがあるとはいえ、もう少し落ち着てやらねば。。。

気を取り直して、Ubuntu側で以下のコマンドを実行し、指定通りの内容のファイルを作成する。

> /etc/udev/rules.d
> gedit 51-android.rules

ただし、Mozillaの説明では
B2G に対しては、安全に使用するために、ファイルモードを "0666" に設定します。
と書いてあるので、ファイルを作成後、以下のコマンドを実行する。

> sudo chmod 0666 51-android.rules

さて、これで接続できるだろうとリトライするも何も変化なし。lsusbでもTI関係の出力は出ないし、そもそもホストOSであるWindowsでも認識されていない。。。配線が間違っているのかと確認してみると、あれ?PandaBoardの基板にもう一つUSBと書かれたコネクタがあるぞ。。。嫌な予感がして、PandaBoard本家のサイトで確認すると、やはり新たに見つけたUSBコネクタがUSB OTG対応のコネクタということが判明。しかし、このコネクタはmini USBなので、手元に使えるケーブルがないので、今日はどうすることもできない。

という訳で、次はmini USBコネクタのケーブルを買ってからトライだ。

※ ハングの問題はまだ原因究明出来ていないが、PandaBoardに接続したマウスを頻繁に操作しているとハングしないので、もしかするとスクリーンセーバー起動後に復旧出来なくなっているのか?

2013年4月15日月曜日

Firefox OS on PandaBoard ES (1)

昨年度はPandaBoard ESを別の目的で使用していたが、ここでは報告することができない内容だったのだが、今回は公開しても問題ない内容なので、手順を記録する意味で記す。

PandaBoard ESで動作させるのは、FirefoxOS。

◆開発環境
 Ubuntu 12.04 on VMware Player on Windows8 Professional
 Linuxの必要条件はここに書かれているので、それらを満たすようにする。

◆SDカードの初期化

とりあえずここの情報をもとにSDカードを初期化。

> sudo ./omap3-mkcard.sh /dev/sdb

./omap3-mkcard.sh: 37: ./omap3-mkcard.sh: kpartx: not found
というエラーが出るので、apt-getでインストール。


> sudo apt-get install kpartx
これで再度シェルを実行するとSDカードのパーティションが正常に分割された。
パーティションは次の二つに分割されればOK。
  1. W95FAT32(LBA)タイプでBootable74MB
  2. Linuxタイプの8.0GB
◆AndroidのSDカード作成

Firefox OSの動作環境を作るためには一度AndroidのIceCream Sandwichを起動できるSDカードを準備しないといけないらしい。
ICSをビルドするのはしんどいので、ここの情報をもとにイメージをダウンロードして、SDカードの構築を行う。
まずここのページから 、boot.tar.bz2、system.tar.bz2、userdata.tar.bz2の3ファイルをダウンロードする。
次のコマンドでLinaroイメージツールをインストールする。
> sudo add-apt-repository ppa:linaro-maintainers/tools
> sudo apt-get update
> sudo apt-get install linaro-image-tools
> sudo apt-get install bzr
> bzr branch lp:linaro-image-tools

次のコマンドを実行した結果がtrueならば、

> gsettings get org.gnome.desktop.media-handling automount
以下のコマンドを実行する(自動マウントの無効化)。
> gsettings set org.gnome.desktop.media-handling automount false

次のコマンドを実行した結果がtrueならば、

> gsettings get org.gnome.desktop.media-handling automount-open
以下のコマンドを実行する(自動オープンの無効化)。
> gsettings set org.gnome.desktop.media-handling automount-open false

※Linaroのページでは自動マウント、自動オープンの無効化はdconfを使っていたのだが、エラーが出て正しく動作しないので、上記コマンドを代用した。

次にダウンロードしたファイルがあるフォルダに移動し、以下のコマンドを実行(赤字のドライブ名は環境によって違うので、各自の環境に合わせて変更すること)。
> sudo linaro-android-media-create --mmc /dev/sdb --dev panda --boot boot.tar.bz2 --system system.tar.bz2 --userdata userdata.tar.bz2

※ここで、なぜか/dev/sdb1がresource busyと怒られてエラーだらけとなっていたが、VMware PlayerからSDカードリーダーを切断し、再接続したらエラーは回避された。

この手順の後で確かにSDカードに色々書き込まれていることが確認できる。

次に以下のコマンドでグラフィックスライブラリをインストールするらしい。

> wget http://people.linaro.org/~vishalbhoj/install-binaries-4.0.4.sh
> chmod a+x install-binaries-4.0.4.sh
> ./install-binaries-4.0.4.sh

なお3番目のコマンドはライセンス規約を読まされて最後にI ACCEPTと入力しないと失敗するので注意。

最後に自動マウント、自動オープンを有効にする。

> gsettings set org.gnome.desktop.media-handling automount true
> gsettings set org.gnome.desktop.media-handling automount-open true

以上の手順で作成されたSDカードをPandaBoard ESに挿入して起動すると、Androidが起動して、マウスで操作できることは確認できた。PCとserial接続してminicomでアクセスすることもできた。
しかし、なぜか時間が経つと、Androidが固まり、マウスもminicomも反応しなくなる問題が発生。。。


◆Firefox OSのダウンロード&ビルド

並行して、ここの情報をもとにFirefox OSのプロジェクトのダウンロードとビルドを行う。ちなみに、ダウンロードは6時間くらいかかったような気がする。
また、ビルドも途中で以下のエラー出力を筆頭にして大量のエラーが発生するが、ここの情報を見る限りはNSPRのインストールができていないことが原因の様子。

external/negatus/src/Buffer.h:8:21: error: prtypes.h: No such file or directory

NSPRはここのページに書いてある通りNetspace Portable Runtimeだそうです。以下のコマンドでインストールできることも書いてある。

> sudo apt-get install libnspr4-dev

再度ビルドすると、一時間はかからずに完了する。
この後の手順はPandaBoard ESとPCがUSB接続できてからとなるはずなので、反応しなくなる問題を解決しないといけない。。。

※2013/04/17 ラベルをつけ忘れていたので、追加。

2013年4月14日日曜日

Windows8

やはりMacBookAirでは色々とリソース不足なので、Windows8 PCを購入。ノートパソコンではなく、デスクトップ。

今後は、Windows+Ubuntu on VMwareで色々試したりしようかと思っている。
MacBookAirは今でリモートデスクトップでWindowsマシンを制御するのに利用する予定。

2013年1月17日木曜日

what's transferable objects?

元ネタはこちら
workers with transferable objectとは何か?を調べて見つけたページ。
2011年の投稿なので結構前からある技術の様だ。

transferable object以前


chrome 13でweb workerとmain process間でデータのやり取りを行うのにstructured cloningと呼ばれる(HTML5の仕様に記載されているらしい)方法が使われていた。これはJavaScriptの複雑なオブジェクトをシリアライズする方法でJSONよりも使える範囲は広くImageObjectやRegExpとかでもOK。だが、オブジェクトは新規にクローンを作って伝達する仕組みになっているので、メモリコピーが発生している分遅く、H/Wスペックは不明だが、32MBのArrayBufferをweb workerに転送するのに数百ミリ秒かかるらしい。

でtransferable objectとは?

そんなstructured cloningの課題を解決する方法として開発されchromeに採用されたのがtransferable object。メモリコピーがボトルネックだった訳なので、当然の様にzero-copyであり、C/C++の世界の参照渡しを想像してもらえばよい。しかし、完全に同じと言う訳ではなく、オブジェクトを送信してしまうと、そのオブジェクトは送信元のコンテキストから送信先のコンテキストに移動してしまい、送信元のコンテキストからクリアされ、利用する事が出来なくなる。うーん、使い方を気をつけないと行けない制約だ。

で、transferable objectを使う為のAPIは専用になっており、以下のAPIがchrome/v8には用意されている。

worker.webkitPostMessage(arrayBuffer, [arrayBuffer]);
window.webkitPostMessage(arrayBuffer, targetOrigin, [arrayBuffer]);

どの程度早くなるのか?

で最終的にどの程度早くなったのかを計測した結果が書かれている。それによると、32MBのArrayBufferを転送するのが302msecから6.6msecまで短縮されており、効果としては絶大なものがある。しかし、32MBものデータを転送するのか?とか考える人もいるだろうと思うのだが、WebGLのテクスチャー転送などで使えると書いてある(ちょっとした自動車のモデルを高精度に描画しようとすると、数MBは楽勝なので、確かに考えられるレベルではあると思う)。






2012年11月23日金曜日

webkit w/ gtk on 64 bit Ubuntu12.04

Ubuntu12.04 (64bit)でGTK版のWebKitをビルドする時、libsecret-1-devをapt-getしようとしてもnot foundと言う事でインストール出来ない。

このライブラリはwebkit.orgでインストールを指定されているものであり、当然インストールされていない状況でWebKitをビルドしようとしても、以下の通り、エラーとなる。

> Tools/Scripts/build-webkit --gtk
.....
checking for LIBSECRET... no
configure: error: Package requirements (libsecret-1) were not met:

No package 'libsecret-1' found
.....

当然なければソースコードからインストールする必要があると言う事で、以下のサイトを参考にインストール。

http://git.gnome.org/browse/libsecret/

gitのアドレスが記載されているので、そのアドレスからソースコードを入手。

> git clone git://git.gnome.org/libsecret

その後はお決まりの手順でmake & install。

> cd libsecret
> ./autogen.sh
> make
> sudo make install

これでGTK版のWebKitはビルド出来る。

2012年9月23日日曜日

Skia for NaCl

最近、色々と事情があり調べなければ行けない事がコロコロと移り変わるので結構しんどい。で、今はSkiaについて。

SkiaのSource Codeを調べていると、どうもnacl関係のディレクトリが作られている。naclと言えばNative Clientの事だろう。つまりはnacl環境で使えるSkiaが開発されていると言う事か?とかなり期待。

この中のindex.htmlを見てみると、どうやらIntel系CPU向けのnaclでskiaを動かそうという試みらしい。
ChangeLogから色々情報を探してみると、どうも2週間程度前から開始されたプロジェクトの様で、まだ動作するには色々やる事がある様子。今の所、サンプルHTMLとサンプルサーバまでの様で、naclport内でskiaをビルドするのはまだ出来ていない。今後に期待ですね。

2012年9月2日日曜日

making and running CUDA sample program

今回は前回インストールしたCUDAの開発環境で正しいのか確認するため、サンプルプログラムでmakeして、実行できるか確認してみる。


  • ターミナルを開いて以下のパスに移動する。
/Developer/GPU\ Computing/C


  • 中にサンプルプログラムが入っているので、ターミナルから"make"を実行する。
このときに警告が多数出力されるのが若干不安。。。でも、ビルドは完了した。


  • ビルド結果は以下のパスにあるので、そこに移動。かなりのファイル数がある。。。そりゃ、ビルドに時間かかるわな。。。
bin/darwin/release/

以下、サンプル画面を適当にコピー。これはsmokeParticles。

次はMandelbrot。
次はpostProcessGL。
次はparticles。
次はfluidGL。
次はsimpleGL。
次はvolumeRender。
他にも色々あるのだが、GeForceのバージョンが古いのでサポートしていない機能を使っているサンプルは動作しないものも少なからずあった。。。







Installing CUDA programming environment on MacBookAir

今回はMacでCUDAを使ってみようと思い、開発環境を構築してみた。

今使っているMacBookAirはNVIDIA GeForce 320MをGPUとして搭載しているので、CUDAを使えるはず。確認したら大丈夫だったので、構築開始。

CUDAのダウンロードはNVIDIAのこのページから行う。
現時点のCUDAの最新版は5だが、安定板は4.2なのでそちらを選択。

Mac用にはCUDA toolkit、ドライバ、SDKの3種類のファイルをダウンロード。ちなみに、今回ダウンロードしたのは以下のファイル。macosってMac OSの事ね。。。「まこす」って何?とか一瞬でも思ってしまった自分がいた。。。
  • cudatoolkit_4.2.9_macos.pkg
  • devdriver_4.2.10_macos.dmg
  • gpucomputingsdk_4.2.9_macos.pkg

■Toolkitのインストール
  • cudatoolkit_4.2.9_macos.pkgをダブルクリックして暫くすると以下のウィンドウが表示される。

  • ここで「続ける」をクリックすると、以下のメッセージが表示される。1GB位なら問題なし。
  • 「インストール」をクリックすると、インストールが開始される。

  •  そのまま放置されると、以下の様にインストールは成功するので、「閉じる」をクリックして、めでたくインストール完了。

■ドライバのインストール
  • devdriver_4.2.10_macos.dmgをダブルクリックすると、ディスクイメージの中身が見る事ができるので、CUDADriver.pkgをダブルクリック。
  • すると、インストーラーのウィンドウが表示される。CUDAアプリが動いているとマズいので、もし起動している場合は全て終了させる様にとの事。
  • 「続ける」をクリックすると、使用許諾契約が表示される。言語の選択肢が表示されているが、Englishしか選択肢が無いのはご愛嬌。
  • 「続ける」をクリックすると、確認ポップアップが表示される。

  • 「同意する」をクリックすると、以下の画面。インストール先の選択になると思っていたら、スキップしてインストールの種類になっている。機種によっては選択出来るのかも知れない。
  • 「インストール」をクリックすると、インストールが開始される。
  • インストールが完了すると、以下の画面になるので「閉じる」をクリックして、インストール終了。
■SDKのインストール
  • gpucomputingsdk_4.2.9_macos.pkgをダブルクリックすると、以下のウィンドウが表示される。
  • 「続ける」をクリックすると、使用許諾契約が表示される。今回は言語の選択肢がない。。。
  • 「続ける」をクリックすると、確認ポップアップが表示される。
  • 「同意する」をクリックすると、以下の画面。今回はインストール先が選択可能になっている。まあ、SDKだし選択出来てもおかしくない。
  • ちなみに「インストール先を変更...」を選択すると、以下の様な画面でHDDの選択が出来る様子だが、今回はデフォルトのままとした。
  • また「カスタマイズ」を選択すると、以下の様な画面でインストール先フォルダを変更出来る様子だが、今回はデフォルトのママとした。
  • 「インストール」をクリックすると、インストールが開始される。
  • そのまま放置されると、以下の様にインストールは成功するので、「閉じる」をクリックして、めでたくインストール完了。

インストールなんで、特に詰まる事もなし。次はサンプルでも動かしてみるかな。

2012年7月2日月曜日

[FIXED]make error on 64 bit Ubuntu12.04

現在、64bit Ubuntu12.04上でChromium Browserのビルドを行っているが、Chromium Projectに記載の手順だけでは上手く行かなかったので、メモ。

makeを実行する手前までは手順通りで問題は顕在化しないが、以下のコマンドを実行するとビルドエラー(エラーログが消失してしまったので定かではないのだが、lib32と言う単語があったような。。。)。

> make chrome BUILDTYPE=Release

定かでない記憶にあるlib32で想像するに64bit OSでビルドする場合には32bit用ライブラリが必要になる??と言う事かと思い、32bit OSでUbuntu8系で必要と記載のあった以下のコマンドを実行。

> sudo apt-get install bison fakeroot flex g++ g++-multilib gperf \  libapache2-mod-php5 libasound2-dev libbz2-dev libcairo2-dev \  libdbus-glib-1-dev libgconf2-dev libgl1-mesa-dev libglu1-mesa-dev \  libglib2.0-dev libgtk2.0-dev libjpeg62-dev libnspr4-dev libnss3-dev \  libpam0g-dev libsqlite3-dev libxslt1-dev libxss-dev \  mesa-common-dev msttcorefonts patch perl pkg-config python \  python2.5-dev rpm subversion libcupsys2-dev libgnome-keyring-dev \  libcurl4-gnutls-dev libelf-dev libc6-i386 lib32stdc++6 \  libbluetooth-dev

するとpython2.5-devは対応するモジュールがないよと言った趣旨のエラーが出るので

> python -V

でバージョン確認すると2.6.5なのでpython2.6-devに修正して再度実行。すると、以下のライブラリがインストールされた。

  g++-4.4-multilib g++-multilib gcc-4.4-multilib gcc-multilib lib32gcc1 lib32gomp1 lib32stdc++6 libc6-dev-i386 libc6-i386

その後再度makeを実行するとめでたくエラーはパス。
思わず、直感で対応してしまったのでエラー内容も原因も良く判らなくなってしまったのが非常に痛い。。。

2012年3月11日日曜日

checking chromium processes structure

Linuxでプロセスを調べる場合にはpsコマンドを使うことがあるが、あんまり見やすいとは言い難い出力になる(少なくとも自分には)。
 今回プロセスの親子関係を調べたいと思って調べたら"pstree"なるコマンドがLinuxにはあって、それを使うと、

init─┬─NetworkManager─┬─dhclient
     │                └─2*[{NetworkManager}]
/* 省略 */
     ├─chromium-browse─┬─chromium-browse
     │                 └─19*[{chromium-brows}]
     ├─chromium-browse───chromium-browse───3*[{chromium-brows}]
/* 省略 */

みたいな感じでinitをルートとしたプロセスがきっちりと親子関係が分かりやすく出力してくれる(多分、上の例は等幅フォントじゃないとずれて見えると思うが)。

N*[...]で囲まれているのは、...がN個その階層に存在していることを意味し、{...}は...がスレッドであることを意味する。

つまり、上記の例で見ると1個目のchromium-browse(rが抜けている…文字制限か…)の下には1個の子プロセスと19個のスレッドがあり、2個目のchromiumは1個の子プロセスを持ち、その子プロセスには3個のスレッドがあるという事になる。

ちなみに上記例はchromium-browserを起動した直後の状態なので、Linux版chromiumは起動直後で既に4プロセス動いている訳だ。

ここでchromiumのタブを一つ追加して、再度pstreeを実行すると

/* 省略 */
     ├─chromium-browse─┬─chromium-browse
     │                 └─15*[{chromium-brows}]
     ├─chromium-browse───2*[chromium-browse───3*[{chromium-brows}]]
 /* 省略 */

と出力される。2個目のchromium-browseの子プロセスが2個に増えている事が分かる。よく見ると1個目のchromium-browserのスレッド数が19個から15個に減っているがこれだけでは理由は不明。

どちらにせよ1個目のchromium-browseがBrowser UIプロセスで、 2個目がRender Viewプロセスの様だ。おそらく親のプロセスは管理プロセスか何かではないかと推測。

またここで先ほど追加したタブを別ウィンドウとして切り離して再度pstreeを実行すると

 /* 省略 */
      ├─chromium-browse─┬─chromium-browse
     │                 └─16*[{chromium-brows}]
     ├─chromium-browse───2*[chromium-browse───3*[{chromium-brows}]]
 /* 省略 */

と出力される。Browser UIプロセスと思われるchromium-browserのスレッド数が1個増えているが、Render VIewプロセスと思われるchromium-browserの子プロセスは増えていない。

どうやらchromium-browserは複数のタブをウィンドウに分離してもBrowser UIプロセスは増やさずに管理している様子。

2012年3月5日月曜日

Reading platform.h in v8 repository

v8のメモリまわりを知りたいので、virtual memory機能を調べるとplatform.hにVirtualMemoryなるクラスを発見。

class VirtualMemory

予約されたメモリ領域を表現し制御するクラス。
予約されたメモリの制御は代入とcopy-contructing?(コピーコンストラクタの誤字と思われる)によって他のVirtualMemoryオブジェクトにアサイン可能。予約されたメモリはお事理なるオブジェクトからは削除される。

メソッドは以下のものがある。日本語はheader fileに記載のコメント。

VirtualMemory();
空のVirtualMemoryオブジェクトを生成。予約されたメモリを持たない。

exlicit VirtualMemory(size_t size);
サイズが引数sizeのvirtual memoryを予約する。

VirtualMemory(size_t size, size_t alignment);
引数alignment毎にアライメントされた、サイズが引数sizeの領域を持つvirtual memoryを予約する。この処理ではaddress()によって戻された位置ではないかもしれない。

~VirtualMemory();
このVirtualMemoryオブジェクトによって制御されていた予約したメモリを開放する。

bool IsReserved();
予約されたメモリを持っているかどうかを返す。

void Reset();
組み込まれたVirtualMemoryオブジェクトの初期化、もしくはリセットを実行する。

void* address();
予約されたメモリの先頭アドレスを返す。
もしアライメントを持って予約されたメモリならば、このアドレスは必ずしもアライメントされているとは限らない。アライメントブロックの先頭を取得するためにはアライメントサイズの倍数だけ端数を切り捨てる必要があるかもしれない。

size_t size();
予約されたメモリのサイズを返す。戻り値が意味あるのはIsReserved()がtrueの場合のみである。
もしアライメントを持って予約されたメモリならば、このサイズは要求されたサイズよりも大きくなるかもしれない。

bool Commit(void* address, size_t size, bool is_executable);
実際のメモリをコミットする。コミット操作が成功したかどうかを戻り値で返す。

bool Uncommit(void* address, size_t size);
実際のメモリをアンコミットする。アンコミット操作が成功したかどうかを戻り値で返す。

void Release();
[コメントなし]

void TakeControl(VirtualMemory* from);
予約された領域の制御を異なるVirtualMemoryオブジェクトにアサインする。
古いオブジェクトはこれ以上動作しない(IsReserved()はfalseを返す)。

static void* ReserveRegion(size_t size);
[コメントなし]

static bool CommitRegion(void* base, size_t size, bool is_executable);
[コメントなし]

static bool UncommitRegion(void* base, size_t size);
[コメントなし]

static bool ReleaseRegion(void* base, size_t size);
ReserveRegion()によって返されるベースポインタと予約時のサイズと同サイズの値を引数に実行する必要がある。

基本的なメモリ管理クラスの様だ。ccファイルの方はplatform別にplatform-<プラットフォーム名>.ccと言うファイルになっている。linuxの場合にはplatform-linux.ccといった具合。
次回はccファイルの中身を見てみる予定。

2012年3月1日木曜日

V8 JavaScript Engine libraries.cc Part 2

昨日の続き。
libraries.ccで定義されている関数がどこで使われているかを調査。
(JavaScriptコードをv8エンジンではどう使っているのか)一番気になるGetRawScriptSource()がターゲット。
■GetRawScriptSource()
1.void Deserializer::ReadChunk() @ serializer.cc
data = source_->Get();の結果がkNativesStringResourceの場合に実行される。
その戻り値を利用してNativesExternalStringResourceクラスのインスタンス生成。
2.Handle<String> Bootstrapper::NativesSourceLookup() @ bootstrapper.cc
heap->natives_source_cache()->get(index)->IsUndefined()がtrueならば実行される(ただし、Natives::GetRawScriptSource())。
※ indexはint型引数。
※ NativeSourceLookup()はbool Genesis::CompileBuiltin() @ bootstrapper.ccから実行され、戻り値がCompileNative()に渡される。
3.bool Genesis::CompileExperimentalBuiltin() @ bootstrapper.cc
ExperimentalNatives::GetRawScriptSource()限定だが実行され、その結果がfactory->NewStringFromAscii()に渡され、その結果がCompileNative()に渡される。
4.void Shell::InstallUtilityScript() @ d8.cc
GetRawScriptSource()の引数として与えられる値は以下の通り。
i::NativesCollection<i::D8>::GetIndex("d8");
"d8"と言う時点でbuiltinではなく、d8固有の機能をインストールしているはず。

ちなみにNativesとExperimentalNativesは以下の通りnatives.hで定義されている。NativeCollectionクラスの定義も同じファイルで定義されている。

typedef NativesCollection<CORE> Natives;
typedef NativesCollection<EXPERIMENTAL> ExperimentalNatives;

以上の事から、以下の2点が今後の調査ポイントになりそう。

  • Deserializer::ReadChunk()でNativesExternalStringResourceオブジェクトを作る事の意味
  • Bootstrapper::NativesSourceLookup()でCompileNative()にJavaScriptソースコードが渡された後の処理
あと、libraries.ccに生成された整数値の羅列を解析(と言う程のものではないが、char型データとしてファイル出力)して、目視確認すると以下の事をやっている事は分かった。
  • コメント行は全て改行のみに変換
  • ローカル変数名を1文字のアルファベットに変換

つまりは、データ化した時のサイズを小さくする事が目的の変換が施されている様子。
依然として関数名の先頭に%が記述されている変則的な記法は残っている。。。

とりあえず今日はここまで。

2012年2月29日水曜日

V8 JavaScript Engine libraries.cc

V8と言って思い浮かべるのがエンジンなのか、JavaScriptなのか、と言うと私はJavaScript。と言う訳で今回はV8 JavaScript Engineについて調査。

 V8をビルドするとobj/releaseもしくはobj/debug以下にlibraries.ccexperimental-libraries.ccと言うソースコードとそのビルド結果となるlibraries.oexperimenta-libraries.oいう合計4個のファイルが生成される。これは一体どうやって作られて、どんな目的のモノなのであろうか。

 まずはビルド時のログ出力をlibrariesをキーに検索すると、以下のような出力がある事が分かる(ちなみに、以下の出力はscons d8 mode=debugでビルドした時のもの。他の場合でも同じだとは思う)。
JS2C(["obj/debug/libraries.cc"], ["src/runtime.js", "src/v8natives.js", "src/array.js", "src/string.js", "src/uri.js", "src/math.js", "src/messages.js", "src/apinatives.js", "src/date.js", "src/regexp.js", "src/json.js", "src/liveedit-debugger.js", "src/mirror-debugger.js", "src/debug-debugger.js", "src/macros.py"])
g++ -o obj/debug/libraries.o -c -fno-rtti -fno-exceptions -fvisibility=hidden -Wall -Werror -W -Wno-unused-parameter -Woverloaded-virtual -Wnon-virtual-dtor -pedantic -m32 -g -O0 -ansi -DV8_TARGET_ARCH_IA32 -DENABLE_DISASSEMBLER -DDEBUG -DENABLE_DEBUGGER_SUPPORT -DV8_ENABLE_CHECKS -DOBJECT_PRINT -Iobj/debug -Isrc -Isrc obj/debug/libraries.cc
JS2C(["obj/debug/experimental-libraries.cc"], ["src/proxy.js", "src/collection.js", "src/macros.py"])
g++ -o obj/debug/experimental-libraries.o -c -fno-rtti -fno-exceptions -fvisibility=hidden -Wall -Werror -W -Wno-unused-parameter -Woverloaded-virtual -Wnon-virtual-dtor -pedantic -m32 -g -O0 -ansi -DV8_TARGET_ARCH_IA32 -DENABLE_DISASSEMBLER -DDEBUG -DENABLE_DEBUGGER_SUPPORT -DV8_ENABLE_CHECKS -DOBJECT_PRINT -Iobj/debug -Isrc -Isrc obj/debug/experimental-libraries.cc
 どうもJS2Cでccファイルを生成して、その後にg++でビルドしている様子。JS2Cと言う関数名からするとJavaScriptをCに変換しているのであろう。そのJS2Cはtools/js2c.pyファイルに定義されてて、そのファイルの先頭には以下の様なコメントがある。
# This is a utility for converting JavaScript source code into C-style
# char arrays. It is used for embedded JavaScript code in the V8
# library.
 つまり、JavaSciptコードをC形式の文字列配列に変換する、と言う事でJavaScript関数をCの関数に変換している訳ではないようなので、ちょっとがっかり。

 とりあえずJS2Cの第二引数に与えられているjsもpyもsrc以下と言う事なのでsrcフォルダを見てみると、jsもpyも全てそこに存在している。とりあえずv8natives.jsの中身を見てみると、どうやらJavaScriptコードの様子。。。なのだが微妙に違う記法が混じっていて、関数名の先頭に%記号が付いている。。。。こんなのありだっけか?と思ったが、恐らくpyの方で何かしらの変換をするのかも知れない。

// Helper function used to install functions on objects.
function InstallFunctions(object, attributes, functions) {
  if (functions.length >= 8) {
    %OptimizeObjectForAddingMultipleProperties(object, functions.length >> 1);
  }
  for (var i = 0; i < functions.length; i += 2) {
    var key = functions[i];
    var f = functions[i + 1];
    %FunctionSetName(f, key);
    %FunctionRemovePrototype(f);
    %SetProperty(object, key, f, attributes);
    %SetNativeFlag(f);
  }
  %ToFastProperties(object);
}
とりあえずsrcフォルダ以下でOptimizeObjectForAddingMultiplePropertiesを検索キーとしてgrepをかけてみると以下のファイルが見つかった(subversion関連は除外)。
./src/v8natives.js
./src/runtime.cc
./src/runtime.h
./src/math.js
どうもOptimizeObjectForAddingMultiplePropertiesはruntime.ccで定義されているcの関数である事が分かった。と言う事は%が先頭についた関数はcで定義された関数を直接記述する特別な記法なのかも知れない。

次にlibraries.ccの中を見ると以下の通りで、正確にはsources[]の中身を見る必要があるが、やはりスクリプトをC形式の文字列データに置き換えて、V8からアクセス出来る様にしている様子。
// Copyright 2011 Google Inc. All Rights Reserved. 
// This file was generated from .js source files by SCons.  If you
// want to make changes to this file you should either change the
// javascript source files or the SConstruct script.
#include "v8.h"
#include "natives.h"
#include "utils.h"
namespace v8 {
namespace internal {
static const byte sources[] = { .....(数値の羅列).....};
static const char* raw_sources = reinterpret_cast<const char*>(sources);  // const byteをconst charにキャスト
  template <>
  int NativesCollection<CORE>::GetBuiltinsCount() { // ビルトイン関数の個数
    return 14;
  }
  template <>
  int NativesCollection<CORE>::GetDebuggerCount() {  // デバッガー関数の個数
    return 3;
  }
  template <>
  int NativesCollection<CORE>::GetIndex(const char* name) { // オブジェクト名からインデックスを導出
    if (strcmp(name, "liveedit") == 0) return 0;
 。。。
    if (strcmp(name, "json") == 0) return 13;
    return -1;
  }
  template <>
  int NativesCollection<CORE>::GetRawScriptsSize() { // 生スクリプトサイズ
    return 238136;
  }
  template <>
  Vector<const char> NativesCollection<CORE>::GetRawScriptSource(int index) { // 生スクリプトソースをインデックスをキーに取得
    if (index == 0) return Vector<const char>(raw_sources + 144015, 15179);
 。。。
    if (index == 13) return Vector<const char>(raw_sources + 138135, 5880);
    return Vector<const char>("", 0);
  }
  template <>
  Vector<const char> NativesCollection<CORE>::GetScriptName(int index) { // スクリプト名をインデックスをキーに取得
    if (index == 0) return Vector<const char>("native liveedit.js", 18);
 。。。
    if (index == 13) return Vector<const char>("native json.js", 14);
    return Vector<const char>("", 0);
  }
  template <>
  Vector<const byte> NativesCollection<CORE>::GetScriptsSource() { // スクリプトソースを取得
    return Vector<const byte>(sources, 238136);
  }
  template <>
  void NativesCollection<CORE>::SetRawScriptsSource(Vector<const char> raw_source) { // 生スクリプトの設定
    ASSERT(238136 == raw_source.length());
    raw_sources = raw_source.start();
  }
}  // internal
}  // v8
 しかし、スクリプトコードをV8から見る事がどんな状況で必要なのだろうか?ここのスクリプトコードをJITコンパイルしてからbuilt-inオブジェクトのメソッドは実行されている?少なくともbuilt-in関数のソースコードはJavaScriptでは見える必要はないので、JITが有力である気がする。となると独自のbuilt-in関数を組み込む場合にはjsファイルを作成して、SConsのスクリプトを書き換えれば、追加が出来る様になるとか?

うーん、もう少し調べたいが、遅いので今日はこれまで。

2012年2月27日月曜日

Webinos Demo Series #4: Cardio Hills – Remote Sensors

原文リンク
ヘルスケアや個人トレーナーサービスを例にあげた、webベースのリモートセンシングのデモらしい。心拍数のようなプライバシーに関わる様な情報を自分が洗濯した人と共有する事が出来る(webinosではプライバシーや公開対象の人似ついての制御を提供する)。
内容的には良く聞く様なデモシナリオなのでそんなに興味がある訳ではないし、残念ながらデモは観られない(というかどこにデモがある??)のでどんなシステム構成かは不明だが、リモートのセンサーに外部からアクセス出来ると言う事はセンサー側がサーバになる訳なんだろう。と言う事はかなりの省電力を意識した設計にするんだろうな。
こういう話から超小型のOSを一昔前にMITだかのアメリカの大学で開発していたな〜、どうなったんだろうな〜、と懐かしく思ったのだが、そのOSの名前が全く思い出せない。。。

と思った数分後に思い出した。TinyOSだ。
サイトを見ると2010年のリリースを最後にGoogle codeに移動したらしい。

2012年2月22日水曜日

How to invoke v8 engine on chromium

少しWebKitから外れて、chromiumの調査をしてみる。

気になっていたのはchromiumのWebKitとv8の関係。WebKitはJavaScriptCoreを持っているのだが、一部を流用してv8が動いているのか、それともv8単体でJavaScriptを実現しているのか。そして、WebKitとv8の繋ぎはどうなっているのか。
とりあえずWebKitとv8の繋ぎをコードを追っかけてみた結果が下のシーケンス図。


WebCoreのScriptElementからScriptControllerのevaluate()を実行しているが、このScriptControllerはv8用とjs用の2種類が用意されていて、chromiumではv8用のコードがビルド時に使われ、そのままv8に流れて行く事になる。
次にV8Proxyでv8のライブラリを呼び出してv8の機能でプリコンパイル、コンパイル、実行、と処理を行っている。最終的な実行はi:Executtionで行っている様子。この構成を見る限り、v8は単独でJavaScriptを実現している様だ。まあ、v8のスタンドアローン版もある訳だし、敢えてブラウザの場合だけJavaScriptCoreと連動するってのも変な構成だし、至極当たり前な流れだ。

次はv8はJITコンパイラな訳だから、ネイティブコンパイルする条件を調べたい。

(2/22追記)
chromiumのコードにprintf()を追加してビルドしてみて分かったのだが、どうもV8Proxyから左側はchromiumのビルド時にターゲットから外れている様子。調べ直しだな。。。

(2/23追記)
v8はJITコンパイルするけれど、Firefoxのとは違って全て初回実行時にネイティブビルドすると言う事が分かった。全て初回ビルドか。。。



2012年2月21日火曜日

WebKitGtk Build on Ubuntu11.10 Part 2

pixmanが取得出来ない問題は時間帯を変えると、すんなり通った。。。
しかし、pixbufで以下のエラーが。。。

make[4]: *** `all-am' に必要なターゲット `GdkPixbuf-2.0.typelib' を make するルールがありません.  中止.
加えてlibsoupでも

make[2]: *** ターゲット `/usr/share/gobject-introspection-1.0/Makefile.introspection' を make するルールがありません.  中止.
at-spi2-coreでも

make[2]: *** `Atspi-2.0.gir' に必要なターゲット `/usr/bin/g-ir-scanner' を make するルールがありません.  中止.
こんなエラーでmakeが失敗する。。。

少なくとも/usr/share/gobject-introspection-1.0なるディレクトリは存在しない。
>  sudo apt-get install gobject-introspection
とかやってみるとインストールが始まる。。。make時のログ出力を確認すると

checking for gobject-introspection... yes
と出力されているが、うまくチェック機構が動作していないのだろうか。。。

とりあえず、状況を変更したので再度
> Tools/Scripts/update-webkitgtk-libs
を実行してみると、何故かpixbufもうまくmakeできる様になった。成功するのは良いんだけれども、原因が分からないまま成功するのは気持ちがいいモノではないなあ。その勢いで今までconfigureすら動かなかったものまで動作し始めて、また完了まで時間がかかりそうなので、今日はここまで。
(追記)
すべて正常にインストールが完了した様子。
明日はようやくWebKit本体のビルドが出来る。



2012年2月18日土曜日

WebKitGtk Build on Ubuntu11.10 Part 1

Gtk版のWebKitが欲しいので、ビルドしようとトライしていたのだが、Ubuntu10.04では必要なライブラリをインストール出来ず(正確にはインストールできるが色々な物を破壊してしまう。。)挫折。Ununtu11.04でもやってみて何とかウィンドウが表示される所までは行ったのだが、何故かページロードが出来ないし、裏では色々とエラー吐き撒くっているので、ちょっと微妙。と言う訳でビルドが出来ないのはUbuntuのバージョンが古いからという勝手な理由付けで、今回はUbuntu11.10で再チャレンジ(本当はもっとLinuxについて調べておくべきだとは思うんだが、時間がない)。
ビルド環境となるUbuntu11.10は以下の通りVirtualBox上で実行。
  • Ubuntu11.10 on VirtualBox on MacBookAir (Mac OS X 10.6.8)
ここの内容に従って環境構築。

Install the base WebKitGTK+ dependencies
apt-getはUbuntu10.04では色々とインストール出来なかったのだが、今回は特にエラーも出ずに全てインストール成功。
Install the jhbuild module dependencies
ここもapt-getはエラーなく完了。Ubuntu10.04でもエラーは出なかった筈。
ここでGitをインストールしていない、WebKitのソースコードを取得していない(^^;)のでインストールとチェックアウト。
> sudo apt-get install git-core
> cd webkit
> git clone git://git.webkit.org/WebKit.git WebKit
チェックアウトに時間がかかるので取り敢えずここまで。
(追記)
と思ったが、並行してnightly buildから取ってきて残りの手順を実施してみる。

> Tools/Scripts/update-webkitgtk-libs
どうもpixmanのwgetで応答がないので再試行を繰り返している。。。cairographics.orgにはアクセス出来ている様なのだが、ダウンロードが出来ない様子。
Firefox on Ubuntu11.10で該当URLにアクセスしてみてもやはりダウンロードできない。Chrome on MBAでもcairographics.orgにアクセス出来ず。
他のチェックアウトは成功するので、サーバメンテでもしているのだろう。あとで、pixmanのためにやり直さないと。。。
とりあえず、時間がないのでここまで。





WebKit Page Cache I - The Basics 抄訳

WebKit Page Cache I – The Basics
Page Cacheの内部動作を調べる必要があったので、上記記事を読んでみた。ざっと見ただけで内部動作については書かれていない事は分かったが、取り敢えずちょこっとピックアップして和訳。

Page Cache Overview
  • Page Cache=Firefoxの"Back-Forward Cache"、"bfcache"、Operaの"Fast History Navigation"と呼ばれる。
  • WebKitの"Back/Forward List"と"Page Cache"は違う(らしい)。
  • Page Cacheはウェブをよりスムーズに移動出来る様にするためのエンドユーザ向けの機能。
  • "HTTP sense"、"disk cache"、"memory cache"における"cache"とは異なる。
  • Page Cacheは「あるページを移動する時に"一時停止"し、そのページに戻ってきた時に"再生"する」機能。
  • 新しいページに遷移する場合、前のページのDOM、JavaScript、プラグイン、画像等はクリアされてしまうと、戻るボタンで戻ってくると再度これらリソースをネットワーク上から取得して、ページを再構築しなければならず、非効率。
  • 以前のページのリソースを(戻るボタンを押された場合のために)解放せずに維持しておくのがPage Cache。
Why Wouldn't Work?
  • Page Cacheがそんなに素晴らしいものならば、新しいページに遷移する時にWebKitは常にPage Cacheを使わないのか?
  Some Pages aren't Interesting
  • ページロードが未完了、もしくはエラーの場合や、他のURLにリダイレクトするページの場合にはPage Cacheは動作しない。
  Some Pages are Complicated
  • ウェブページはPage Cacheされる事を想定されていないかも知れないため、"一時停止"する事が難しい場合もある。WebKitが"一時停止"できないネイティブコードを持つプラグインを持つ場合や、WebKitが履歴上キャッシュ管理していない複数フレームを持つページ等があげられる。
  Some Pages are Secure
  • WebKitは全てのHTTPSサイトをPage Cacheから展開する事を許可していない。
  Planned Improvements
  • revision 48036では主要な制約が解消され、フレームを持ったページのPage Cacheが可能。
  • Plug-inサポートは計画中改善の中の大きなアイテム。
Unload Handlers
  • unloadイベントは、ユーザがページをクローズした時にページにcleanup処理をさせるために設計されたもの。
  • Page Cache内にページを移動させる前に、ブラウザはunloadイベントを発火させる事ができない。
  • もしブラウザがunloadイベントを行わずにPage Cacheにページを移動させるならば、そのページは"一時停止"されて隠れている間にブラウザによって解放されるかも知れず、その場合cleanup処理は決して動作しない。
  • unloadイベントの目的はページが閉じられる時の重要な処理を許可する事であり、全ての主要ブラウザはそのようなページをPage Cacheに移動する事を拒絶しており、ユーザ操作上のインパクトに繋がる。

2012年2月14日火曜日

The Vehicle API by webinos

The Vehicle API – pushing borders of Web applications

車内はFlexRay, CAN,MOST等の異なるネットワークが存在し、Gatewayを経由して相互に接続している。それらのネットワークへのアクセスを提供する場合には安全機能の妨げにならない事を保証する必要がある。

よいエントリーポイントとしてはヘッドユニットがあるが、駐車時の後方距離センサーのデータを利用して物体までの距離をディスプレイに表示する場合にはソフトリアルタイムメッセージが必要となる(のでリアルタイム性を損なわない注意が必要)。そこでwebinos APIを経由した車両バスへのアクセスを制御し、車両情報への安全なデータアクセスを提供する。今のところ、要求される安全性を確保するためヘッドユニット内でのデータ利用に制限している。

webinosプラットフォームであるVehicle APIの最初のリリースでは車両データの読み取りと、オンボードナビゲーションシステムとの連携機能にフォーカスしている。Vehicle APIはW3C仕様に沿った設計でイベントモデルをベースとしている。現在速度や縦加速度はW3CのGeolocationやDevice Orientation APIが提供するため、Vehicle APIでは扱わず、以下のデータ等を扱う。
  • 静的車両データ(型式、 モデル、燃料やトランスミッションのタイプ)
  • 距離センサーデータ
  • トリップコンピュータデータ(平均速度、燃費、走行距離、走行可能距離)
  • 気候データ(エアコンや排気口)
  • 制御データ(ワイパーやライトの状態)
  • ギアデータ
  • ナビゲーションデータ(目的地までの距離、経路案内のキャンセル)
HTML、CSS、JavaScriptで作成された駐車時の物体距離センサー情報を利用したデモを作成している。

W3C仕様に沿った仕様作りを意識してはいるものの、W3Cの仕様にまで持って行く計画があるかどうかも分からない状況であり、今後も少しは気にして見ておいた方が良さそう。また、BMWが仕様作成したと言う点が興味深い。他者と協力して車両情報APIの主導権を握って置きたいのかも知れない。この辺のAPIが固まって一般に公開され、普及してしまうと、車載用アプリも一般ユーザが軽く作れる状況になってしまって、ナビメーカーはさあ大変、な状況になりそう。

まあ、その前にデータ取得だけとは言え、データの組み合わせ次第では幾らでもプライバシー侵害が出来てしまうので、セキュリティが重要になってくると思われる。でも、セキュリティを維持するために使い勝手を損なうのでは微妙なのでユーザビリティを維持、もしくは向上させる事が可能なセキュリティシステムとか、今後必要になってくるかも知れない。