<html><head></head><body bgcolor="#FFFFFF" text="#000000" lang="en-GB" style="background-color: rgb(255, 255, 255); line-height: initial;">                                                                                      <div style="width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);"><span style="line-height: initial;">Hi Thomas,</span></div><div><br><div class="gmail_quote">On Sat, May 7, 2016 at 9:02 PM, Thomas Jakway<span dir="ltr"><<a href="mailto:tjakway@nyu.edu" target="_blank">tjakway@nyu.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div bgcolor="#FFFFFF" text="#000000">This is a strange coincidence.  I'm definitely no expert GHC hacker but I started (highly preliminary) work on a JVM backend for GHC a few weeks ago.  It's here:<a href="https://github.com/tjakway/ghcjvm/tree/jvm/compiler/jvmGen/Jvm" target="_blank">https://github.com/tjakway/ghcjvm/tree/jvm/compiler/jvmGen/Jvm</a><br>(The memory runtime is here:<a href="https://github.com/tjakway/lljvm" target="_blank">https://github.com/tjakway/lljvm</a>)<br></div></blockquote><div><br></div><div>Wow that is coincidence!</div><div> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div bgcolor="#FFFFFF" text="#000000">I'm very new to this so pardon my ignorance, but I don't understand what the benefit is of intercepting STG code and translating that to bytecode vs. translating Cmm to bytecode (or Jasmin assembly, as I'd prefer)?  It seems like Cmm is designed for backends and the obvious choice.  Or have I got this really mixed up?<br></div></blockquote><div><br></div><div>In the GHC RTS, the heap is composed of basic units called closures which consist of an info table (metadata of the closure), entry code, and a payload, and these are used to implement the STG machine. The GHC backend translates STG code into closures and tells you how they should be laid out in memory (not using exact addresses, but using abstract labels) using the language of Cmm. That format is perfect for consumption by register-based machines and architectures like most processors these days. However, the JVM is stack-based, not register-based.</div><div><br></div><div>The point is, Cmm is too low-level when trying to compile to the JVM you don't have control over the memory layouts (but new projects like Valhalla as mentioned by Ian above seem to make that possible). Another problem is that you need to write your own garbage collector if you go the Cmm route because Cmm generates stack and heap checks which call into the RTS GC functions, which you need to implement in order to make it work.</div><div><br></div><div>The main benefit of STG is that it's the lowest level of Haskell code you can get without specifying low-level details like memory layouts, </div><div>placement of data in the stack vs registers, and heap/stack checks.</div><div><br>In GHCVM, I am trying to avoid reinventing the wheel and re-use existing infrastructure as much as possible. This allows the final product to come out sooner and performance can be optimized at a later stage. That is why I use as much of the JVM's features as possible (especially GC and automatic heap/stack management) because the JIT will not be able to optimize DirectByteBuffers (which is what I think lljvm uses).‎<br></div><div><br></div><div>In my implementation, I'll probably end up using a modified version of Cmm that is more relevant for the JVM (without references to registers/memory locations), but for now I'm going for direct bytecode generation.  </div><div> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div bgcolor="#FFFFFF" text="#000000">I hope this isn't out of line considering my overall lack of experience but I think I can give some advice:<br><ul><li>read the JVM 7 spec cover-to-cover. </li></ul></div></blockquote><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div bgcolor="#FFFFFF" text="#000000"><ul><li>I <b><u>highly</u></b> suggest outputting <a href="http://web.mit.edu/javadev/packages/jasmin/doc/" target="_blank">Jasmin</a> assembly instead of raw bytecode.  The classfile format is complicated and you will have to essentially rewrite Jasmin in Haskell if you don't want to reuse it.  Jasmin is also the de facto standard assembler and much more thoroughly tested than any homegrown solution we might make.<br></li></ul></div></blockquote><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div bgcolor="#FFFFFF" text="#000000"><ul><li>read the LLVM code generator.  This project is more like the LLVM backend than the native code generator.</li><li>Don't go for speed.  The approach that I've begun is to emulate a C stack and memory system the RTS can run on top of (<a href="https://github.com/tjakway/lljvm/blob/master/src/main/java/lljvm/runtime/Memory.java" target="_blank">https://github.com/tjakway/lljvm/blob/master/src/main/java/lljvm/runtime/Memory.java</a>). This will make getting <i>something</i> working much faster and also solves the problem of how to deal with memcpy/memset/memmove on the JVM.  This will of course be <u>very</u> slow (I think) and is not a permanent solution.  Can't do everything at once.  Any other approach will probably require rewriting the entire RTS from the beginning.</li></ul></div></blockquote><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div bgcolor="#FFFFFF" text="#000000"><ul><li>I don't think Frege is especially useful to this project, though I'd love to be proven wrong.  Frege's compilation model is completely different from GHC's: they compile Haskell to Java and then send that to javac.  Porting GHC to the JVM is really more like writing a Cmm to JVM compiler.</li></ul></div></blockquote><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div bgcolor="#FFFFFF" text="#000000"><p>Information on Jasmin:<br></p><p><a href="http://web.mit.edu/javadev/packages/jasmin/doc/" target="_blank">http://web.mit.edu/javadev/packages/jasmin/doc/</a><br><a href="http://web.mit.edu/javadev/packages/jasmin/doc/instructions.html" target="_blank">http://web.mit.edu/javadev/packages/jasmin/doc/instructions.html</a><br><a href="http://web.mit.edu/javadev/packages/jasmin/doc/about.html" target="_blank">http://web.mit.edu/javadev/packages/jasmin/doc/about.html</a><br></p><p>Once you've tried manually dealing with constant pools you'll appreciate Jonathan Meyer's work!<br></p></div></blockquote><div>I've tried simple bytecode experiments with Jasmin when exploring the different methods of doing tail calls on the JVM and one of the methods can't be done using Java so I had to resort to hand-writing the assembly. Jasmin was pretty cool but I wanted to have composability which a monad would provide and add my own helper instructions that can generate GHCVM-specific patterns of bytecode.</div><div><br></div><div>Moreover, the Haskell JVM implementation, MateVM used the hs-java library for bytecode generation and so I figured it would be reliable. Why should I spend time writing up a Jasmin AST/Pretty printer in Haskell when bytecode generation is already available with hs-java? Yes, there were a couple features that were not present like Haskell ADT representations of the different classfile attributes, but it took hardly a day's worth of work to add it in.</div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div bgcolor="#FFFFFF" text="#000000"><p></p><p>I forked <a href="https://github.com/davidar" target="_blank">davidar's</a> extended version of Jasmin.  The differences versus the original Jasmin are detailed<a href="https://github.com/davidar/jasmin/blob/master/html2x/xt.html" target="_blank">here</a>.  Some nice additions:<br></p><ul><li>supports invokedynamic</li><li>supports .annotation, .inner, .attribute, .deprecated directives</li><li>better handling of the ldc_w instruction</li><li>multi-line fields</li><li>.debug directives</li><li>signatures for local variables</li><li>.bytecode directive to specify bytecode version</li><li>(most importantly, I think): support for the StackMap attribute.  If we eventually want to use new JVM instructions like invokedynamic, we<b>need</b> stack map frames or the JVM will reject our bytecode.  JVM 7 has options to bypass this (but it's a hack), but they're deprecated and I believe not optional going forward.  Alternatively we can stick with older bytecode versions indefinitely and not use the new features.</li></ul></div></blockquote><div>I'm aware of the need of generating StackMapTables for JVMs beyond 7 and for right now I just want compatibility with the older JVMs (5 and 6), so it's not a big issue in the first phase.‎ I have the option of using the ASM bytecode engineering library if I get a chance to make GHCVM self-hoisted, or I can integrate it in the pipeline as an extra step after code generation using a standalone jar whose job is to generate StackMapTables.</div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div bgcolor="#FFFFFF" text="#000000"><p>I think the biggest risk is taking too much on at once.  Any one of these subtasks, writing a bytecode assembler, porting the RTS, etc. could consume the whole summer if you're not careful.<br></p></div></blockquote><div>Yeah good point. Right now my goal is just to compile very simple Haskell programs so I'm only porting the bare minimum required to get to that target. If you actually go through the STG->Cmm code generator, you'll find that if you remove all the noise of memory layouts, heap/stack checks, LDV + CCS + Ticky profiling, you get a nice and simple core which can be transformed to bytecode in a straightforward manner once the basic concepts of the GHC RTS have been translated over (like closures, stack frames, etc).</div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div bgcolor="#FFFFFF" text="#000000"><p></p><p>I'd love to help out with this project!<br></p></div></blockquote><div>Great! Please post any additional  ideas you have as separate issues on the GitHub repo, so that your suggestions don't get lost in this mailing list.</div><div> </div></div></div>                                                                                                                                     <div style="width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);">‎Thanks,</div><div style="width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);">Rahul</div><div id="_originalContent" style="background-color: rgb(255, 255, 255);">
    <br>
  

<br><!--end of _originalContent --></div></body></html>