Jet最关注的是它的性能,在jet生成的code中,如何来检查safepoint,在hotstpot里,在它启动的时候,会先申请一个全局的polling page的这一个页,是一个4k大小的页,然后在jit生成的代码中,在某些特定的一个点,它会生成一两条指令,直接去访问页,就去读一下页里面这个内容是不是可读,特定点大概有两个,第一个是在jit code的返回的时候,在return的地方会去检查一次;另一个是循环,如果代码里面有循环,它会在循环的 loop的back edge中,他\也会去检查一次,只在这两个点上去做检查,一方面是确保他\检查尽可能的少,另一方面要确保它的jit能够及时的响应 safepoint的请求,本身只是读一下,并没有做任何的动作,这里如何把自己给停下来,就是 vm Thread开始要触发sfepoint的时候,会做一个动作,会把全局的pulling page把他的权限给改了,会用n protect类似于的API把权限设成不可访问。 这样如果读取polling page的这条指令就会触发一次SIGSEGV的异常,但 hotstpot本身在 signal handle里面,会对这种SIGSEGV做进行一些特殊处理,它会捕获住这种异常,会看触发异常的地址,是不是polling page ,然后如果是个polling page的,就知道是jit里面触发的 safepoint,所以这里并不是一个真正的异常,而是一次safepoint的请求。 后续的操作,会把 Java线程给暂停,然后把自己的状态标志为已经进入了 safepoint。 如下图所示这段jit深层的代码,里面有一个 Loop的polling,又有一个 return的polling,可以看这两条test的指令,用红框标出来的,最上面的是一个 polling是一个在back edge中他用来做polling的,其实只是做一次test,把 polling地址放到了20寄存器中,然后就去读一下test一下,后续对这个其实根本没有任何操作, Test的结果对他来说没有任何作用,就是为了去读一次,能读这个代码就可以继续往下执行。
下面的一条test,旁边的标注是poll return,紧接着下面就是一个return的指令,所以这一条指令就是在return之前,也会去做一次polling,来判断下是不是有人在发起了 safepoint的请求。 这就是在jit code中,大概会在这样的两个地方去做 polling,第二个test,如果看上一条,可能会看到20的地址其实是从二十五中读取了一个偏移量过来,25在现在X86的hotstpot,主要是用来做一个thread,所以它其实是从thread中去读了一个。 这里说明一下,牵涉到新的一个 jdk10引入了一个技术,引入了一个叫thread local handkerchief,因为上述的 polling page是global的,实际上把 global的page把它作为这个地址记下来,然后每次polling的时候就直接去访问这个地址,这就是一个常量,根本没有任何动作不需要去到thread上去读。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。