review for 7145024: Crashes in ucrypto related to C2

Vladimir Kozlov vladimir.kozlov at oracle.com
Mon Feb 27 17:39:30 PST 2012


I looked on code in unpack_array_argument() and see that it should work for all 
cases since you are using tmp register to keep value. So it does not matter if 
it moves rsi -> rdi:rsi or rdi -> rdi:rsi for array argument.

Sorry for noise. Code looks good.

Thanks,
Vladimir

Vladimir Kozlov wrote:
> Actually assembler from JNITest::nativeTest3 should be enough since 
> first array copied as rsi -> rdi:rsi, the same as in nativeTest1.
> 
> Vladimir
> 
> Vladimir Kozlov wrote:
>> First, can you show assembler moves code for an array?
>>
>> For example, in next example you move "rsi -> rdi:rsi". I assume that 
>> destination registers contains length in rdi and ptr to array base in 
>> rsi. Correct?
>>
>> rsi, rdx, rcx, r8, r9, rdi, [0], [8]
>> rdi, rsi, rdx, rcx, r8, r9, [0], [8], [16]
>> [8] -> [16], [0] -> [8], rdi -> [0], r9 -> r9, r8 -> r8, rcx -> rcx, 
>> rdx -> rdx, rsi -> rdi:rsi
>>    1744   16     n 0       JNITest::nativeTest1([BIIIIIII)V (0 
>> bytes)   (static)
>>
>> In next example first register is matched for second array : rdx -> 
>> rdx:rcx. So what is assembler for it again?
>>
>> rsi, rdx, rcx, r8, r9, rdi, [0], [8]
>> rdi, rsi, rdx, rcx, r8, r9, [0], [8], [16], [24]
>> [8] -> [24], [0] -> [16], rdi -> [8], r9 -> [0], r8 -> r9, rcx -> r8, 
>> rdx -> rdx:rcx, rsi -> rdi:rsi
>>    1746   18     n 0       JNITest::nativeTest3([B[BIIIIII)V (0 
>> bytes)   (static)
>>
>> Thanks,
>> Vladimir
>>
>>
>> Tom Rodriguez wrote:
>>> On Feb 24, 2012, at 4:21 PM, Tom Rodriguez wrote:
>>>
>>>> On Feb 24, 2012, at 12:14 PM, Vladimir Kozlov wrote:
>>>>
>>>>> Tom,
>>>>>
>>>>> I don't get T_ARRAY argument processing in ComputeMoveOrder(). 
>>>>> T_ARRAY has two out arguments length and array pointer so two moves 
>>>>> are involved. I don't see how code handles it.
>>>> Yes it's a little odd.  I had convinced myself that because the 
>>>> arguments locations and just rotated relative to each other that 
>>>> only one argument could collide any testing indicated that it worked 
>>>> without killing anything.  Now I'm not so sure.  I'm going to think 
>>>> through it a bit more and maybe expand my test a bit.
>>>
>>> So the main part of the deals with partial overlap between the source 
>>> register and destinations.  For single moves if the source and dest 
>>> are the same then no edge is created but the array moves have to do 
>>> something different.  Because of the argument ordering in almost all 
>>> cases there is partial overlap between s and d1,d2.  In the partial 
>>> overlap case picking the second register if the source and the first 
>>> are the same will accurately capture the dependence ordering.  The 
>>> only case where they are fully disjoint occurs with an array argument 
>>> in rcx being moved into r8/r9 and in that case r8 and r9 are being 
>>> moved to the stack so they are free.  I attached JVM output showing 
>>> the argument shuffle order for all the signatures generated by the test.
>>>
>>> It's not a completely general algorithm but it's adequate for the 
>>> usage.  The moves assembly code actually validates that a register 
>>> isn't killed before being used it would have tripped assert is there 
>>> were any issues.
>>>
>>> I could do something different to be more general but I can't see an 
>>> easy way to represent this using the code I've written.
>>>
>>> tom
>>>
>>>
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>>
>>>>> I think next code in break_cycle() could be simpler since it is 
>>>>> cycle chain:
>>>>>
>>>>> 1416       MoveOperation* p = prev();
>>>>> 1417       if (p->_next != NULL) {
>>>>> 1418         p->_next->_prev = NULL;
>>>>> 1419       }
>>>>>
>>>>> as this:
>>>>>
>>>>> 1416       MoveOperation* p = prev();
>>>>> 1417       assert(p->_next == this, "");
>>>>> 1418       _prev = NULL;
>>>> You're right.  I had refactored the code so that the calling context 
>>>> changed but didn't simplify it in  that way.   I'll fix it.
>>>>
>>>>> Why you don't want new test to be executed during regular testing? 
>>>>> You used "manual" and double "##". Did you try to run it with jtreg.
>>>> jtreg doesn't support compiling libraries as part of a test so it 
>>>> has to be run by hand.  By default jtreg will run manual tests 
>>>> unless you specify -automatic.  I kind of assumed that's how it's 
>>>> being run during nightlies but maybe that's not true.  Maybe it's 
>>>> not appropriate for a jtreg test?
>>>>
>>>> tom
>>>>
>>>>> Thanks,
>>>>> Vladimir
>>>>>
>>>>> Tom Rodriguez wrote:
>>>>>> http://cr.openjdk.java.net/~never/7145024
>>>>>> 489 lines changed: 451 ins; 22 del; 16 mod; 3645 unchg
>>>>>> 7145024: Crashes in ucrypto related to C2
>>>>>> Reviewed-by:
>>>>>> There are two issues here.  The first issue, that resulted in the
>>>>>> asserts was incorrect incrementing of the slots when building the oop
>>>>>> map.  Fixing that exposed the second issue which is that different
>>>>>> signatures may require very different orders for the move to avoid
>>>>>> clobbering other arguments.  There's no simple way to order them
>>>>>> safely so I resurrected some old C1 code for computing a safe order
>>>>>> for issuing stores and break any cycles in those stores.  The code
>>>>>> itself is fairly general but it's not necessary on the other 
>>>>>> platforms
>>>>>> so I kept it in the platform dependent code instead of moving it into
>>>>>> a shared file.  Tested with a new manual test that exercises all
>>>>>> permutations of 8 arguments that mix primtives and arrays on Solaris,
>>>>>> Linux and Windows.  Also tested with failing
>>>>>> javasoft.sqe.tests.api.java.security.Signature.updateTests test.
>>>


More information about the hotspot-compiler-dev mailing list