Failing typeflow responsibility assertions
gbenson at redhat.com
Fri May 23 01:33:24 PDT 2008
Tom Rodriguez wrote:
> Why would you want to make the register allocator cope with not
> having registers? If you are replacing the backend then you aren't
> using the existing register allocators. You'd simply skip
> everything after then high level ir is generated and you'd be
> responsible for filling in a code buffer that could be turned into
> an nmethod by new_nmethod. There are no problems in there that you
> aren't facing with writing a new compiler from scratch. Writing and
> maintaining a good, correct Java front end is work that I would
> recommend you do everything you can to avoid, unless of course you
> think it sounds like fun.
The register allocator was just a random example I remembered from
six months ago when I looked at writing a direct ppc client port
briefly. The answers to your questions are better examples I think.
For example, I've no access to the compiled code, so I can't patch
oops, I have to write everything without inlining them. Would it
be possible to get C1 or C2 to never inline an oop? If so I may
re-think my strategy! :)
> These are the problem I think you are really facing and maybe you
> already have answer for these:
> 1. How do you derive oopmaps from the generated code?
I don't know that I can. One question I've been saving up for a while
is how does the interpreter do this? Looking at frame.[hc]pp I see a
lot of stuff that compiled frames are expected to provide that I
probably can't -- it may be that I'll end up giving my compiled frames
the same layout as the interpreter frames and doing whatever the
interpreter does to tell the GC where the oops are. The problem
being, I'm most familiar with the C++ interpreter, and I can't for the
life of me see how it does this!
> 2. How do you get hotspot's relocation information into the code
> you generate?
I can't, I can't rewrite the code once it's generated. I have to
write the code without ever inlining oops.
> 3. If you are intending to support deoptimization, how do you get
> at the locations of the needed values. This is similar to 1 but may
> imply a little more complexity.
The way I'm currently heading is to allocate stack space for all
locals and stack slots and to write them out from wherever LLVM has
them (registers, etc) before method calls or safepoints. I may make
the frame identical in layout to the interpreter frames so I can use
the same decaching code so that deoptimization is simply a matter of
starting the interpreter at bci X.
> 4. Some things we emit, like compiled inline caches and embedded
> references to oop, require instruction patterns that are patchable
> from the runtime. Does LLVM provide the control you need?
>From this question I think I misunderstood what you were asking for
> 5. What's your plan for dealing with unloaded classes? C2 does
> it by terminating the control flow at the unloaded bytecode and
> emitting an uncommon trap that will fall back to the interpreter.
> The class will be loaded and a new compile of the code will be
> generated. C1 does it by emitting special patchable instructions
> and rewriting them when it encounters them. I don't know which one
> fits better with LLVM, C1 could probably be modified to use the
> uncommon trap strategy if patching were too difficult.
I'm planning to do it like C2, I really like how it does it.
> There are probably other issues but those are the ones that jump out
> at me.
Interfacing with the GC is the most troubling for me at the moment.
If you can (or know anyone who can) point me in the right direction
it would be much appreciated!
More information about the hotspot-compiler-dev