Compiler JDK8

下載jdk8

開啟終端機,在Downloads目錄下,執行以下句子。

git clone https://github.com/openjdk/jdk8u

安裝一些工具

# 安装基础编译工具和依赖
brew install autoconf freetype ccache pkg-config

xcode-select --install  # 确保Xcode命令行工具已安装

binutils

brew install binutils

echo 'export PATH="/usr/local/opt/binutils/bin:$PATH"' >> ~/.zshrc

# 立即生效
source ~/.zshrc

下載jdk7

為什麼要下載jdk7呢?

編譯的時候需要jdk8的前一個版本的jdk。

我是mac,我下載的bin目錄的位置在此處。

/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home

暫時設定Java Home

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home
## 檢查版本
$JAVA_HOME/bin/java -version

要確保印出以下內容

java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

編譯

進到jdk8的目錄

cd jdk8u
# 确保使用绝对路径
export OBJCOPY=$(which objcopy)

# 完整配置命令(必须在一行)
bash configure \
    --with-boot-jdk=$JAVA_HOME \
    --with-debug-level=slowdebug \
    --enable-debug-symbols \
    --with-native-debug-symbols=internal \
    OBJCOPY=$OBJCOPY

make

make JOBS=2 images

若要重新make,請先clean

make clean
rm -rf build

檢查PrintVtables功能

檢查是否可以用PrintVtables功能

 ./build/macosx-x86_64-normal-server-slowdebug/jdk/bin/java -XX:+UnlockDiagnosticVMOptions -XX:+PrintVtables 

JAVA_HOME

把build目錄中的編譯好的macosx-x86_64-normal-server-slowdebug,更改名jdk8_debug

修改zshrc

vi ~/.zshrc
export JAVA_HOME=/Users/cici/Downloads/jdk8u/build/jdk8_debug/jdk
export PATH=$JAVA_HOME/bin:$PATH
source ~/.zshrc

檢查版本

java -version 
openjdk version "1.8.0_462-internal-debug"
OpenJDK Runtime Environment (build 1.8.0_462-internal-debug-cici_2025_05_27_10_21-b00)
OpenJDK 64-Bit Server VM (build 25.462-b00-debug, mixed mode)

測試

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintVtables PolyExample

測試檔案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Animal {
    public void speak() { System.out.println("Animal"); }
    public void eat() { System.out.println("Animal eats"); }
}

class Dog extends Animal {
    @Override public void speak() { System.out.println("Dog"); }
    @Override public void eat() { System.out.println("Dog eats"); }
}

class SuperDog extends Dog {
    @Override public void speak() { System.out.println("SuperDog"); }
    @Override public void eat() { System.out.println("SuperDog eats"); }
}

public class TestVtable {
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 10000; i++) {
            Animal a = getAnimal(i);
            a.speak();
            a.eat();
        }
        Thread.sleep(300_000); // 等待觀察
    }

    public static Animal getAnimal(int i) {
        if (i % 2 == 0) return new SuperDog();
        else return new Dog();
    }
}

編譯

./build/macosx-x86_64-normal-server-slowdebug/jdk/bin/javac TestVtable

執行

./build/macosx-x86_64-normal-server-slowdebug/jdk/bin/java \
  -Xcomp \
  -XX:+UnlockDiagnosticVMOptions \
  -XX:+PrintVtables \
  -XX:+TraceClassLoading \
  -XX:+TraceClassInitialization \
  TestVtable 2>&1 | tee vtables.log

檔案中尋找vtable

grep -i vtable vtables.log
grep -A10 'Vtable for class' vtables.log

results matching ""

    No results matching ""