dalvik虚拟机解释器高频解释代码的加速

来源:互联网 发布:网络出租屋怎么赚钱的 编辑:程序博客网 时间:2024/05/21 00:55

             有些日子没写博客,后来发现做过的东西不记下来就忘了,还是恢复写博客的习惯。前两天将unicore dalvik解释器的汇编代码放入esram的工作。方式如下:

              首先,遇到的第一个问题:在汇编中有调用libdvm.so里面的c语句。而指令使用的是b.l。也就是相对pc的跳转。当这段代码放入esram后。要想到正确的内存地址,显然这种方式无法通过。所以只能逐个修改解释器调用c的部分,要做的工作还是挺多。而且要细心,万一一个地方漏了还是错了,查BUG要消耗大量的时间,所以还不如做的过程中慢一点,小心一点。              解决方式很简单:将所有的b.l   offset  替换为add lr,pc,#4;  ldr  pc, address。在arm中这是常用的长地址跳转的方式。我们的unicore也是类似的方式。

            第二个问题是如何得到函数的绝对地址:我们向Glue胶合结构中人为添加需要记录的函数,并在进程进入解释代码之前初始化。这样在汇编中直接方位Glue的偏移即可得到。

             第三个就是。映射esram空间。和各个进程只进行一次copy的问题。实现如下:

 87     if(fd == 0)
 88     {
 89         volatile unsigned int *fPtr,*fPtrtmp,*fPtr_check;
 90         fd = open("/dev/mem",O_RDWR);
 91         if(fd == -1)
 92         {
 93             LOGI("open /dev/mem error");
 94         }
 95         fPtr = (volatile unsigned int *)mmap(0,0x10000,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,fd,0x32000000);
 96 
 97         fPtrtmp = fPtr;
 98         fPtr_check = fPtr;
 99         if((*(volatile unsigned int *)fPtr_check) != (*(volatile unsigned int *)dvmMterpStdRun))  //避免多进程重复copy
100         {
101             /*
102             int iii = 0;
103             for(; iii < 0x10000/4;iii++)
104             {
105                 *fPtrtmp  = *((volatile unsigned int *)dvmMterpStdRun+iii);
106                 ++fPtrtmp;
107             }
108             */
109             memcpy(fPtrtmp,dvmMterpStdRun,0x10000);
110         }
111         tmp_xxx = (tmp_function)fPtr;  //注意这里的tmp_xx必须是全局变量。
112         int  jjj  = 0;
113         for(; jjj < 10;jjj++)
114         {
115             LOGI("abc123 = %08x",*((volatile unsigned int *)tmp_xxx+jjj));
116         }
117         //memcpy(tmp_xxx,dvmMterpStdRun,0x10000);
118         LOGI("aftermemcpy");
119         LOGI("dvmMterpStdRun = %p",dvmMterpStdRun);
120         LOGI("esram_mmap_address = %p",fPtr);
121 
122         //dvmMterpStdRun = tmp;
123     }

              。。。

              。。。

             change = tmp_xxx(rGlue);  //原来是 change = dvmMterpStdRun(rGlue);

              。。。

发现做起来的时候很多细节消耗很多时间。比如映射esram映射的时候忘了PROT_WRITE。而有趣的是我们还用memcpy向里面copy数据。结果遇到esram映射的初始地址android就崩了。   再比如:tmp_xxx一开始只是局部变量。结果dalvik每次只运行一次第二次就挂了。后来才想起来tmp_xxx第二次进去的时候就是个不定值,自然会挂。还有很多,所以做事不仅仅要细心,还需要养成习惯,就比如这个tmp_xxx。说到底还是对编程理念没有宏观性的把握。遇到的这些问题虽然很弱,却反映的自身很多的问题。

             

              

原创粉丝点击