RFR: 8354954: Typed static memory for late initialization of static class members in Hotspot [v4]
Johan Sjölen
jsjolen at openjdk.org
Tue Apr 22 10:48:56 UTC 2025
On Tue, 22 Apr 2025 04:58:23 GMT, Quan Anh Mai <qamai at openjdk.org> wrote:
>> I believe you are right, we do not need launder here. From [[class.union]/6](https://eel.is/c++draft/class.union#6):
>>
>>> [Note [5](https://eel.is/c++draft/class.union#general-note-5): In cases where the above rule does not apply, the active member of a union can only be changed by the use of a placement [new-expression](https://eel.is/c++draft/expr.new#nt:new-expression)[.](https://eel.is/c++draft/class.union#general-6.sentence-1) — end note]
>> [Example [3](https://eel.is/c++draft/class.union#general-example-3): Consider an object u of a union type U having non-static data members m of type M and n of type N[.](https://eel.is/c++draft/class.union#general-6.sentence-2) If M has a non-trivial destructor and N has a non-trivial constructor (for instance, if they declare or inherit virtual functions), the active member of u can be safely switched from m to n using the destructor and placement [new-expression](https://eel.is/c++draft/expr.new#nt:new-expression) as follows:
>> u.m.~M();
>> new (&u.n) N;
>> — end example]
>>
>> We can see that `::new(_&obj) T()` is considered an act to make `_obj` active, not to create a new `T`, the `_obj` itself has been created before at this location, it is just that it has not been initialized and its lifetime has not started. As a result, `_obj` can be used to refer to this object without launder.
>
> ~~To be perfectly clear, we can just remove launder from the patch, and do not need to do this:~~
>
> template<typename... Args>
> void initialize(Args&&... args) {
> assert(!_initialized, "already initialized");
> using NCVP = std::add_pointer_t<std::remove_cv_t<T>>;
> ::new (const_cast<NCVP>(_obj)) T(std::forward<Args>(args)...);
> }
>
> ~~Just do it normal:~~
>
> template<typename... Args>
> void initialize(Args&&... args) {
> assert(!_initialized, "already initialized");
> ::new (&_obj) T(std::forward<Args>(args)...);
> }
>
> Edit: Ah I misunderstood this part it is needed to support `const`.
Good, I've removed the launder. I see your point re: const-ness.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/24689#discussion_r2053844382
More information about the hotspot-dev
mailing list