要用PrintAssembly的目的 应该会另开帖子说明,本帖只是为了记录为了简单的记录使用这个命令遇到的问题.
1 ,直接使用,用的是
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)
该版本,当然,必须用不了咯..继续google.发现,需要用fastjson版本的jdk.然后,继续找.
2,找到对应的下载地址. http://download.java.net/jdk6/6u25/promoted/b03/index.html
注意,需要下载debug版本的.下载下来是一个jar,双击运行.然后就可以安装.
这里下载的b03版本,有可能在window下跑不通,每次运行都会造成jvm crash.可以换一下b01的试试
http://download.java.net/jdk6/6u25/promoted/b01/index.html
3 然后,就运行试试.继续遇到问题
MOptions -XX:+PrintAssembly Test
VM option '+UnlockDiagnosticVMOptions'
VM option '+PrintAssembly'
Java HotSpot(TM) Client VM warning: PrintAssembly is enabled; turning on DebugNo
nSafepoints to gain additional output
Could not load hsdis-i386.dll; library not loadable; PrintAssembly is disabled
4 后续就是找hsdis-i386.dll 的问题了.这也是我用时间最久的地方.我按照stackoverflow的说明,自己build这货,但是死的很惨,一直没成功.具体就不多说了,最后还是万能的撒迦告诉了我答案.
这个疑问在之前某帖的回复里有提到:HotSpot的JIT编译器遇到简单无限循环时
是的,这个是由GNU binutils里的as提供反汇编功能。
Sun HotSpot需要一个反汇编插件才可以使用-XX:+PrintAssembly参数来打印JIT编译生成的代码。该插件有一组通用接口,本来是可以用任意反汇编器套个适配器就行。官方提供了一个现成的版本(hsdis)是基于gas的,我懒于是就直接用它了。在Windows上直接build我还没成功过,用MinGW和Cygwin都试过不行。我用的版本是在Ubuntu上cross-compile出来的,根据插件作者提供的cross-compile指引来做没有遇到问题。
编译出来的hsdis-i386.dll放到JDK安装目录中jre/bin/server和jre/bin/client中即可。
不太记得是不是从Sun JDK 6 update 20开始,在product build的HotSpot里要用-XX:+PrintAssembly参数必须同时带上-XX:+UnlockDiagnosticVMOptions参数才可以。
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly YourMainClass
debug与fastdebug build就不用带。
而在比较老的Sun JDK 6里这个插件的名字要改为hdis-i486.dll才行。具体是从哪个版本开始变的我可以回头查查看。
如果有人需要我编译好的这个插件的话,待会儿可以上传一个到圈子共享里。
已经上传到圈子的共享里了
OpenJDK 7里可以看到还有另外一个附加的选项,-XX:PrintAssemblyOptions,可以用来向反编译插件传递参数。
借助HotSpot SA来反汇编
这帖提到的也是其中一个办法。看图:
=======================================
上面是针对Sun JDK的HotSpot而言。
JRockit的话要用别的办法,不过由于Oracle在输出的日志里说那信息是confidential的,所以抱歉我不能在这里说。
IBM J9的话我还没找到简单的办法。
Harmony、Jikes RVM、Maxine这些都有提供命令行参数可以让JVM把动态编译的汇编吐出来。
然后 在JE的虚拟机圈子里找到了下载链接.
http://hllvm.group.iteye.com/group/share
最后就是下载对应的 hsdis-i386.dll ,在DK目录下jre/bin/client和jre/bin/server中各放一份 .这个问题终于搞定..
在实际的使用中,我们通过直接加-XX:+PrintAssembly 打印ASM码会有两个问题
1 ASM码非常多.因为系统会打印出类似loadclass toString对应这些方法的ASM码.但是我们可能只关心对应的某一个方法而已.系统会打印8W行+的输出,但是我们可能只关心里面的100行
2 经常会帮我们内联.这个其实很纠结.之前为了这个内联,每次都想方设法如何让方法不被内联.当然,对应的解决方法也很简单.
对应的代码(我懒得自己写,就直接copy网上的了)
public class Test{ int a = 1; static int b = 2; public int sum(int c){ return a + b + c; } public static void main(String[] args){ new Test().sum(3); } }
运行的代码如下
其中,
-XX:CompileCommand=dontinline,*Test.sum 这个表示不要把sum方法给内联了.这是解决内联问题
-XX:CompileCommand=compileonly,*Test.sum 这个表示只编译sum方法,这样的话,只会输出sum方法的ASM码.
对应的输出如下
VM option '+PrintAssembly'
VM option 'CompileCommand=dontinline,*Test.sum'
VM option 'CompileCommand=compileonly,*Test.sum'
CompilerOracle: dontinline *Test.sum
CompilerOracle: compileonly *Test.sum
Loaded disassembler from D:\software\jdk6_fastdebug\jdk1.6.0_25\fastdebug\jre\bin\client\hsdis-i386.dll
Decoding compiled method 0x026ab608:
Code:
[Disassembling for mach='i386']
[Entry Point]
[Constants]
# {method} 'sum' '(I)I' in 'Test' //这个好理解,记录一下这个方法名对应的描述符
# this: ecx = 'Test' //表示this指针在ecx寄存器中
# parm0: edx = int //sum 方法对应的参数在edx寄存器中.
# [sp+0x20] (sp of caller)
;; block B1 [0, 0]
0x026ab700: nop
0x026ab701: nop
0x026ab702: nop
0x026ab703: nop
0x026ab704: nop
0x026ab705: nop
0x026ab706: nop
0x026ab707: cmp 0x4(%ecx),%eax
0x026ab70a: jne 0x0266ad90 ; {runtime_call}
[Verified Entry Point]
0x026ab710: mov %eax,-0x8000(%esp) //检查栈溢出
0x026ab717: push %ebp //保存上一栈帧基址
0x026ab718: sub $0x18,%esp ;*aload_0 //给新栈帧分配空间.这个18很奇怪,我试了好多,无聊方法写成什么样,都是$0x18.
; - Test::sum@0 (line 13)
;; block B0 [0, 10]
0x026ab71b: mov 0x8(%ecx),%eax ;*getfield a //获取实例变量a,放入eax寄存器中, %ecx在上面已经说了,是存放this指针的寄存器. 0x8(%ecx)表示越过test对象头(对象头占8个字节,后面就是跟着实例变量a的内存位置)
; - Test::sum@1 (line 13)
0x026ab71e: mov $0x2024d7d8,%esi ; {oop('Test')}//获取Test在方法区的指针, 可以看标记oop(methodName),$0x2024d7d8就是对应的Test方法区位置
0x026ab723: mov 0x150(%esi),%esi ;*getstatic b //获取对应的类变量b,放到esi寄存器中,0x150(%esi)表示在Test方法区指针开始的150偏移量的位置存放类变量b
; - Test::sum@4 (line 13)
0x026ab729: add %esi,%eax// esi存放的是b,eax存放的是a.两者相加,放到eax寄存器中
0x026ab72b: add %edx,%eax //edx 存放的是sum方法对应的参数c,eax存放着a+b的和.两者相加放到eax寄存器中
0x026ab72d: add $0x18,%esp //esp为对应的栈帧指针,之前sub 0x18 ,现在加回去.也就是撤销栈帧
0x026ab730: pop %ebp //恢复上一个栈帧
0x026ab731: test %eax,0x230100 ; {poll_return} //轮询方法返回处的SafePoint
0x026ab737: ret //返回.
0x026ab738: nop
0x026ab739: nop
;; Unwind handler
0x026ab73a: mov %fs:0x0(,%eiz,1),%esi
0x026ab742: mov -0xc(%esi),%esi
0x026ab745: mov 0x198(%esi),%eax
0x026ab74b: movl $0x0,0x198(%esi)
0x026ab755: movl $0x0,0x19c(%esi)
0x026ab75f: add $0x18,%esp
0x026ab762: pop %ebp
0x026ab763: jmp 0x026a7be0 ; {runtime_call}
0x026ab768: hlt
0x026ab769: hlt
0x026ab76a: hlt
0x026ab76b: hlt
0x026ab76c: hlt
0x026ab76d: hlt
0x026ab76e: hlt
0x026ab76f: hlt
[Exception Handler]
[Stub Code]
0x026ab770: mov $0xdead,%ebx ; {no_reloc}
0x026ab775: mov $0xdead,%ecx
0x026ab77a: mov $0xdead,%esi
0x026ab77f: mov $0xdead,%edi
0x026ab784: call 0x026a9c40 ; {runtime_call}
0x026ab789: push $0x83c8bc0 ; {external_word}
0x026ab78e: call 0x026ab793
0x026ab793: pusha
0x026ab794: call 0x0822c2e0 ; {runtime_call}
0x026ab799: hlt
[Deopt Handler Code]
0x026ab79a: push $0x26ab79a ; {section_word}
0x026ab79f: jmp 0x0266bac0 ; {runtime_call}
指令码的解析,上面基本都写了.
参照链接
http://stackoverflow.com/questions/1503479/how-to-see-jit-compiled-code-in-jvm/4149878#4149878
http://hllvm.group.iteye.com/group/topic/21769
https://blogs.oracle.com/kto/entry/mustang_jdk_6_0_fastdebug
相关推荐
综上所述,“ASM 设备操作手册”提供了关于AD830高速银浆固晶机的详细操作指导,涵盖了从设备安装到日常维护的各个方面,并且在全球范围内设有多个服务支持点,以便用户在遇到问题时能够迅速获得帮助和支持。...
标题中的"asm-util-4.0_RC1.jar.zip"是一个归档文件,它是一个ZIP格式的压缩包,其中包含了ASM工具库的一个特定版本——ASM Util 4.0 Release Candidate 1(RC1)。ASM是一个Java字节码操控和分析框架,广泛用于动态...
【标题】"asm----masm615+mirro+good1+good2" 提供的是一个关于汇编语言学习的资源包,其中包含了MASM615汇编器、Mirror反汇编器以及两个名为"good1"和"good2"的学习示例程序。这些工具和例子对于深入理解汇编语言至...
赠送jar包:asm-all-5.0.2.jar; 赠送原API文档:asm-all-5.0.2-javadoc.jar; 赠送源代码:asm-all-5.0.2-sources.jar; 赠送Maven依赖信息文件:asm-all-5.0.2.pom; 包含翻译后的API文档:asm-all-5.0.2-javadoc-...
asm-util-1.3.4.jar, asm-util-1.3.5.jar, asm-util-1.4.1.jar, asm-util-1.4.3.jar, asm-util-1.5.1.jar, asm-util-1.5.2.jar, asm-util-1.5.3.jar, asm-util-2.0.jar, asm-util-2.1.jar, asm-util-2.2.1-sources....
asm-1.3.3.jar, asm-1.3.4.jar, asm-1.3.5.jar, asm-1.4.1.jar, asm-1.4.2.jar, asm-1.4.3.jar, asm-1.4.jar, asm-1.5.1.jar, asm-1.5.2.jar, asm-1.5.3.jar, asm-2.0.jar, asm-2.1.jar, asm-2.2.1-sources.jar, asm...
JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2...
asm-all-5.2.jar asm-all-5.2.jar asm-all-5.2.jar asm-all-5.2.jar asm-all-5.2.jar asm-all-5.2.jar asm-all-5.2.jar asm-all-5.2.jar asm-all-5.2.jar asm-all-5.2.jar asm-all-5.2.jar asm-all-5.2.jar asm-all-...
### Oracle 11g RAC_ASM 搭建详解 #### 一、环境配置与准备 在进行Oracle 11g RAC_ASM的实际部署前,首先需要准备好合适的硬件及软件环境。 **1.1 主机配置** - **RAC1.vm 和 Rac2.vm** - 公共IP (Public IP): ...
Oracle 11gR2 RAC (Real Application Clusters) 和 ASM (Automatic Storage Management) 是在AIX-6.1操作系统上部署企业级数据库环境的关键组件。本安装指南将涵盖预安装检查、规划以及安装过程中的重要步骤。 1. ...
这些文件是Java编程语言中用于动态代码生成和字节码操作的重要库,主要涉及ASM和CGLIB两个框架。ASM是一个轻量级的Java字节码操控和分析框架,而CGLIB是一个强大的代码生成库,它在许多情况下作为Spring框架的依赖...
1. **时钟问题**:从上述代码可以看出,问题的根本在于USB主机控制器的48MHz时钟未能正确启动。这是由于在启动过程中没有正确配置PLL导致的。S3C2410芯片支持多个PLL(包括APLL、MPLL和EPLL),其中EPLL用于USB主机...
总之,SUSE Linux Enterprise Server 11使用udev管理ASM,确保了在Oracle 11gR2 RAC环境中设备的稳定识别和操作,这是成功部署RAC的关键部分。通过正确的配置和依赖包安装,可以保证Oracle RAC在SLES上的高效运行。
仍然是JavaScript的子集,但更适合手写(这样您就不需要使用C / C ++-> Emscripten-> asm.js进行数学运算) 工作正在进行中。目前支持: ES6 import并命名export 自动var , let , const提取和转换自动功能布局...
asm-analysis-5.0.3.jar;asm-analysis-5.0.3.jar;asm-analysis-5.0.3.jar
ASM库通常被用于编译器、代码分析工具以及一些需要在运行时修改Java类的框架。 描述中提到的“asm, util, jar.zip包下载, 依赖包”揭示了这个压缩包的核心内容。"asm"是ASM库的简称,"util"可能指的是包含了一些...
JavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-...