RFR(M): 8223051: support loops with long (64b) trip counts

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Fri Aug 21 09:12:30 UTC 2020


>> Sorry, I don't get it. Normally JVM state associated with a call is a
>> state right after the call returns. Do you mean there are cases when
>> call has reexecute bit set and hence it has JVM state before the call
>> associated with it?
> 
> JVM state at a call can't be state after the call because it would need
> to capture the return value which can't be an incoming edge to the call,
> right?

Yes, you are right. But, strictly speaking, it's not the state before 
the call either since all the arguments are not on the stack anymore (as 
an example [1]).

>> Anyway, it's trivial to convert between 2 states (before and after) and
>> we already do that in some places (e.g., late inline prepares JVM state
>> for the parser based on the state associated with CallStaticJava node).
> 
> Sure it's feasible to build state after the call. I was concerned that
> the runtime would hardwire somewhere that state at the call is always
> state before the call. That would lead to nasty, rare and hard to debug
> failures. It felt a lot simpler and robuster to leave SafePoint nodes in
> the graph. We could have the patch go through a performance run and see
> if that change makes any difference if there's concern about it.

Indeed, keeping a safepoint right after the call does look appealing.

But it also means there should be always a safepoint accompanying the 
call and it should follow it immediately for the logic in question to be 
in effect. Do we guarantee that?

Best regards,
Vladimir Ivanov

[1]

56 invokevirtual 179 
<java/util/HashMap.newNode(ILjava/lang/Object;Ljava/lang/Object;Ljava/util/HashMap$Node;)Ljava/util/HashMap$Node;> 

   152 bci: 56   VirtualCallData     count(0) nonprofiled_count(0) 
entries(2)
                                     'java/util/HashMap'(4607 0.99)
                                     'java/util/LinkedHashMap'(57 0.01)

(lldb) p jvms->dump()
  149	SafePoint	===  146  94  148  8  9  10  1  1  1  1  15  1  1  1  1 
1  1  1  96  102  10  11  12  13  32  1  [[]]  SafePoint replaced nodes: 
127->136 !orig=55,[26],23
JVMS depth=1 loc=5 stk=18 arg=20 mon=26 scalar=26 end=26 mondepth=0 sp=2 
bci=56 reexecute=false method=virtual jobject 
java.util.HashMap.putVal(jint, jobject, jobject, jboolean, jboolean)
     bc:     locals(13): 10 1 1 1 1 15 1 1 1 1 1 1 1
      stack(2): 96 102
       args(6): 10 11 12 13 32 1
   monitors(0):
    scalars(0):


(lldb) p call->jvms()->dump()
...
  150	CallDynamicJava	===  146  94  95  8  1 ( 10  11  12  13  32  10  1 
  1  1  1  15  1  1  1  1  1  1  1  96  102 ) [[ 151  152  153  155  156 
  163  164 ]] # Dynamic  java.util.HashMap::newNode 
java/util/HashMap$Node * ( java/util/HashMap:NotNull *, int, 
java/lang/Object *, java/lang/Object *, java/util/HashMap$Node * ) 
HashMap::putVal @ bci:56 !jvms: HashMap::putVal @ bci:56
JVMS depth=1 loc=10 stk=23 arg=25 mon=25 scalar=25 end=25 mondepth=0 
sp=2 bci=56 reexecute=false method=virtual jobject 
java.util.HashMap.putVal(jint, jobject, jobject, jboolean, jboolean)
     bc:     locals(13): 10 1 1 1 1 15 1 1 1 1 1 1 1
      stack(2): 96 102
       args(0):
   monitors(0):
    scalars(0):

(lldb) p new_jvms->dump()
...
  149	SafePoint	===  158  163  165  8  9  10  1  1  1  1  15  1  1  1  1 
  1  1  1  96  102  155  11  12  13  32  1  | 161  [[]]  SafePoint 
replaced nodes: 127->136 !orig=55,[26],23
JVMS depth=1 loc=5 stk=18 arg=21 mon=26 scalar=26 end=26 mondepth=0 sp=3 
bci=56 reexecute=false method=virtual jobject 
java.util.HashMap.putVal(jint, jobject, jobject, jboolean, jboolean)
     bc:     locals(13): 10 1 1 1 1 15 1 1 1 1 1 1 1
      stack(3): 96 102 155
       args(5): 11 12 13 32 1
   monitors(0):
    scalars(0):


More information about the hotspot-compiler-dev mailing list