6880034: Change 6420645 causes SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
Vladimir Kozlov
Vladimir.Kozlov at Sun.COM
Wed Sep 30 12:18:40 PDT 2009
Volker Simonis wrote:
> I don't know why this strange encoding has been chosen for the 16
> upper double registers in sparc.ad, but changing it to:
>
> reg_def R_D32x(SOC, SOC, Op_RegD,255, F32->as_VMReg()->next());
> reg_def R_D32 (SOC, SOC, Op_RegD, 1, F32->as_VMReg());
> reg_def R_D34x(SOC, SOC, Op_RegD,255, F34->as_VMReg()->next());
> reg_def R_D34 (SOC, SOC, Op_RegD, 3, F34->as_VMReg());
> ...
> reg_def R_D62x(SOC, SOC, Op_RegD,255, F62->as_VMReg()->next());
> reg_def R_D62 (SOC, SOC, Op_RegD, 31, F62->as_VMReg());
>
> which seems more natural to me, solved the SIGBUS issue and didn't
> revealed any other problems in the tests which I run so far.
>
> Could you please comment on the proposed solution of changing the
> VMReg numbering of F32-F62 or advice a better solution if you think
> that the proposed one will not work in the general case?
>
> Thank you and best regards,
> Volker
Your changes are correct but I would also swap definitions
to be more clear.
reg_def R_D32 (SOC, SOC, Op_RegD, 1, F32->as_VMReg());
reg_def R_D32x(SOC, SOC, Op_RegD,255, F32->as_VMReg()->next());
reg_def R_D34 (SOC, SOC, Op_RegD, 3, F34->as_VMReg());
reg_def R_D34x(SOC, SOC, Op_RegD,255, F34->as_VMReg()->next());
I looked on the history and originally it was
reg_def R_D32( SOC, SOC, Op_RegD, 1, 0 );
reg_def R_D32L(SOC, SOC, Op_RegD, 99, 0 );
reg_def R_D34( SOC, SOC, Op_RegD, 3, 0 );
reg_def R_D34L(SOC, SOC, Op_RegD, 99, 0 );
where R_D32L and R_D34L represented nonexisting F33 and F35
low 32 bits halves of D32 and D34.
Then the ordering of declarations was changed and introduced
the confusion:
reg_def R_D32x(SOC, SOC, Op_RegD,255, 0 );
reg_def R_D32 (SOC, SOC, Op_RegD, 1, 0 );
reg_def R_D34x(SOC, SOC, Op_RegD,255, 0 );
reg_def R_D34 (SOC, SOC, Op_RegD, 3, 0 );
Vladimir
Tom Rodriguez wrote:
>> The problem can be easily solved by switching back to the old
>> implementation of frame::oopmapreg_to_location(), but I assume there
>> was a rational behind the change and that the new implementation is
>> probably necessary for compressed oops (at least that's what the whole
>> change was all about). So I dug a little further and found that in my
>> opinion the root cause of the whole problem is the strange numbering
>> of the 16 upper double registers in sparc.ad. They are defined as
>> follows:
>>
>> reg_def R_D32x(SOC, SOC, Op_RegD,255, F32->as_VMReg());
>> reg_def R_D32 (SOC, SOC, Op_RegD, 1, F32->as_VMReg()->next());
>> reg_def R_D34x(SOC, SOC, Op_RegD,255, F34->as_VMReg());
>> reg_def R_D34 (SOC, SOC, Op_RegD, 3, F34->as_VMReg()->next());
>> ...
>> reg_def R_D62x(SOC, SOC, Op_RegD,255, F62->as_VMReg());
>> reg_def R_D62 (SOC, SOC, Op_RegD, 31, F62->as_VMReg()->next());
>
> I don't really know why it's done this way. It's certainly not
> consistent with the others. If it all works better I'd be ok with
> correcting.
>
>> PS: while I was hunting the error, I also stumbled across the
>> following code in RegisterSaver::save_live_registers():
>>
>> // Save all the FP registers
>> int offset = d00_offset;
>> for( int i=0; i<64; i+=2 ) {
>> FloatRegister f = as_FloatRegister(i);
>> __ stf(FloatRegisterImpl::D, f, SP, offset+STACK_BIAS);
>> map->set_callee_saved(VMRegImpl::stack2reg(offset>>2), f->as_VMReg());
>> if (true) {
>> map->set_callee_saved(VMRegImpl::stack2reg((offset +
>> sizeof(float))>>2), f->as_VMReg()->next());
>> }
>> offset += sizeof(double);
>> }
>
> That would probably be ok too.
>
> tom
>
>>
>> In my opinion, this could be changed to:
>>
>> // Save all the FP registers
>> int offset = d00_offset;
>> for( int i=0; i<64; i+=2 ) {
>> FloatRegister f = as_FloatRegister(i);
>> __ stf(FloatRegisterImpl::D, f, SP, offset+STACK_BIAS);
>> map->set_callee_saved(VMRegImpl::stack2reg(offset>>2), f->as_VMReg());
>> if (i < 32) { // VS 2009-08-31: the 16 upper double registers
>> can't be used as floats anyway
>> map->set_callee_saved(VMRegImpl::stack2reg((offset +
>> sizeof(float))>>2), f->as_VMReg()->next());
>> }
>> offset += sizeof(double);
>> }
>>
>> because the 16 upper double registers can't be used as floats anyway.
>> Again, I didn't found any regression in my few tests. What do you
>> think?
>> <DeoptTest.java>
>
More information about the hotspot-compiler-dev
mailing list