OpenJDK ソースコードリーディング

自分用メモ。Ubuntu bionicでビルドできた最小バージョンのjdk-12-ga (jdk-12+33)を読んでいる。

## 関連リソース
* [OpenJDK の設計と実装に関する備忘録](http://hsmemo.github.io/index.html)
* [Java 起動(Launcher)の仕組み](http://cco.hatenablog.jp/entry/2014/11/04/024712)
* [JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」](https://www.slideshare.net/torazuka/jvm-28095989)
  * [HotSpotのディレクトリ構造](https://www.slideshare.net/torazuka/jvm-28095989#s=43) - `src/` は `src/hotspot/` に移った?
* [HotSpot Runtime Overview](https://openjdk.java.net/groups/hotspot/docs/RuntimeOverview.html)
  * [VM Lifecycle](http://openjdk.java.net/groups/hotspot/docs/RuntimeOverview.html#VM%20Lifecycle%7Coutline)
* [徹底解剖「G1GC」実装編](http://www.narihiro.info/g1gc-impl-book/)
  * [1.4. ソース構成](http://www.narihiro.info/g1gc-impl-book/prepare.html#h1-4)
* [OpenJDKのビルドやデバッグ](https://blog.tiqwab.com/2019/07/08/openjdk-build.html)
* [Hotspot VMの基本構造を理解する](https://www.atmarkit.co.jp/ait/articles/0403/11/news096.html)
* [DEMYSTIFYING THE JVM: JVM VARIANTS, CPPINTERPRETER AND TEMPLATEINTERPRETER](https://metebalci.com/blog/demystifying-the-jvm-jvm-variants-cppinterpreter-and-templateinterpreter/)
* [Hotspot JVMの圧縮OOP](https://www.oracle.com/technetwork/jp/articles/java/compressedoops-427542-ja.html)

## ディレクトリ構造
* src/
  * hotspot/
     * cpu: x86 など
     * os: linux など
     * os_cpu: linux_x86 など
     * share/
         * adlc: C2 JITのプラットフォーム依存コード生成 ADLC
         * asm: アセンブラのアーキテクチャ非依存部
         * c1: C1 JITコンパイラ
         * ci: (JIT) Compiler Interface
         * classfile: クラスファイルの実装
         * code: CodeCache領域
         * compiler: JIT管理用スレッド
         * gc: G1GC, Parallel GC, ZGC など
         * interpreter: C++インタプリタ, テンプレートインタプリタ
         * libadt: ALDCが使うデータ構造
         * memory: ヒープ管理
         * oops: オブジェクトの管理ポインタ (Ordinary Object Pointer)
         * opto: C2 JITコンパイラ
         * prims: JNIのAPIなど
         * runtime: JVMスレッド作成など
  * java.base/
     * share/
         * classes/
               * java.lang: Object, String, Integerなど
               * java.util: List, Map, Setなど
         * native/
               * launcher/main.c: javaコマンドのエントリポイント
               * libjli/java.c: javaコマンドの実際の実装
  * jdk.internal.vm.compiler: Graal

## インタプリタが起動されるまで
### 1. javaコマンド
* `main()`: src/java.base/share/native/launcher/main.c
  * libjliの`JLI_*` なAPIが呼び出され、コマンドライン引数処理の準備がされる
  * 最後に `JLI_Launch` を呼んで終わり (ここが本体)

### 2. Java Launcher Infrastructure: libjli

* `JLI_Launch()`: src/java.base/share/native/libjli/java.c
  * LoadJavaVM(): libjvm.so をダイナミックロードするらしい
  * JVMInit(): これは src/java.base/unix/native/libjli/java_md_solinux.c にある
     * ContinueInNewThread()
         * ContinueInNewThread0(JavaMain, ...): これも share ではなく unix
              * pthread_create で JavaMain() が呼び出される
              * pthread_join で JavaMain() の終了を待つ
* `JavaMain()`: src/java.base/share/native/libjli/java.c
  * InitializeJVM()
     * JNI_CreateJavaVM(): ここまでlibjli内
         * JNI_CreateJavaVM_inner(): src/hotspot/share/prims/jni.cpp
              * Threads::create_vm(): src/hotspot/share/runtime/thread.cpp
                    * 14くらい新たにスレッドが作られる。ここで何回かSEGV
  * LoadMainClass(): Main-Class を取得する
  * GetStaticMethodID(): そのmainClassからstaticなmainメソッドを探索、methodIDを取得
  * CallStaticVoidMethod() を呼ぶ

### 3. Java Virtual Machine: libjvm
以下はC++インタプリタでのフロー。templateインタプリタだと`StubGenerator::call_stub`のところから動的生成コードになる。

* `jni_CallStaticVoidMethod()`: src/hotspot/share/prims/jni.cpp
  * jni_invoke_static()
     * Method::resolve_jmethod_id(): methodIDから `methodHandle method` が取り出される
     * JavaCalls::call(): src/hotspot/share/runtime/javaCalls.cpp
         * JavaCalls::call_helper()
              * StubGenerator::call_stub(): src/hotspot/cpu/zero/stubGenerator_zero.cpp
                   * CppInterpreter::invoke_method(): src/hotspot/share/interpreter/cppInterpreter.cpp
                       * ZeroEntry::invoke(): src/hotspot/cpu/zero/entry_zero.hpp
                            * CppInterpreter::normal_entry(): src/hotspot/cpu/zero/cppInterpreter_zero.cpp
                                 * CppInterpreter::main_loop()
                                      * BytecodeInterpreter::run(): hotspot/share/interpreter/bytecodeInterpreter.cpp