RFR: 8340392: Handle OopStorage in location decoder [v4]
Kim Barrett
kbarrett at openjdk.org
Thu Sep 19 07:26:40 UTC 2024
On Thu, 19 Sep 2024 05:42:18 GMT, Aleksey Shipilev <shade at openjdk.org> wrote:
>> Another debugging QoL improvement. Currently, when there is a pointer into `OopStorage` that we need to decode for the error log, we just print:
>>
>> 0x00007ad45c169e10 into live malloced block starting at 0x00007ad45c169dd0, size 632, tag mtInternal
>>
>>
>> This is reported by NMT after [JDK-8304815](https://bugs.openjdk.org/browse/JDK-8304815). It is likely worse without NMT. We can actually decode which block in which `OopStorage` the address likely belongs to. This becomes handy when debugging GC crashes that involve `OopStorage`-handled roots.
>>
>> This patch is able to print the following instead:
>>
>>
>> 0x0000000102c05bd0 is a pointer 2/64 into block 0 in oop storage "VM Global"
>
> Aleksey Shipilev has updated the pull request incrementally with two additional commits since the last revision:
>
> - Try to handle unaligned pointers well
> - Indenting and formats
Changes requested by kbarrett (Reviewer).
src/hotspot/share/gc/shared/oopStorageSet.cpp line 86:
> 84:
> 85: bool OopStorageSet::print_containing(const void* addr, outputStream* st) {
> 86: const void* aligned_addr = align_down(addr, alignof(oop*));
Should be `alignof(oop)`.
src/hotspot/share/gc/shared/oopStorageSet.cpp line 87:
> 85: bool OopStorageSet::print_containing(const void* addr, outputStream* st) {
> 86: const void* aligned_addr = align_down(addr, alignof(oop*));
> 87: if (aligned_addr != nullptr) {
I think the nullptr check should come first. Pointer arithmetic can't produce a null pointer (because
of UB), so I think a sufficiently smart might be able to conclude that this test is always true in the
absence of UB in the alignment code.
src/hotspot/share/gc/shared/oopStorageSet.cpp line 88:
> 86: const void* aligned_addr = align_down(addr, alignof(oop*));
> 87: if (aligned_addr != nullptr) {
> 88: for (uint i = 0; i < OopStorageSet::all_count; i++) {
Don't need the `OopStorageSet::` qualifier here, since we're in that class already.
But better would be to iterate over the storages using the provided iteration mechanism:
for (OopStorage* storage : Range<Id>()) {
...
}
test/hotspot/gtest/gc/shared/test_oopStorageSet.cpp line 139:
> 137: void doit() {
> 138: PrintContainingClosure cl;
> 139: for (auto id: EnumRange<OopStorageSet::Id>()) {
Instead use
for (OopStorage* storage : OopStorageSet::Range<OopStorageSet::Id>()) {
...
}
test/hotspot/gtest/gc/shared/test_oopStorageSet.cpp line 166:
> 164: {
> 165: stringStream ss;
> 166: bool printed = OopStorageSet::print_containing((char*)0x8, &ss);
Instead of hard-coded 0x8, instead use alignof(oop).
-------------
PR Review: https://git.openjdk.org/jdk/pull/21072#pullrequestreview-2314518336
PR Review Comment: https://git.openjdk.org/jdk/pull/21072#discussion_r1766234492
PR Review Comment: https://git.openjdk.org/jdk/pull/21072#discussion_r1766237573
PR Review Comment: https://git.openjdk.org/jdk/pull/21072#discussion_r1766241306
PR Review Comment: https://git.openjdk.org/jdk/pull/21072#discussion_r1766297311
PR Review Comment: https://git.openjdk.org/jdk/pull/21072#discussion_r1766282757
More information about the hotspot-dev
mailing list