Threads::create_vm

代码位于\hotspot\src\share\vm\runtime\Thread.cpp  Line 2891~Line 3226
这个方法是JVM初始化的主要方法,300多行代码,代码虽然很多,但是思路很清晰,比较容易阅读。
 
JVM初始化无外乎:解析参数、分配内存、创建内部数据结构、创建主线程、加载系统class等步骤。
这些代码均是相当好地被放在各个函数中,代码写的相对直白。
 
下面讲讲初次看这个方法,比较难理解的一个地方
Thread.cpp Line 3138
  SystemDictionary::compute_java_system_loader(THREAD);
这里面突然出现一个THREAD,很是突兀。
 
JVM是C++写成的,自然也继承了C的光荣传统:宏。
 
THREAD是宏,和它相关的宏还有:EXCEPTION_MARK、TRAPS、CHECK_0等。
它们均定义在:\hotspot\src\share\vm\utilities\exceptions.hpp
正如文件名exceptions.hpp所暗示的,这些宏和Exception处理有关系。这里的异常是指JVM代码中的异常,不是指Java程序的异常。
 
exceptions.hpp Line 270
#define EXCEPTION_MARK Thread* THREAD; ExceptionMark __em(THREAD);
 
exceptions.hpp Line 155
#define THREAD __the_thread__
 
所以THREAD实际上是 Thread* __the_thread__,这个变量在用VS调试的时候能清楚地通过IDE看到。
为了能使用THREAD必须首先使用宏:EXCEPTION_MARK
回到Thread::create_vm,在Line 3024处首先使用了EXCEPTION_MARK宏。
 
JVM代码中处理异常并没有使用C++的异常机制,而是用C的方式模拟了异常处理。
先看CHECK_0的定义
Exceptions.hpp Line179
#define CHECK_(result)         THREAD); if (HAS_PENDING_EXCEPTION) return result; (0
#define CHECK_0                CHECK_(0)
 
其中的HAS_PENDING_EXCEPTION的定义是
#define HAS_PENDING_EXCEPTION  (((ThreadShadow*)THREAD)->has_pending_exception())
是查询当前Thread是否有没有处理的异常,有的话就返回true。
 
CHECK_0的含义就是如果有没有处理的异常,就返回0。
 
再看一个CHECK_0的使用
Thread::create_vm, Line 3050
      initialize_class(vmSymbolHandles::java_lang_String(), CHECK_0);
 
initialize_class的原型是
static void initialize_class(symbolHandle class_name, TRAPS) {
  // ....
}
它的第二个参数是TRAPS,定义为
Exceptions.hpp Line 156
#define TRAPS  Thread* THREAD
 
那么代码initialize_class(vmSymbolHandles::java_lang_String(), CHECK_0);经过宏展开之后是:
initialize_class(vmSymbolHandles::java_lang_String(), __the_thread__);
if (((ThreadShadow*)__the_thread__)->has_pending_expection())
 return 0;
(0);
 
注意:上面的 (0); 不是我误写,是实实在在的宏产生的代码。
也就说initialize_class(vmSymbolHandles::java_lang_String(), CHECK_0);经过宏替换变成了三句代码。
第一句自然是对initialize_class的正常调用,其最后一个参数为__the_thread__
第二句是检查异常是否都已经被处理完毕。
第三句就是一个占位符性质的语句,什么也没有作,只是为了让产生的语句能顺利被编译,抵消多余的一个右括号。
 
是不是仍然有点迷糊?OK,我们再来一遍。
因为:#define CHECK_(result)   THREAD); if (HAS_PENDING_EXCEPTION) return result; (0
所以:CHECK_(0) <==> THREAD); if (HAS_PENDING_EXCEPTION) return 0; (0
 
因为:#define CHECK_0          CHECK_(0)
所以:CHECK_0 <==> THREAD); if (HAS_PENDING_EXCEPTION) return 0; (0
 
那么  initialize_class(... , CHECK_0);
 <==> initialize_class(... , THREAD); if (HAS_PENDING_EXCEPTION) return 0; (0);
 

总结一下
1、一个函数的最后一个参数是TRAPS, 则说明该函数需要应用到如上的异常处理场景。
2、为了让一个行数应用到如上场景,它只能是最后一个参数是TRAPS。否则经过宏替换后,不能正常编译。
3、在调用该函数之前,需要先用宏EXCEPTION_MARK来声明变量。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值