openjdk1.8工程結構

關於makefile,請參考《gcc&makefile基礎

目錄說明

openjdk源碼中有很多目錄,根據功能做了模塊化劃分,每個目錄實現其相應的功能。
每個目錄下的結構都差不多,分爲src(源碼)、make(makefile)、test(或沒有)、其他特殊目錄。

openjdk
│   common   一些公共文件,比如下載源碼的shell腳本、生成make的autoconf等文件
│   corba     分佈式通訊接口
└───hotspot  虛擬機實現
│   │   make makefile
│   │   test 單元測試文件
│   │   Agent  主要實現SA
│   └───src  源碼目錄
│       │   Cpu 處理器的代碼,主要按照Sparc、x86和Zero三種計算機體系結構
│       │   Os  操作系統的代碼,主要按照Linux、Windows、Solaris和Posix2
│       │   Os_cpu 同時依賴於操作系統和處理器的代碼,如Linux+Sparc、Linux+x86、Linux+Zero...等模塊。
│       └───Share  獨立於操作系統和處理器類型的代碼,這部分代碼是HotSpot工程的核心業務,實現了HotSpot的主要功能
│   │   │   │   Tools  獨立的虛擬機工具程序,如Hsdis...
│   │   │   └───vm 實現虛擬機各項功能
│   │   │   │   │  Adlc:平臺描述文件。
│   │   │   │   │  Libadt:抽象數據結構。
│   │   │   │   │  Asm:彙編器。
│   │   │   │   │  Code:機器碼生成。
│   │   │   │   │  C1:client編譯器,即C1編譯器。
│   │   │   │   │  Ci:動態編譯器。
│   │   │   │   │  Compiler:調用動態編譯器的接口。
│   │   │   │   │  Opto:Server編譯器,即C2編譯器。
│   │   │   │   │  Shark:基於LLVM實現的即時編譯器。
│   │   │   │   │  Interpreter:解釋器。
│   │   │   │   │  Classfile:Class文件解析和類的鏈接等。
│   │   │   │   │  Gc_interface:GC接口。
│   │   │   │   │  Gc_implementation:垃圾收集器的具體實現。
│   │   │   │   │  Memory:內存管理。
│   │   │   │   │  Oops:JVM內部對象表示。
│   │   │   │   │  Prims:HotSpot對外接口。
│   │   │   │   │  Runtime:運行時。
│   │   │   │   │  Services:JMX接口。
│   │   │   │   │  Utilizes:內部工具類和公共函數。
│   jaxp xml處理代碼
│   jaxws ws實現api
│   jaxp xml處理代碼
└───jdk源碼
│   │   make makefile
│   │   test 單元測試文件
│   └───src  源碼目錄
│       │   bsd bsd實現
│       │   linux linux實現
│       │   macosx macos實現
│       │   share 公用代碼
│       │   solaris solaris實現
│       │   windows window實現
└───langtools java語言工具實現,比如java, javac, javah, javap等
│   │   make makefile
│   │   test 單元測試文件
│   └───src  源碼目錄
│   │   └───share java源代碼
│   │   │   │   bin 模板 
│   │   │   │   sample 樣例源碼
│   │   │   └───classes java源碼文件
│   │   │   │   │   com 存放了java提供的一些基礎類實現,打包成tools.jar
│   │   │   │   │   javax
│   │   │   │   │   jdk
│   make make文件
│   nashorn java中js的運行時實現
│   test 測試文件

目標生成

java中提供的bin目錄下的java、javac、javap等都不是完全通過c/c++編寫實現的,是通過c/c++入口,啓動虛擬機加載class文件實現的相關功能。

所有java提供的工具程序(bin目錄下的可執行程序)入口都是jdk/src/bin/share/bin/main.c。
它們通過makeFile與jdk/src/share/bin/defines.h中的宏開關,來改變java的運行軌跡。

文件名爲:/openjdk/jdk/make/CompileLaunchers.gmk

$(eval $(call SetupLauncher,javadoc, \
    -DEXPAND_CLASSPATH_WILDCARDS \
    -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javadoc.Main"$(COMMA) }'))

$(eval $(call SetupLauncher,javah, \
    -DEXPAND_CLASSPATH_WILDCARDS \
    -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javah.Main"$(COMMA) }'))

$(eval $(call SetupLauncher,javap, \
    -DEXPAND_CLASSPATH_WILDCARDS \
    -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javap.Main"$(COMMA) }'))

BUILD_LAUNCHER_jconsole_CFLAGS_windows := -DJAVAW
BUILD_LAUNCHER_jconsole_LDFLAGS_windows := user32.lib

$(eval $(call SetupLauncher,jconsole, \
    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "-J-Djconsole.showOutputViewer"$(COMMA) "sun.tools.jconsole.JConsole"$(COMMA) }' \
    -DAPP_CLASSPATH='{ "/lib/jconsole.jar"$(COMMA) "/lib/tools.jar"$(COMMA) "/classes" }'))

$(eval $(call SetupLauncher,jdb, \
    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.example.debug.tty.TTY"$(COMMA) }' \
    -DAPP_CLASSPATH='{ "/lib/tools.jar"$(COMMA) "/lib/sa-jdi.jar"$(COMMA) "/classes" }'))

$(eval $(call SetupLauncher,jhat, \
    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.hat.Main"$(COMMA) }'))

$(eval $(call SetupLauncher,jinfo, \
    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) \
        "-J-Dsun.jvm.hotspot.debugger.useProcDebugger"$(COMMA) \
        "-J-Dsun.jvm.hotspot.debugger.useWindbgDebugger"$(COMMA) \
        "sun.tools.jinfo.JInfo"$(COMMA) }' \
    -DAPP_CLASSPATH='{ "/lib/tools.jar"$(COMMA) "/lib/sa-jdi.jar"$(COMMA) "/classes" }' \
    ,,,,,,,,,Info-privileged.plist))

$(eval $(call SetupLauncher,jmap, \
    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) \
        "-J-Dsun.jvm.hotspot.debugger.useProcDebugger"$(COMMA) \
        "-J-Dsun.jvm.hotspot.debugger.useWindbgDebugger"$(COMMA) \
        "sun.tools.jmap.JMap"$(COMMA) }' \
    -DAPP_CLASSPATH='{ "/lib/tools.jar"$(COMMA) "/lib/sa-jdi.jar"$(COMMA) "/classes" }' \
    ,,,,,,,,,Info-privileged.plist))

$(eval $(call SetupLauncher,jps, \
    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.tools.jps.Jps"$(COMMA) }'))

在makeFile文件可以看到各種熟悉的命令jps,jmap,javap等命令,但它們參數不同。

文件名爲:jdk/src/share/bin/defines.h

ifdef JAVA_ARGS
static const char* const_progname = "java";
static const char* const_jargs[] = JAVA_ARGS;
/*
 * ApplicationHome is prepended to each of these entries; the resulting
 * strings are concatenated (separated by PATH_SEPARATOR) and used as the
 * value of -cp option to the launcher.
 */
#ifndef APP_CLASSPATH
#define APP_CLASSPATH        { "/lib/tools.jar", "/classes" }
#endif /* APP_CLASSPATH */
static const char* const_appclasspath[] = APP_CLASSPATH;
#else  /* !JAVA_ARGS */
#ifdef PROGNAME
static const char* const_progname = PROGNAME;
#else
static char* const_progname = NULL;
#endif
static const char** const_jargs = NULL;
static const char** const_appclasspath = NULL;
#endif /* JAVA_ARGS */

#ifdef LAUNCHER_NAME
static const char* const_launcher = LAUNCHER_NAME;
#else  /* LAUNCHER_NAME */
static char* const_launcher = NULL;
#endif /* LAUNCHER_NAME */

#ifdef EXPAND_CLASSPATH_WILDCARDS
static const jboolean const_cpwildcard = JNI_TRUE;
#else
static const jboolean const_cpwildcard = JNI_FALSE;
#endif /* EXPAND_CLASSPATH_WILDCARDS */

#if defined(NEVER_ACT_AS_SERVER_CLASS_MACHINE)
static const jint const_ergo_class = NEVER_SERVER_CLASS;
#elif defined(ALWAYS_ACT_AS_SERVER_CLASS_MACHINE)
static const jint const_ergo_class = ALWAYS_SERVER_CLASS;
#else
static const jint const_ergo_class = DEFAULT_POLICY;
#endif /* NEVER_ACT_AS_SERVER_CLASS_MACHINE */
#endif /*_DEFINES_H */

如果定義了JAVA_ARGS宏,則會把jvm的參數從宏定義中獲取
此處參照/CompileLaunchers.gmk文件在聲明javac的地方,定義了該宏內容
-DJAVA_ARGS=’{ “-J-ms8m”(COMMA)"com.sun.tools.javac.Main"(COMMA) "com.sun.tools.javac.Main"(COMMA) }’)),
所以生成的elf文件javac中會得到該值爲{ “-J-ms8m”(COMMA)"com.sun.tools.javac.Main"(COMMA) "com.sun.tools.javac.Main"(COMMA) }

通過c/c++的main函數入口,創建jvm虛擬機後,通過執行相關功能的java代碼實現其功能,所以java相關的功能如編譯、運行、查看jvm信息等功能都是通過啓動一個jvm虛擬機或者通過jvmti等實現的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章