While trying to run clojure on JNode I noticed that some dead code in the ASM generated bytecode of clojure makes it fail because it confuses the JIT. One example of the problem can be seen with javap: javap -c clojure.core\$last__2780
Result (relevant part) : public java.lang.Object invoke(java.lang.Object) throws java.lang.Exception; Code: 0: getstatic #22; //Field const__0:Lclojure/lang/Var; 3: invokevirtual #37; //Method clojure/lang/Var.get:()Ljava/ lang/Object; 6: checkcast #39; //class clojure/lang/IFn 9: aload_1 10: invokeinterface #41, 2; //InterfaceMethod clojure/lang/ IFn.invoke:(Ljava/lang/Object;)Ljava/lang/Object; 15: dup 16: ifnull 47 19: getstatic #47; //Field java/lang/Boolean.FALSE:Ljava/ lang/Boolean; 22: if_acmpeq 48 25: getstatic #22; //Field const__0:Lclojure/lang/Var; 28: invokevirtual #37; //Method clojure/lang/Var.get:()Ljava/ lang/Object; 31: checkcast #39; //class clojure/lang/IFn 34: aload_1 35: invokeinterface #41, 2; //InterfaceMethod clojure/lang/ IFn.invoke:(Ljava/lang/Object;)Ljava/lang/Object; 40: astore_1 41: goto 0 44: goto 65 47: pop 48: getstatic #26; //Field const__1:Lclojure/lang/Var; 51: invokevirtual #37; //Method clojure/lang/Var.get:()Ljava/ lang/Object; 54: checkcast #39; //class clojure/lang/IFn 57: aload_1 58: aconst_null 59: astore_1 60: invokeinterface #41, 2; //InterfaceMethod clojure/lang/ IFn.invoke:(Ljava/lang/Object;)Ljava/lang/Object; 65: areturn By investigating the bytecode one can notice that line: "44: goto 65" in unreachable. This creates the problem. After some investigation of the clojure source code I came to the conclusion that for this particular case changing the clojure.lang.Compiler, r1193 at line 2367 to: if(!(thenExpr instanceof RecurExpr)) gen.goTo(endLabel); That is: if the thenExpr of the if node is such that it wouldn't fall through to the elseExpr then there is no need to emit a goto bytecode for jumping to the end of the if statement, bacause it will be unreachable. With this change I rebuilt clojure and apparently it's working fine, the bytecode of the method above is correct, but unfortunately there are similar situations in other parts of the code where usesless bytecode is emited. For instance clojure.core$partition__3754.invoke(Object,Object,Object) also contains deadcode similar to the above and it's related to the if node. If clojure will be used on other experimental, limited or non- mainstream Java platforms such problems in the generated bytecode will surface and create problems. The bugs in such paltforms (their intolerance to various non-fatal byecode problems) can stay hidden because the bytecode generated by javac doesn't have such problems. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---