Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RubyでJVMを実装してみる / Implement JVM with Ruby

Daiki Miura
December 14, 2019

RubyでJVMを実装してみる / Implement JVM with Ruby

Daiki Miura

December 14, 2019
Tweet

More Decks by Daiki Miura

Other Decks in Technology

Transcript

  1. JVMを実装とは To implement the Java Virtual Machine correctly, you need

    only be able to read the class file format and correctly perform the operations specified therein. The Java® Virtual Machine Specification: Chapter 2. The Structure of the Java Virtual Machine, https://docs.oracle.com/javase/specs/jvms/se13/html/jvms-2.html Java仮想マシン (JVM) を正しく実装するには、クラスファイル形式を読み 取って、そこに指定されている命令を正しく実行する必要があるだけです。
  2. クラスファイルの読み取り The Java® Virtual Machine Specification: Chapter 4.1. The ClassFile

    Structure, https://docs.oracle.com/javase/specs/jvms/se13/html/jvms-4.html#jvms-4.1 ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; } u4: 符号なし4バイト量 u2: 符号なし2バイト量 ① ② ③ ③ ① ④ ② ④
  3. クラスファイルの読み取り Constant Pool ClassFile { u4 magic; u2 minor_version; u2

    major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; } The Java® Virtual Machine Specification: Chapter 4.1. The ClassFile Structure, https://docs.oracle.com/javase/specs/jvms/se13/html/jvms-4.html#jvms-4.1
  4. クラスファイルの読み取り Constant Pool The Java® Virtual Machine Specification:Chapter 4.4. The

    Constant Pool, https://docs.oracle.com/javase/specs/jvms/se13/html/jvms-4.html#jvms-4.4 Tag Constant Kind 7 CONSTANT_Class 9 CONSTANT_Fieldref 10 CONSTANT_Methodref 11 CONSTANT_InterfaceMethodref 8 CONSTANT_String 3 CONSTANT_Integer 4 CONSTANT_Float 5 CONSTANT_Long 6 CONSTANT_Double 12 CONSTANT_NameAndType 1 CONSTANT_Utf8 15 CONSTANT_MethodHandle 16 CONSTANT_MethodType 17 CONSTANT_Dynamic 18 CONSTANT_InvokeDynamic 19 CONSTANT_Module 20 CONSTANT_Package cp_info { u1 tag; u1 info[]; }
  5. クラスファイルの読み取り 同様にして 仕様を片手にクラスファイルをパースしていく ClassFile { u4 magic; u2 minor_version; u2

    major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; } The Java® Virtual Machine Specification: Chapter 4.1. The ClassFile Structure, https://docs.oracle.com/javase/specs/jvms/se13/html/jvms-4.html#jvms-4.1
  6. Code_attribute { u2 attribute_name_index; u4 attribute_length; u2 max_stack; u2 max_locals;

    u4 code_length; u1 code[code_length]; u2 exception_table_length; { u2 start_pc; u2 end_pc; u2 handler_pc; u2 catch_type; } exception_table[exception_table_length]; u2 attributes_count; attribute_info attributes[attributes_count]; } method_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attribute_info attributes[attributes_count]; } ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; } 命令列の実行 どこに格納されてるのか? 05 3c b2 00 07 1b b6 00 0d b1
  7. 命令の形式 A Java Virtual Machine instruction consists of an opcode

    specifying the operation to be performed, followed by zero or more operands embodying values to be operated upon. This chapter gives details about the format of each Java Virtual Machine instruction and the operation it performs. The Java® Virtual Machine Specification: Chapter 6. The Java Virtual Machine Instruction Set, https://docs.oracle.com/javase/specs/jvms/se13/html/jvms-2.html 実行する操作を指定するオペコードと 0個以上の操作対象の値を指定するオペラン ド
  8. 命令列の構造 05 3c b2 00 07 1b b6 00 0d

    b1 iconst_2 `2`(int型の値)をオペラ ンドスタックにプッシ ュする istore_1 ローカル変数にint型の 値をストアする getstatic クラスのstaticフィールド (Rubyのクラス変数のような もの)を取得してオペランド スタックにプッシュする iload_1 ローカル変数からint型の 値をロードする invokevirtual メソッドを呼び出す return メソッドからvoid をリターンする オペランド オペランド
  9. 命令列の実行 iconst_2 `2`(int型の値)をオペランドスタックにプッシュする istore_1 ローカル変数配列の1番目にint型の値をストアする getstatic クラスのstaticフィールド(Rubyのクラス変数のような もの)を取得してオペランドスタックにプッシュする iload_1 ローカル変数配列の1番目からint型の値をロードする

    invokevirtual メソッドを呼び出す return メソッドからvoidをリターンする 2 java/lang/Syste m.out java/lang/Syste m.out 2 オペランドスタック ローカル変数配列 (0番目にはmainメソッド呼び出し 時の引数が入っている) 0x0007 Constant Poolの7番目 (java/lang/System.out) 0x000d Constant Poolの13番目 (println) [ [] ] [ [] ] [ [], 2 ] [ [], 2 ] [ [] ] [ [] ] [ [] ] 2 java/lang/Syste m.out 2
  10. パフォーマンス比較 Java HotSpot(TM) 64-Bit Server VM (build 13.0.1+9, mixed mode,

    sharing) ・user(ユーザーモードで動作した時間)が長い ・そもそも無駄な処理が走ってる? ・パフォーマンスの悪いコードを書いてしまった? ・Ruby vs C++ ? ・sys(カーネルモードで動作した時間)が長い ・無駄なファイル読み込みがある ・クラスファイルをパースするときにめっちゃ IO#read を呼んでる) 自作JVM (ruby 2.7.0-preview3)
  11. 参考資料 ・The Java® Virtual Machine Specification ・Java仮想マシン仕様 (The Java series)

    ・セルフホストで学ぶJVM入門 ・jjvm ・PHP で JVM を実装して Hello World を出力するまで ・php-java ・ferrugo ・rust-jvm