
2026/01/07 13:48
**RISC‑V における V8 開発の一端** V8 JavaScript エンジンは、多くの最新ウェブブラウザやサーバー側ランタイムにとって不可欠なコンポーネントです。RISC‑V アーキテクチャで継続的に開発されていることは、オープンソースプロジェクトが新興ハードウェアエコシステムに適応できることを示しています。 --- ### なぜ RISC‑V なのか? - **オープン命令セット** – ライセンス料がなく、実験を奨励します。 - **スケーラブルな拡張性** – 組込みデバイスから高性能サーバまで対応可能です。 - **成長中のエコシステム** – ベンダーや学術機関からのサポートが増加しています。 --- ### 主な開発マイルストーン 1. **初期移植(2022)** - RISC‑V LLVM ターゲットで V8 のベアメタルビルドを実装。 - 64 ビット呼び出し規約の ABI 不一致を修正。 2. **JIT ランタイム強化(2023)** - コード密度向上のため *M* と *C* 拡張に対応。 - カスタム *RVC* (圧縮命令) バックエンドを導入。 3. **パフォーマンス最適化(2024)** - RISC‑V の 32 個の汎用レジスタに対するレジスタ割り当てを微調整。 - 新しい *Zk* 拡張に合わせた投機実行経路を実装。 --- ### 発生した課題 - **ツールチェーンの成熟度** – 初期の LLVM リリースは RISC‑V 用の最適化パスが不十分でした。 - **メモリモデルの違い** – 弱順序メモリモデルで一貫した動作を保証するために広範なテストが必要でした。 - **ハードウェアの多様性** – 任意拡張機能の実装差異により、ビルドシステムは高度に構成可能である必要がありました。 --- ### コミュニティ貢献 - **GitHub の Issue と PR** – RISC‑V コミュニティから 150 件以上のプルリクエストがマージされ、バグ修正や新機能が追加。 - **テストインフラ** – エミュレート環境と実際のハードウェア(SiFive の U54 コアを含む)で継続的インテグレーションパイプラインが稼働。 --- ### 今後の方向性 - **完全なガベージコレクタ統合** – V8 の世代別 GC を RISC‑V のキャッシュ階層に適応。 - **セキュリティ強化** – RISC‑V の *Zba* 拡張を利用した効率的な境界チェック。 - **クロスコンパイルサポート** – 開発者が Node.js アプリケーションを直接 RISC‑V プラットフォーム上でビルドできるように。 --- ### 結論 RISC‑V に対する V8 チームの取り組みは、モダン JavaScript エンジンが新しい命令セットに適応できる柔軟性を示しています。ハードウェアベンダーが RISC‑V への投資を継続すれば、クライアント・サーバー両方の環境でさらなる性能向上と採用拡大が期待できます。
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
V8 の JavaScript エンジンは、x86_64 および ARM64 と同等の機能を実現しつつ、完全に RISC‑V に移植されました。このポートは 2020 年に Kim McMahon によって発表され、メイン V8 リポジトリへアップストリーム化されました。継続的に自動ビルドボットが緑(省エネルギー)テストを実行しながら検証しており、コミュニティの貢献者は主流と同期させつつ、定期的なコミットや小規模最適化を担当しています。
主要な低レベル最適化
- 簡略化された定数プールロジック:コード生成時に 32 ビットオフセットが出力されるようになり、複雑さが減少し将来的には実行不能セクションを可能にします。
- WebAssembly における原子ジャンプテーブルパッチングバグの修正:
でターゲットアドレスをロードすることで競合状態を排除し、短距離ld
ジャンプは依然としてサポートします。jal - Zba の
命令を使用した融合シフト+加算:ロード回数を約半分に削減します。shxadd - ポインタデコンプレッションの改善:
(Zba も同様)を利用し、デコンプレッションシーケンスを五命令から二命令へ縮小しました。zext.w - ベクターサポートの拡張:固定 128 ビットから最大 512 ビットまで柔軟な RVV ベクトルに対応。レジスタ保存/復元のバグが修正され、完全な JetStream ベンチマークを実行可能になりました。
RISC‑V の 32‑ビット版は OS サポートが限定的で強力なユースケースが不足しているため、2026 年 5 月までに廃止予定です。64‑ビット版は継続して稼働中で、既に完全な JetStream スイート(約 33 MB の Wasm、約 2 M 行の JavaScript)を実行し、機能同等性と本番ワークロードへの準備が整っています。この進展は、エッジデバイス・サーバー・省電力環境において RISC‑V をパフォーマンスを損なうことなく JavaScript エンジンの有効なプラットフォームとして位置づけています。
本文
投稿者: Florian Loitsch、Ji Qiu、Kasper Lund、Yahan Lu、Zhijin Zeng
2020 年に Kim McMahon が RISC‑V 上で V8 をオープンソース化したことを発表するブログ記事を書きました。その時点ではポートは別リポジトリに存在し、多くの作業が残っていました。近年、RISC‑V のサポートはメインの V8 リポジトリへ統合され、x86_64 や ARM64 など公式にサポートされているアーキテクチャとほぼ同等の機能を実現できるようになりました。RISC‑V ポートは V8 のビルドボットで継続的にテストされ、最も「グリーン(低資源消費)」なポートの一つとして評価されています。RISC‑V コミュニティはコア開発者が導入したバグを素早く修正し、独立した Jenkins ビルドボットではさらに多くの構成がテストされます。
以下に、過去 6 か月間で特に興味深い変更点をまとめました。網羅的ではありませんが、代表的なハイライトです。
プール機能の改善
ポートは 定数プール(直接エンコードできない定数用)と トランスミッションプール(長距離ジャンプ用)の 2 種類を使用します。
- V8 は全ての前方ジャンプに対して近接ジャンプ(near‑jump)を発行します。ターゲットが遠すぎる場合、近接ジャンプはトランスミッションプール内のエントリを指し、そのエントリから実際のターゲットへ長距離ジャンプします。
- 近接ジャンプではオフセットとして 13 ビットしか使えないため、V8 は「最後に生成したトランスミッションプールエントリ」と現在位置との距離が閾値を超えているか定期的にチェックし、必要ならば現在位置でトランスミッションプールを挿入します。
# 64 個のエントリを持つトランスミッションプールを飛び越える j 516 # エントリ 0: auipc t6, 0x0 jalr zero_reg, 1552(t6) # エントリ 1: auipc t6, 0x0 jalr zero_reg, 1632(t6) ...
定数プールも同様に機能していましたが、各プールが相互に位置を影響し合うため複雑なロジックが必要でした。ロード命令は最大 32 ビットオフセットで定数プールから値を取得できることを利用し、コード生成の最後に定数プールを発行するように変更しました。これによりロジックが簡素化され、将来的には非実行領域へ定数を移動させる準備も整います。
原子ジャンプテーブルパッチング
WebAssembly(Wasm)で、間接呼び出しテーブルを更新する際の競合状態を修正しました:
元の実装:
auipc t6, high_20 # 上位 20 ビットをロード jalr t6, t6, low_12 # ターゲットへジャンプ
この 2 命令は原子的に書き込まれますが、CPU は最初の命令を実行してから次を実行する可能性があります。
新しい実装:
auipc t6, 0 # PC を t6 にロード ld t6, 16(t6) # ターゲットアドレス(下位)をロード jalr x0, t6 # ターゲットへジャンプ nop .dw target[0] # 下位 32 ビット .dw target[1] # 上位 32 ビット
ターゲットが短いオフセット内にある場合は
jal を直接使用できます:
Far | Near -------------|------------- auipc t6, 0 | jal x0 <imm21> ld t6,16(t6)| ld t6,16(t6) jalr x0,t6 | jalr x0,t6 nop | nop .dw target[0] | .dw target[0] .dw target[1] | .dw target[1]
パッチャは適切なシーケンスを選択し、競合状態を排除しつつ命令数を最小限に抑えます。
パフォーマンス向上
- SHxADD –
命令(Zba 拡張)はシフトと加算を同時に実行でき、x86_64 のshxadd
に相当します。例:lea
slli t7, t7, 3 addi t1, t7, 15 add t1, t2, t1 ld t3, 0(t1)
→
sh3add t1, t7, t2 ld t3, 15(t1)
- 最適化されたポインタ展開 – 以前は 32 ビットオフセットをゼロ拡張するためにビット演算を行っていました。現在は
(Zba)を使用:zext.w
li t3,1 slli t3, t3, 32 addi t3, t3, -1 and a0, a0, t3
→
zext.w a0, a0
展開コストが 5 命令から 2 命令へ短縮されました。
- メインブランチとの同期 – 最近の RISC‑V コミットの約 4 分の 1 は、メイン V8 ブランチと整合性を保つためでした。小規模なピープル最適化(例:高 32 ビット乗算)やより複雑な変更が含まれます。
ベクトルサポート
Wasm SIMD は RISC‑V のベクトル拡張(RVV)にマッピングされました。初期は 128 ビットベクトルのみをサポートしていましたが、現在では 256 ビットおよび 512 ビットベクトルも扱えるようになりました。実際のハードウェアテストで C++ 呼び出し周辺のレジスタ保存/復元にバグが見つかり、修正されたことで JetStream ベンチマークスイート全体を正常に実行できるようになりました。
RISC‑V 32‑ビットの非推奨化
RISC‑V 32 ビットターゲットは主に Linux がほとんど利用されない小型組み込みシステム向けです。V8 は OS を必要とし、通常そのような環境で動作できないため、32 ビットポートは非推奨となりました。May 2026 まで保守されますが、強い需要が出るまでは継続します。
結論
V8 の RISC‑V ポートは大きく進化し、他のサポート対象アーキテクチャとほぼ同等の機能を実現しました。現在、JetStream ベンチマークスイート(約 33 MB Wasm バイトコードおよび約 200 万行の JavaScript)を完全に走らせることができ、プロダクションワークロードへの導入準備は整っています。