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