作者 [email protected]
在dalvik运行时每个函数也是有自己的Frame的,首先分析在dalvik源码里描述了对Frame结构的描述:
Low addresses (0x00000000)
+- - - - - - - - -+
- out0 -
+-----------------+ <-- stack ptr (top of stack)
+ VM-specific +
+ internal goop +
+-----------------+ <-- curFrame: FP for cur function
+ v0 == local0 +
+-----------------+ +-----------------+
+ out0 + + v1 == in0 +
+-----------------+ +-----------------+
+ out1 + + v2 == in1 +
+-----------------+ +-----------------+
+ VM-specific +
+ internal goop +
+-----------------+ <-- frame ptr (FP) for previous function
+ v0 == local0 +
+-----------------+
+ v1 == local1 +
+-----------------+
+ v2 == in0 +
+-----------------+
+ v3 == in1 +
+-----------------+
+ v4 == in2 +
+-----------------+
- -
- -
- -
+-----------------+ <-- interpStackStart
High addresses (0xffffffff)
其中寄存器分配规则是由dalvik编译器决定的。而VM-specific internal goop就是“struct StackSaveArea”,该结构定义如下:
struct StackSaveArea {
…
/* saved frame pointer for previous frame, or NULL if this is at bottom */
u4* prevFrame;
/* saved program counter (from method in caller's frame) */
//该PC指针为并不是二进制的r15,而是当前字节码地址
const u2* savedPc;
/* pointer to method we're *currently* executing; handy for exceptions */
const Method* method;
union {
/* for JNI native methods: bottom of local reference segment */
u4 localRefCookie;
/* for interpreted methods: saved current PC, for exception stack
* traces and debugger traces */
const u2* currentPc;
} xtra;
/* Native return pointer for JIT, or 0 if interpreted */
const u2* returnAddr;
…
};
“struct StackSaveArea”作用如下:
保存当前字节码的地址到其成员变量“xtra. currentPc”
#define EXPORT_PC() \
str rPC, [rFP, #(-sizeofStackSaveArea + offStackSaveArea_currentPc)]
其中offStackSaveArea_currentPc被定义为12,sizeofStackSaveArea即为“struct StackSaveArea”结构的size。rFP为当前帧基地址,参考上一节的Frame结构,“[rFP, #(-sizeofStackSaveArea + offStackSaveArea_currentPc)]”为“xtra. currentPc”所在地址。