[讨论] javac 的代码跟踪的问题
beneo
2011-01-20
beneo 写道 源代码是
public class Demo { public void foo() { char a = 'a'; a += 32; //可以通过 } } bytecode后是 public void foo(); Signature: ()V Code: 0: bipush 97 // 将byte 97压入堆栈 2: istore_1 // 弹出堆栈并存入局部变量1 3: iload_1 // 将局部变量1压入堆栈 4: bipush 32 // byte 32压入堆栈 6: iadd // 相加 7: i2c // cast int to char 8: istore_1 // 弹出堆栈并存入局部变量1 9: return 我看javac,因为时间很少,加上编译原理知识为0,我很想知道,在javac源代码里面,哪儿有放i2c的地方?我自己search没有找到 RednaxelaFX 写道 不知道行号对得对不上,我用的是JDK 6 update 18的javac:
Items$LocalItem.incr(int) line: 404 Gen.visitAssignop(JCTree$JCAssignOp) line: 1793 JCTree$JCAssignOp.accept(JCTree$Visitor) line: 1367 Gen.genExpr(JCTree, Type) line: 818 Gen.visitExec(JCTree$JCExpressionStatement) line: 1605 JCTree$JCExpressionStatement.accept(JCTree$Visitor) line: 1074 Gen.genDef(JCTree, Env<GenContext>) line: 665 Gen.genStat(JCTree, Env<GenContext>) line: 700 Gen.genStat(JCTree, Env<GenContext>, int) line: 686 Gen.genStats(List<JCTree>, Env<GenContext>) line: 737 Gen.visitBlock(JCTree$JCBlock) line: 1013 JCTree$JCBlock.accept(JCTree$Visitor) line: 739 Gen.genDef(JCTree, Env<GenContext>) line: 665 Gen.genStat(JCTree, Env<GenContext>) line: 700 Gen.genMethod(JCMethodDecl, Env<GenContext>, boolean) line: 893 Gen.visitMethodDef(JCTree$JCMethodDecl) line: 866 JCTree$JCMethodDecl.accept(JCTree$Visitor) line: 639 Gen.genDef(JCTree, Env<GenContext>) line: 665 Gen.genClass(Env<AttrContext>, JCClassDecl) line: 2198 JavaCompiler.genCode(Env<AttrContext>, JCClassDecl) line: 617 JavaCompiler.generate(List<Pair<Env<AttrContext>,JCClassDecl>>, ListBuffer<JavaFileObject>) line: 1289 JavaCompiler.generate(List<Pair<Env<AttrContext>,JCClassDecl>>) line: 1259 JavaCompiler.compile2() line: 765 JavaCompiler.compile(List<JavaFileObject>, List<String>, Iterable<Processor>) line: 730 Main.compile(String[], Context, List<JavaFileObject>, Iterable<Processor>) line: 353 Main.compile(String[], Context) line: 279 Main.compile(String[]) line: 270 你要的代码是这个样子的: makeStackItem(syms.intType).coerce(typecode); 很好奇你给的stack没有makeStackItem,然后你就突然告诉我这个 还有,不知道你用什么办法能够看到一个stack所有的line,这个对阅读源代码很有帮助,谢谢了 |
|
RednaxelaFX
2011-01-20
我那个是从Eclipse JDT的调试器里的debug窗口复制出来的。换句话说我调试到那个地方然后把当时的调用栈状况复制下来了。
前面回复给你的信息的意思是,在Items$LocalItem.incr(int) line: 404那行,代码是 makeStackItem(syms.intType).coerce(typecode); 那个coerce()方法的调用就会生成出i2c指令了。 大致了解javac的结构的话,要跟到想要的逻辑的位置很容易~ 因为大概能猜到是在几个步骤的那一个,这个例子也就是在Gen的步骤里了。 |
|
lazybird86
2011-01-21
RednaxelaFX 写道 我那个是从Eclipse JDT的调试器里的debug窗口复制出来的。换句话说我调试到那个地方然后把当时的调用栈状况复制下来了。
前面回复给你的信息的意思是,在Items$LocalItem.incr(int) line: 404那行,代码是 makeStackItem(syms.intType).coerce(typecode); 那个coerce()方法的调用就会生成出i2c指令了。 大致了解javac的结构的话,要跟到想要的逻辑的位置很容易~ 因为大概能猜到是在几个步骤的那一个,这个例子也就是在Gen的步骤里了。 FX能告知怎么构建调试javac的环境吗? |
|
RednaxelaFX
2011-01-21
lazybird86 写道 FX能告知怎么构建调试javac的环境吗?
嗯。很简单的: 先下载Sun JDK或者OpenJDK的源码。 在Sun JDK里,javac源码的路径在: j2se/src/share/classes/com/sun/tools/javac 在OpenJDK里,javac源码的路径在: langtools/src/share/classes/com/sun/tools/javac 但我们并不一定要真的在自己的工程里把javac的源码全拷贝过来。有更简单的做法。 先在Eclipse里建一个新的空工程,把JDK下的tools.jar添加到依赖的JAR包里。 然后,像这帖的描述一样,把上面说的路径添加到tools.jar的源码上。 注意:添加源码路径时,加的是上面说的路径到classes/那里,后面实际上是包名对应的路径。 然后写个带main()方法的启动类,例如: package test.debug.javac; import com.sun.tools.javac.main.Main; public class DebugEntryPoint { public static void main(String[] args) { Main m = new Main("fx_debug"); m.compile(asArray("Demo.java")); } private static <T> T[] asArray(T... args) { return args; } } 然后就随便调试了。比较值得关注的几个点是JavaCompiler.compile()、JavaCompiler.compile2()方法之类的。 |
|
lazybird86
2011-01-21
FX:谢谢啦
我以为是你是直接能调试到命令行下的javac,我想多了 ![]() 这种方法也是好啊 ![]() |
|
RednaxelaFX
2011-01-21
lazybird86 写道 FX:谢谢啦
我以为是你是直接能调试到命令行下的javac,我想多了 ![]() 这种方法也是好啊 ![]() 会偷懒是程序员的美德 XD |
|
Willam2004
2011-02-10
引用 但我们并不一定要真的在自己的工程里把javac的源码全拷贝过来。有更简单的做法。
参照这里试了一下,tools.jar下的包都能找到源码了,但是jdk中的jsse.jar包内容对应的源码好像没有,ls你遇到过这种问题么?
先在Eclipse里建一个新的空工程,把JDK下的tools.jar添加到依赖的JAR包里。 然后,像这帖的描述一样,把上面说的路径添加到tools.jar的源码上。 注意:添加源码路径时,加的是上面说的路径到classes/那里,后面实际上是包名对应的路径。 |
|
RednaxelaFX
2011-02-11
OpenJDK 7的源码包里是有这部分代码的。
hmm…Sun的JDK源码包里貌似是缺了些JSSE相关的源码。呃我不记得应该在哪里找了。 |