RFR [XS] 8041658: Use of -fdevirtualize on macroAssembler_x86.o (via -O2) with gcc 4.9.0 creates broken VM
John Rose
john.r.rose at oracle.com
Fri Apr 25 00:10:09 UTC 2014
On Apr 24, 2014, at 9:41 AM, Andrew Haley <aph at redhat.com> wrote:
> On 04/24/2014 05:21 PM, Volker Simonis wrote:
>> And I'm not quite sure how to fix this in HotSpot.
>>
>> I first thought I could solve this with an anonymous union like:
>>
>> union {
>> void* _relocbuf[ _relocbuf_size ];
>> Relocation _reloc;
>> }
>> Relocation* reloc() const { return &_reloc; }
>>
>> but unfortunately I can't put a Relocation into a union because it is
>> not a POD (at least not with C++98).
>>
>> Any other ideas how we could fool GCC 4.9?
>>
>> I more and more think this should be fixed in GCC because I can
>> imagine this will also break other code.
>
> Only code that is not legal C++, and GCC developers have historically
> been very reluctant to support that. So, it might not happen.
>
> AFAICS there is no C++98 way to embed a non-POD object in an object in this
> way. It could be done via a pointer, but that wastes some space.
That design (RelocationHolder, bitwise non-PODS copy) was committed 1998-02-27. (Full discl.—courtesy of yours truly.) It may well be illegal C++98.
Sorry it got in your way. We've seen occasional problems with it before at high optimization levels. And I agree that current C++ standards make this doubtful usage.
The goal of it (as nearby comments suggest) is to allow all three of these things to be true at once:
- we are traversing a stored stream of N records
- each record can have a class with class-specific behaviors (virtual methods, vtbl)
- storage consumption is O(1), and there are O(1) mallocs and frees
This can be done easily (I think it is still the case) by allocating a suitable buffer in the stream object, and using placed new to create each successive record produced by the stream. These guys can be non-PODS with virtuals. (I hope that's still the case...)
A fourth goal makes everything more dicey:
- buffers containing records can be copied around without malloc; functions can bitwise-return PODS buffers containing the non-PODS
This is a hack for allowing functions to create a non-PODS record (with virtuals, etc.) without allocating it.
Perhaps we lean too hard on the fourth point; it's hard to tell without detailed investigation. Easy workaround: Functions which need to do this thing could require the caller to pass a scratch buffer (RelocationHolder) to use with placed new, if a new record is to be returned.
Perhaps also there are better, more standard ways to do this sort of thing.
— John
P.S. As a separate detail, the stream of 16-bit data, as a way to reduce size, was already out of date in 1998, and I regret the cleverness I spent enhancing it. I've wanted for a long time to rewrite that stuff using compressedStream.hpp as a carrier for the bits.
More information about the hotspot-dev
mailing list