此处同样,对应的字节码是CUSTOMCODE,其最终调用的是initInitialThreadBehaviorFromThread.此处的代码如下:
static void
initInitialThreadBehaviorFromThread(FRAME_HANDLE exceptionFrameH) {
INSTANCE_CLASS thisClass;
METHOD thisMethod;
// 1. 如果有异常,则直接return
if (exceptionFrameH != NULL) {
/* We have no interest in dealing with exceptions. */
return;
}
thisClass = secondStackAsType(INSTANCE_CLASS);// 获得主类名称
// 2. 获得main方法
thisMethod = getSpecialMethod(thisClass, mainNameAndType);
if (thisMethod == NULL) {// 如果main方法不存在,则终止执行
AlertUser(KVM_MSG_CLASS_DOES_NOT_HAVE_MAIN_FUNCTION);
stopThread(http://www.amjmh.com/v/);
} else if ((thisMethod->accessFlags & ACC_PUBLIC) == 0) {// 如果main方法的修饰符不是public,则终止执行
AlertUser(KVM_MSG_MAIN_FUNCTION_MUST_BE_PUBLIC);
stopThread();
} else {
START_TEMPORARY_ROOTS
/*
* ARRAY arguments = (
arguments = (*(ARRAY *)((GlobalState.gs_sp))),
TemporaryRoots[TemporaryRootsLength++].cellp = (cell *)&arguments,
arguments)
*/
DECLARE_TEMPORARY_ROOT(ARRAY, arguments, topStackAsType(ARRAY));
/* Reinitialize the thread for the new method 3. 由于此处是最后一个栈帧,则需要做一些初始化工作*/
setSP((CurrentThread->stack->cells - 1) + thisMethod->argCount); // 复用参数
setFP(NULL);
setIP(KILLTHREAD);
pushFrame(thisMethod);
((ARRAY *)getLP())[0] = arguments;
END_TEMPORARY_ROOTS
// 4. 对同步的处理
if (thisMethod->accessFlags & ACC_SYNCHRONIZED) {
getFP()->syncObject = (OBJECT)thisClass;
monitorEnter((OBJECT)thisClass);
} else {
getFP()->syncObject = NULL;
}
}
}
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
这里比较重要的是第3步.由于当前是最后一个栈帧,因此将sp设置为(CurrentThread->stack->cells - 1) + thisMethod->argCount.(为何这样设置,是因为就相当于隐式弹栈一样)。此时的情况如图所示
————————————————