webrev to extend HSAIL backend deoptimization to support live values in stack slots
Deneau, Tom
tom.deneau at amd.com
Wed Apr 30 22:28:55 UTC 2014
I have placed a webrev up at
http://cr.openjdk.java.net/~tdeneau/graal-webrevs/webrev-hsail-stackslot-deopt/webrev
which we would like to get checked into the graal trunk.
This webrev extends the existing hsail deoptimization logic (which
only supports deoptimization points where the live values are in
registers) to handle the case where the live values are in stackslots.
Here are the major areas that get affected by stack slot deoptimization:
1) At the deopt exit point of a kernel, need to save the required
stack slot variables into the hsail frame. This is some new
code in HSAILHotSpotBackend.
2) The host trampoline code needs to handle the case where a
deoptimization value is in a stack slot. See
getNodeForStackSlotFromFrame in HSAILHotSpotBackend.
* In doing this I realized that we have only one deopt exit from
an hsail kernel, so all the saved hsailFrames for a given
kernel have the same num_s_regs, num_d_regs, etc. So we can
treat num_s_regs, num_d_regs, etc as compile time constants
(for that kernel). This simplified the LocationNodes for
building the hostgraph.
3) The oopmap data that can be used from the JVM side to take care
of the case where oops might move under GC needs to handle the
case that stack slot variables could also be oops.
Regarding #3 above, the way the current hsail oopmap data is saved (as
a single 16-bit integer in each frame representing the $d registers)
needed some redesign. Now that we will also need an intderminately
longer set of bits to represent stack slots oops, a better strategy
would be to not save the oopsmap at deopt time but instead have some
deopt metadata in a form that the JVM side could access which would
map a deopt "PC" to an oopmap (set of bits) for that PC. This was
done thru OopMapArrayBuilder in HSAILHotSpotBackend (at compile time),
and OopSaver class in gpu_hsail.cpp (at execute time).
I added fields to ExternalCompilationResult and create a
HSAILHotSpotNmethod to pass the oopMapArray from the compile time
environment to the execute time.
The deopt save area (allocated on the C++ side) used to allocate an
area for each workitem that was a fixed size big enough to handle a
deopt that saved all the registers. Now it is computed based on the
actual number of s registers, d registers and stack slots saved for
that compilation. See gpu_hsail.cpp and gpu_hsail.hpp.
Similarly the temporaray oopSave array allocated from the java side
now uses the register and stack slot counts to determine how big an
Object Array to allocate. (this oopSave array will go away some day
when we implement the better oops_do support for the oops in the
HSAILFrame).
Other changes:
* Some old junit tests that had been designed to test stack slots
had been disabled once deoptimization logic was added because some
of their deopt points needed to save stack slots, which was not
supported. These tests were re-enabled in this webrev. (Note:
these tests never actually deopted).
* Some HSAIL backend LIR Ops had @Use annotations that incorrectly
included STACK. These were fixed and some existing Ops (that did
not declare @Use(STACK) had their names changed to better reflect
what they were doing.
* In DeoptimizeOp, (HSAILControlFlow) and HSAILHotSpotSafepointOp,
removed code that computed the $d register oopmap for that
deoptimization point. This is all computed now in the
OopMapArrayBuilder so doesn't need to be computed and saved at
each deopt point.
* Some new junit tests to specifically test deoptimizations that
used stack slots (and had oops in stack slots). Including a
forceDeopt call which uses @MethodSubtitution
(ForceDeoptSubstitutions.java)
More information about the graal-dev
mailing list