Overview of Classfile Constant Pool
Take abstract syntax tree for method type signatures and constants
- serialize it as a graph
To see it, use
javap -verbose
Cafebabe does most of these things for you
- can unzip Scala source code to see how
Documentation is in JVM Spec, Class File Format
Example
The most complex part is constant pool, which is an acyclic directed graph whose nodes have a tag and content. The tag indicates the nature of the cell, and the content can be e.g. a tuple of pointers to other cells, or a zero-terminated sequence of characters. See constant pool definition.
class Factorial { public int fact(int num){ int num_aux; if (num < 1) num_aux = 1 ; else num_aux = num * (this.fact(num-1)); return num_aux; } } class Calls { public static void main(String[] args) { Factorial f = new Factorial(); System.out.println("Result is: " + f.fact(6)); } }
Result of javap -v:
Compiled from "Calls.java" class Calls extends java.lang.Object SourceFile: "Calls.java" minor version: 0 major version: 50 Constant pool: const #1 = Method #14.#23; // java/lang/Object."<init>":()V const #2 = class #24; // Factorial const #3 = Method #2.#23; // Factorial."<init>":()V const #4 = Field #25.#26; // java/lang/System.out:Ljava/io/PrintStream; const #5 = class #27; // java/lang/StringBuilder const #6 = Method #5.#23; // java/lang/StringBuilder."<init>":()V const #7 = String #28; // Result is: const #8 = Method #5.#29; // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; const #9 = Method #2.#30; // Factorial.fact:(I)I const #10 = Method #5.#31; // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; const #11 = Method #5.#32; // java/lang/StringBuilder.toString:()Ljava/lang/String; const #12 = Method #33.#34; // java/io/PrintStream.println:(Ljava/lang/String;)V const #13 = class #35; // Calls const #14 = class #36; // java/lang/Object const #15 = Asciz <init>; const #16 = Asciz ()V; const #17 = Asciz Code; const #18 = Asciz LineNumberTable; const #19 = Asciz main; const #20 = Asciz ([Ljava/lang/String;)V; const #21 = Asciz SourceFile; const #22 = Asciz Calls.java; const #23 = NameAndType #15:#16;// "<init>":()V const #24 = Asciz Factorial; const #25 = class #37; // java/lang/System const #26 = NameAndType #38:#39;// out:Ljava/io/PrintStream; const #27 = Asciz java/lang/StringBuilder; const #28 = Asciz Result is: ; const #29 = NameAndType #40:#41;// append:(Ljava/lang/String;)Ljava/lang/StringBuilder; const #30 = NameAndType #42:#43;// fact:(I)I const #31 = NameAndType #40:#44;// append:(I)Ljava/lang/StringBuilder; const #32 = NameAndType #45:#46;// toString:()Ljava/lang/String; const #33 = class #47; // java/io/PrintStream const #34 = NameAndType #48:#49;// println:(Ljava/lang/String;)V const #35 = Asciz Calls; const #36 = Asciz java/lang/Object; const #37 = Asciz java/lang/System; const #38 = Asciz out; const #39 = Asciz Ljava/io/PrintStream;; const #40 = Asciz append; const #41 = Asciz (Ljava/lang/String;)Ljava/lang/StringBuilder;; const #42 = Asciz fact; const #43 = Asciz (I)I; const #44 = Asciz (I)Ljava/lang/StringBuilder;; const #45 = Asciz toString; const #46 = Asciz ()Ljava/lang/String;; const #47 = Asciz java/io/PrintStream; const #48 = Asciz println; const #49 = Asciz (Ljava/lang/String;)V; { Calls(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 11: 0 public static void main(java.lang.String[]); Code: Stack=4, Locals=2, Args_size=1 0: new #2; //class Factorial 3: dup 4: invokespecial #3; //Method Factorial."<init>":()V 7: astore_1 8: getstatic #4; //Field java/lang/System.out:Ljava/io/PrintStream; 11: new #5; //class java/lang/StringBuilder 14: dup 15: invokespecial #6; //Method java/lang/StringBuilder."<init>":()V 18: ldc #7; //String Result is: 20: invokevirtual #8; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 23: aload_1 24: bipush 6 26: invokevirtual #9; //Method Factorial.fact:(I)I 29: invokevirtual #10; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 32: invokevirtual #11; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 35: invokevirtual #12; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 38: return LineNumberTable: line 13: 0 line 14: 8 line 15: 38 }