RFR(S): 8214862: assert(proj != __null) at compile.cpp:3251
Vladimir Kozlov
vladimir.kozlov at oracle.com
Thu Dec 6 19:17:01 UTC 2018
Added bug id to Subject.
Why relaxing assert is not enough? Why you want to delay edge removal?
I would suggest to create a small function (in same file) to call from Compile::Optimize() - we
don't do graph transformations in it but call other functions.
You don't need to use 'C->' because it is already Compile's method.
Thanks,
Vladimir
On 12/6/18 1:42 AM, Roland Westrelin wrote:
>
> http://cr.openjdk.java.net/~roland/8214862/webrev.00/
>
> The crash occurs in final_graph_reshape in the following code:
>
> case Op_Proj: {
> if (OptimizeStringConcat) {
> ProjNode* p = n->as_Proj();
> if (p->_is_io_use) {
> // Separate projections were used for the exception path which
> // are normally removed by a late inline. If it wasn't inlined
> // then they will hang around and should just be replaced with
> // the original one.
> Node* proj = NULL;
> // Replace with just one
> for (SimpleDUIterator i(p->in(0)); i.has_next(); i.next()) {
> Node *use = i.get();
> if (use->is_Proj() && p != use && use->as_Proj()->_con == p->_con) {
> proj = use;
> break;
> }
> }
> assert(proj != NULL, "must be found");
> p->subsume_by(proj, this);
> }
> }
> break;
> }
>
> because a call only has control/memory/io uses for the exception path
> but none for the fall through path. This happens because after the call,
> the fallthrough path leads to an infinite loop and that infinite loop
> and the path that leads to it is removed. The infinite loop is removed
> because there are 2 passes of PhaseRemoveUseless that are executed. One
> as part of Compile::inline_string_calls(), and another one right after,
> both at the end of parsing:
>
> if (_late_inlines.length() == 0 && !has_mh_late_inlines() && !failing() && has_stringbuilder()) {
> inline_string_calls(true);
> }
>
> if (failing()) return;
>
> print_method(PHASE_BEFORE_REMOVEUSELESS, 3);
>
> // Remove clutter produced by parsing.
> if (!failing()) {
> ResourceMark rm;
> PhaseRemoveUseless pru(initial_gvn(), &for_igvn);
> }
>
> During parsing, safepoint nodes in infinite loops are kept live with an
> extra precedence edge from the Root node to the safepoint. That edge is
> removed as part of PhaseRemoveUseless. So the first pass of
> PhaseRemoveUseless disconnects the safepoint node in the infinite loop,
> the second finds the safepoint node has no uses and removes it.
>
> To fix that, I moved the logic that disconnects safepoints from the Root
> node after parsing is over for good, that is after all late inlining
> passes. Optimizations that are applied between the initial parsing phase
> and the removal of the precedence edges, can get confused by the
> precedence edge when a safepoint node goes dead. So I also had to add
> explicit tests for a safepoint node in a few locations.
>
> That fix is not sufficient to not hit the assert in final graph
> reshape because a safepoint in an infinite loop doesn't have any io
> input. So I also had to relax the code in final graph reshape for io
> projections.
>
> Roland.
>
More information about the hotspot-compiler-dev
mailing list