OpenJDK系列(一):编译/调试与项目结构

OpenJDK编译

之前的基于OpenJDK8的资料由于人为因素丢失了,索性就重新来过:以OpenJDK10为例.此外,如无特殊说明,开发平台皆为MacOS.最新文章见浮游.

源码下载

在mac平台上,可以通过HomeBrew进行OpenJDK源码的下载,以OpenJDK10为例.由于OpenJDK的源码采用mercurial进行管理,因此需要安装mercurial,另外由于编译需要,我们同时安装ccache和freetype工具:

 brew install mercurial
 brew install install ccache
 brew install freetype

接下来通过以下命令正式进行下载:

 hg clone http://hg.openjdk.java.net/jdk10/jdk10 OpenJDK10
 # 进入OpenJDK10目录下执行命令
 bash ./get_source.sh
image-20180903153521528

现在我们已经将所有的源码下载到本地了,接下来我们可以进行编译来满足下好奇心,

编译

在正式编译之前需要我们先配置编译信息,该过程通过configure.sh脚本实现,其存放在OpenJDK源码的根目录.使用该脚本需要制定一些参数参数,在mac平台下,配置如下:

./configure --with-target-bits=64 --with-freetype=/usr/local/Cellar/freetype/2.9.1 --enable-ccache --with-jvm-variants=server,client --with-boot-jdk-jvmargs="-Xlint:deprecation -Xlint:unchecked" --disable-zip-debug-info --disable-warnings-as-errors --with-debug-level=slowdebug 2>&1 | tee configure_mac_x64.log

注意不要写错freetype的路径,可以通过 brew list freetype命令来查看当前freetype的安装路径.

configure中提供了大量的参数,通过命令bash ./configure --help=short,当然你也可以直接查看OpenJDK的官方说明,这里我们只是简单介绍几个:

参数 含义
--with-target-bits 设置32为/64编译
--with-freetype 指定freetype目录
--with-jvm-variants=server,client 设置要构建的JVM的变体,目前可以选择server,client,minimal,core,zero,zeroshark,custom
--with-boot-jdk-jvmargs 设置运行boot JDK所需要的JVM参数,例如--with-boot-jdk-jvmargs="-Xmx8G"
--with-debug-level 调试等级,目前可以指定为release,fastdebug,是slowdebug,optimized

编译信息配置后之后,通过以下命令进行编译即可:

 export LANG=C
 make all LOG=debug 2>&1 | tee make_mac_x64.log

期间可能会遇到一些编译问题,大多可以官网找到方法,编译的产物会被存放在build目录下:

image-20180903161446477

执行以下命令,验证下编译结果

cd OpenJDK10/build/macosx-x86_64-normal-serverANDclient-slowdebug/jdk/bin
./java -version
image-20180903161734147

OpenJDK调试

对于OpenJDK调试而言,常用的工具有gdb和lldb,在MacOS使用更多的是lldb.直接使用lldb进行调试,相对比较原始,对于比较复杂的项目还可以借助Xcode或者CLion.

Xcode调试OpenJDK

以Xcode 9为例.

工程创建

首先使用Xcode创建一个新的项目OpenSDK10,为Command Line Tool类型.

step1

点击Next继续配置其他信息.

step2

创建完成后,先删除默认生成的文件.

step3

源码导入

右键OpenJDK10,选则Add Files To "OpenJDK10",将之前用于OpenJDK10的源码根目录下的文件都添加进来.

step4
step5

现在我们来配置下项目.选择Product -> Scheme -> Edit Scheme.在左侧的Run选项中先配置info标签页中的Executable,此处指定为之前我们已经编译好的java命令,按照我们之前的编译配置,此处路径即为:

/OpenJDK10/build/macosx-x86_64-normal-serverANDclient-slowdebug/jdk/bin/java

step9

接下来继续配置Arguments标签页中的Arguments Passed On Launch.随便写的一个Hello.java文件,如下内容:

public class Hello{
    public static void main(String[] args){
          System.out.println("Hello World !");
    }
}

然后将其放在java命令所在的目录,即上述提到的/OpenJDK10/build/macosx-x86_64-normal-serverANDclient-slowdebug/jdk/bin中,在该目录下执行'./javac Hello.java'将其编译成class文件.

step8

开始调试

到现在,所有的准备工作已经做好了,可以进行调试了.在main.c的main()打几个断点后开始调试.

step10

到现在已经可以正常调试了,但继续调试可能会遇到signal SIGSEGV错误

step11

此时只需要在lldb中设置(lldb) process handle SIGSEGV --stop=false,然后继续调试即可.

step12

不出意外,最终我们会在lldb控制台看到输出结果"Hello World ! ",如下:

step12

至此关于Xcode下调试OpenJDK源码的流程已经完成.

源码目录结构

OpenJDK源码结构如下:

image-20180903162039612
目录 说明
build OpenJDK编译产物
common
corba 包含corba功能源代码
hotspot 包含Hotspot虚拟机实现源码
jaxp jaxp功能的源代码,用于处理XML,提供了
jaxws jax-ws功能的源代码,用于构建Web服务的API
jdk 包含Java工具包
langtool 语言工具的源代码如javac,javap等
nashorn JavaScript引擎实现

hotspot

jdk是我们平时开发主要关注的地方,而hotspot使我们了解虚拟机重要的目录,下面我们来了解hotspot目录,重点来看其src子目录:

image-20180903163506096
目录 说明
make 编译流程控制
src VM源码
test 单元测试代码

src目录下包含了有关VM实现的代码:

image-20180903165531524

cpu

不同平台上CPU相关的代码,

image-20180903164728943

os

不同操作系统相关代码.根据不同的系统分为不同的目录

image-20180903164636220

os_cpu

操作系统和cpu组合的相关代码.

image-20180903164806923

share

与具体平台无关的代码.该目录下又分为tools和vm目录.其中tools中提供了相关工具代码.vm是虚拟机实现的核心代码.

image-20180903165455427

tools

目录 说明
hsdis 反汇编工具
idealGraphVisualizer 中间代码可视化工具
LogCompilation 将使用-XX:LogCompiliation输出的日志格式化更容易阅读的工具

vm

目录 说明
adlc 平台描述文件的编译器
aot aot编译器实现,用于静态编译
asm 汇编器接口
c1 Client编译器,即我们常说的C1编译器
ci 动态编译器公共接口
classfile 类文件处理
code 管理动态生成的代码
compiler VM调用动态编译器的接口
gc GC的实现,包含cms,g1,parallel,serial目录(对应四种GC器实现代码)以及有关GC器的公共代码实现目录shared
interpreter 解释器的实现,模板解释器和C++解释器
jvmci JVM编译器接口
libadt 抽象数据结构
logging VM通过日志记录系统
memory 内存管理相关
metaprogramming
oops HotSpot中关于对象系统的实现
opto Server编译器,即我们常说的C2编译器
precompiled
prims VM对外接口以及jvmti(用于调试)实现
runtime 运行时支持库,比如线程管理,锁,反射等
services 支持JMX之类的管理功能的接口
shark 基于LLVM的JIT编译器
trace
utilities 一些工具类代码
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容