RFR: 8276563: Undefined Behaviour in class Assembler [v7]
Mai Đặng Quân Anh
duke at openjdk.java.net
Tue Nov 16 18:01:41 UTC 2021
On Tue, 16 Nov 2021 16:48:06 GMT, Andrew Haley <aph at openjdk.org> wrote:
>> The HotSpot code base contains a number of instances of Undefined Behavior, which can cause all manner of unpleasant surprises.
>> The UB to which this patch relates is in class `Assembler`, in which instances are pointers to (nonexistent) objects defined as, for example,
>>
>>
>> typedef RegisterImpl *Register;
>> const Register r10 = ((Register)10);
>>
>>
>> Registers have accessors, e.g.:
>>
>> ` int RegisterImpl::encoding() const { return (intptr_t)this; }`
>>
>> This works by an accident of implementation: it is not legal C++.
>>
>> The most obvious way to this UB bug is to make instances of `Register` point to something, and to use pointer subtraction to find the encoding: (simplified for clarity)
>>
>>
>> extern RegisterImpl all_Registers[num_Registers];
>> int RegisterImpl::encoding() const { return this - all_Registers; }
>>
>>
>> After this patch there is slightly more work to be done when assembling code but it's merely the subtraction of a constant in `encoding()` and the difference in execution time is so small (and the startup variance so large) that I have been unable to measure it, even after averaging 100 runs. It does lead to an increase of about 1% in the size of the stripped libjvm.so, but I think that can be recovered by a subsequent patch.
>>
>> An alternative way to implement this would be to make the encoding a byte-wide field in `RegisterImpl` and define encoding() this way:
>>
>> ` int RegisterImpl::encoding() const { return _encoding; }`
>>
>> This would result in smaller code, but I suspect slower.
>>
>> If this change is accepted, I propose that all instances of this pattern in HotSpot be treated similarly.
>
> Andrew Haley has updated the pull request incrementally with two additional commits since the last revision:
>
> - Whitespace
> - Simplify and improve portability.
src/hotspot/cpu/aarch64/register_aarch64.hpp line 62:
> 60: // accessors
> 61: int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
> 62: bool is_valid() const { return this >= first() && this - first() < number_of_registers; }
Some tiny suggestions, an unsigned comparison between `this - first()` and `number_of_registers` would be sufficient here.
Suggestion:
bool is_valid() const { (unsigned)(this - first()) < number_of_registers; }
-------------
PR: https://git.openjdk.java.net/jdk/pull/6280
More information about the hotspot-compiler-dev
mailing list