Request for reviews (S): 7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29

Vladimir Kozlov vladimir.kozlov at oracle.com
Wed Feb 15 11:47:59 PST 2012


The prolog code is changed as Tom suggested and I moved prolog assembler code 
generation into macroassembler since it is almost the same for 32 and 64-bit. 
But I kept format code separate.

http://cr.openjdk.java.net/~kvn/7125136/webrev

Thanks,
Vladimir

Vladimir Kozlov wrote:
>  > Is there any issue with having to different prologs?  Why not use the 
> SUB/MOV variant all the time?
> 
> No problems, I think, only size of prolog: push is one byte and mov 
> could be from 3 to 7 bytes depending on framesize and bitness, sub is 3 
> bytes if framesize fits into byte. So I would like to keep 2 versions 
> separate as in your example.
> 
> And I will move VerifyStackAtCalls and in_24_bit_fp_mode logic down. It 
> will eliminate a need for fat_nop() use.
> 
> Thanks,
> Vladimir
> 
> Tom Rodriguez wrote:
>> On Feb 14, 2012, at 12:51 PM, Vladimir Kozlov wrote:
>>
>>> I updated changes to use fixed fat_nop(). Also changed MachProlog 
>>> code to use masm instructions (have to add subptr_imm32() for that).
>>
>> Would it be possible refactor the code to make this whole thing 
>> simpler?  The VerifyStackAtCalls and in_24_bit_fp_mode logic make it 
>> very complicated.  Can't that stuff all be done after a fairly 
>> standard prolog?  VerifyStackAtCalls would have to use mov instead of 
>> push but that would be ok I think.  So it would be something more like:
>>
>>     if (C->need_stack_bang(framesize)) {
>>       st->print_cr("# stack bang"); st->print("\t");
>>       st->print_cr("PUSHL  EBP"); st->print("\t");
>>       st->print("SUB    ESP,%d\t# Create frame",framesize);
>>     } else {
>>       st->print("SUB    ESP,%d\t# Create frame",framesize);
>>       st->print_cr(""); st->print("\t");
>>       st->print("MOV  [ESP + #%d],EBP",framesize);
>>     }
>>
>>     if( C->in_24_bit_fp_mode() ) {
>>       st->print("FLDCW  24 bit fpu control word");
>>       st->print_cr(""); st->print("\t");
>>     }
>>
>> !   if (VerifyStackAtCalls) { // Majik cookie to verify stack depth
>>       st->print("MOV  [ESP + #%d], 0xBADB100D\t# Majik cookie for 
>> stack depth check", magic_offset);
>>       st->print_cr(""); st->print("\t");
>>       framesize -= wordSize;
>>     }
>>
>> Is there any issue with having to different prologs?  Why not use the 
>> SUB/MOV variant all the time?
>>
>> tom
>>
>>
>>> http://cr.openjdk.java.net/~kvn/7125136/webrev
>>>
>>> Thanks,
>>> Vladimir
>>>
>>> Vladimir Kozlov wrote:
>>>> Yes, the fat_nop() sequence is wrong. It was from old Guide, in new 
>>>> version of the Guide address nops are recommended. So I will change 
>>>> it and use in my code.
>>>> Vladimir
>>>> Vladimir Kozlov wrote:
>>>>> I found that we have already such function fat_nop() but I am not 
>>>>> sure it is correct. I am worried that it is 2 nops in 64-bit VM:
>>>>>
>>>>>  emit_byte(0x66);
>>>>>  emit_byte(0x66);
>>>>>  emit_byte(0x90);
>>>>>  emit_byte(0x66);
>>>>>  emit_byte(0x90);
>>>>>
>>>>> Thanks,
>>>>> Vladimir
>>>>>
>>>>> Vladimir Kozlov wrote:
>>>>>> Christian Thalinger wrote:
>>>>>>> On Feb 14, 2012, at 4:56 PM, Vladimir Kozlov wrote:
>>>>>>>
>>>>>>>> Thank you, Christian
>>>>>>>>
>>>>>>>> We can't use address nop on old cpus (amd before ss2 and intel 
>>>>>>>> before p6, see vm_version_x86.cpp).
>>>>>>> Right, I missed that.  It would be a good idea to have an assert 
>>>>>>> or guarantee checking UseAddressNop in these methods.
>>>>>> I'm thinking now to add new asm function nop_for_patching() which 
>>>>>> will generated either addr_nop_5 or stack_bang based on 
>>>>>> UseAddressNop flag.
>>>>>>
>>>>>> I will add asserts into addr_nop_*().
>>>>>>
>>>>>> Thanks,
>>>>>> Vladimir
>>>>>>
>>>>>>> -- Chris
>>>>>>>
>>>>>>>> I will look on masm definition in MachProlog.
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Vladimir
>>>>>>>>
>>>>>>>> On 2/14/12 1:08 AM, Christian Thalinger wrote:
>>>>>>>>> On Feb 14, 2012, at 5:02 AM, Vladimir Kozlov wrote:
>>>>>>>>>
>>>>>>>>>> http://cr.openjdk.java.net/~kvn/7125136/webrev
>>>>>>>>>>
>>>>>>>>>> 7125136: SIGILL on linux amd64 in gc/ArrayJuggle/Juggle29
>>>>>>>>>>
>>>>>>>>>> Saving RBP register on nmethod's entry broke nmethod's 
>>>>>>>>>> verified entry patching when it become non-entrant. There is 
>>>>>>>>>> big comment in MachPrologNode::emit() about first instruction 
>>>>>>>>>> which should be at lest 5 bytes long. And push(rbp) is one 
>>>>>>>>>> byte instruction. VerifyFPU code also broken (first 
>>>>>>>>>> instruction is pushf). The same with C1 generated code with 
>>>>>>>>>> VerifyFPU and C1Breakpoint.
>>>>>>>>>>
>>>>>>>>>> The only reason we did not noticed this until now is stack 
>>>>>>>>>> bang instruction is usually generated first and it is big 
>>>>>>>>>> (store to stack with big offset). But C2 does not generated it 
>>>>>>>>>> if compiled stack frame is small and no calls in compiled method.
>>>>>>>>>>
>>>>>>>>>> For C2 moved saving EBP after ESP adjustment. And other 
>>>>>>>>>> cleanup in prolog code.
>>>>>>>>>> For C1 generated stack bang with small offset (-256) first if 
>>>>>>>>>> needed.
>>>>>>>>> Why are we using bang_stack_with_offset in this case?  How 
>>>>>>>>> about addr_nop_5?
>>>>>>>>>
>>>>>>>>> It would be better if you would define masm at the beginning of 
>>>>>>>>> MachPrologNode::emit instead of doing it multiple times in if 
>>>>>>>>> clauses.
>>>>>>>>>
>>>>>>>>> Otherwise this looks good.
>>>>>>>>>
>>>>>>>>> -- Chris
>>>>>>>>>
>>>>>>>>>> Verified by examining generated code.
>>>>>>>>>>
>>>>>>>>>> SPARC code is safe since we generate 1 instruction (load from 
>>>>>>>>>> 0) for patching and use signal handler.
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Vladimir
>>


More information about the hotspot-compiler-dev mailing list