Skip to content

Commit 0f253d1

Browse files
committedSep 23, 2024
8340392: Handle OopStorage in location decoder
Reviewed-by: kbarrett, dholmes
1 parent f31f97d commit 0f253d1

File tree

7 files changed

+132
-1
lines changed

7 files changed

+132
-1
lines changed
 

‎src/hotspot/share/gc/shared/oopStorage.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,26 @@ void OopStorage::BasicParState::report_num_dead() const {
11351135

11361136
const char* OopStorage::name() const { return _name; }
11371137

1138+
bool OopStorage::print_containing(const oop* addr, outputStream* st) {
1139+
if (addr != nullptr) {
1140+
Block* block = find_block_or_null(addr);
1141+
if (block != nullptr && block->print_containing(addr, st)) {
1142+
st->print(" in oop storage \"%s\"", name());
1143+
return true;
1144+
}
1145+
}
1146+
return false;
1147+
}
1148+
1149+
bool OopStorage::Block::print_containing(const oop* addr, outputStream* st) {
1150+
if (contains(addr)) {
1151+
st->print(PTR_FORMAT " is a pointer %u/%zu into block %zu",
1152+
p2i(addr), get_index(addr), ARRAY_SIZE(_data), _active_index);
1153+
return true;
1154+
}
1155+
return false;
1156+
}
1157+
11381158
#ifndef PRODUCT
11391159

11401160
void OopStorage::print_on(outputStream* st) const {

‎src/hotspot/share/gc/shared/oopStorage.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ class OopStorage : public CHeapObjBase {
213213
// Debugging and logging support.
214214
const char* name() const;
215215
void print_on(outputStream* st) const PRODUCT_RETURN;
216+
bool print_containing(const oop* addr, outputStream* st);
216217

217218
// Provides access to storage internals, for unit testing.
218219
// Declare, but not define, the public class OopStorage::TestAccess.

‎src/hotspot/share/gc/shared/oopStorage.inline.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ class OopStorage::Block /* No base class, to avoid messing up alignment. */ {
196196

197197
template<typename F> bool iterate(F f);
198198
template<typename F> bool iterate(F f) const;
199+
200+
bool print_containing(const oop* addr, outputStream* st);
199201
}; // class Block
200202

201203
inline OopStorage::Block* OopStorage::AllocationList::head() {

‎src/hotspot/share/gc/shared/oopStorageSet.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,23 @@ template OopStorage* OopStorageSet::get_storage(StrongId);
8282
template OopStorage* OopStorageSet::get_storage(WeakId);
8383
template OopStorage* OopStorageSet::get_storage(Id);
8484

85+
bool OopStorageSet::print_containing(const void* addr, outputStream* st) {
86+
if (addr != nullptr) {
87+
const void* aligned_addr = align_down(addr, alignof(oop));
88+
for (OopStorage* storage : Range<Id>()) {
89+
if (storage->print_containing((oop*) aligned_addr, st)) {
90+
if (aligned_addr != addr) {
91+
st->print_cr(" (unaligned)");
92+
} else {
93+
st->cr();
94+
}
95+
return true;
96+
}
97+
}
98+
}
99+
return false;
100+
}
101+
85102
#ifdef ASSERT
86103

87104
void OopStorageSet::verify_initialized(uint index) {

‎src/hotspot/share/gc/shared/oopStorageSet.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#define SHARE_GC_SHARED_OOPSTORAGESET_HPP
2727

2828
#include "nmt/memTag.hpp"
29+
#include "oops/oop.hpp"
2930
#include "utilities/debug.hpp"
3031
#include "utilities/enumIterator.hpp"
3132
#include "utilities/globalDefinitions.hpp"
@@ -89,6 +90,8 @@ class OopStorageSet : public AllStatic {
8990
template <typename Closure>
9091
static void strong_oops_do(Closure* cl);
9192

93+
// Debugging: print location info, if in storage.
94+
static bool print_containing(const void* addr, outputStream* st);
9295
};
9396

9497
ENUMERATOR_VALUE_RANGE(OopStorageSet::StrongId,

‎src/hotspot/share/runtime/os.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "code/codeCache.hpp"
3333
#include "code/vtableStubs.hpp"
3434
#include "gc/shared/gcVMOperations.hpp"
35+
#include "gc/shared/oopStorageSet.hpp"
3536
#include "interpreter/interpreter.hpp"
3637
#include "jvm.h"
3738
#include "logging/log.hpp"
@@ -1317,6 +1318,11 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
13171318
}
13181319
#endif
13191320

1321+
// Ask if any OopStorage knows about this address.
1322+
if (OopStorageSet::print_containing(addr, st)) {
1323+
return;
1324+
}
1325+
13201326
// Still nothing? If NMT is enabled, we can ask what it thinks...
13211327
if (MemTracker::print_containing_region(addr, st)) {
13221328
return;

‎test/hotspot/gtest/gc/shared/test_oopStorageSet.cpp

+83-1
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,21 @@
2323
*/
2424

2525
#include "precompiled.hpp"
26-
#include "gc/shared/oopStorage.hpp"
26+
#include "gc/shared/oopStorage.inline.hpp"
2727
#include "gc/shared/oopStorageSet.hpp"
2828
#include "memory/allocation.inline.hpp"
29+
#include "runtime/interfaceSupport.inline.hpp"
30+
#include "runtime/vmOperations.hpp"
31+
#include "runtime/vmThread.hpp"
2932
#include "utilities/debug.hpp"
3033
#include "utilities/enumIterator.hpp"
3134
#include "utilities/globalDefinitions.hpp"
3235
#include "utilities/macros.hpp"
3336
#include "unittest.hpp"
3437

38+
using ::testing::HasSubstr;
39+
using ::testing::Not;
40+
3541
class OopStorageSetTest : public ::testing::Test {
3642
protected:
3743
// Returns index of s in storages, or size if not found.
@@ -83,6 +89,8 @@ class OopStorageSetTest : public ::testing::Test {
8389
EnumRange<OopStorageSet::Id>(),
8490
&OopStorageSet::fill_all);
8591
}
92+
93+
class VM_PrintAtSafepoint;
8694
};
8795

8896
TEST_VM_F(OopStorageSetTest, strong_iteration) {
@@ -96,3 +104,77 @@ TEST_VM_F(OopStorageSetTest, weak_iteration) {
96104
TEST_VM_F(OopStorageSetTest, all_iteration) {
97105
test_all_iteration();
98106
}
107+
108+
class OopStorageSetTest::VM_PrintAtSafepoint : public VM_GTestExecuteAtSafepoint {
109+
private:
110+
class PrintContainingClosure : public Closure {
111+
public:
112+
void do_oop(oop* addr) {
113+
// Direct slot hit.
114+
{
115+
stringStream ss;
116+
bool printed = OopStorageSet::print_containing(addr, &ss);
117+
ASSERT_TRUE(printed);
118+
ASSERT_THAT(ss.freeze(), HasSubstr("is a pointer"));
119+
ASSERT_THAT(ss.freeze(), HasSubstr("into block"));
120+
ASSERT_THAT(ss.freeze(), HasSubstr("in oop storage"));
121+
ASSERT_THAT(ss.freeze(), Not(HasSubstr("(unaligned)")));
122+
}
123+
124+
// Unaligned pointer to adjacent slot, should still be in oop storage range.
125+
{
126+
char* unaligned_addr = (char*)addr + 1;
127+
stringStream ss;
128+
bool printed = OopStorageSet::print_containing(unaligned_addr, &ss);
129+
ASSERT_TRUE(printed);
130+
ASSERT_THAT(ss.freeze(), HasSubstr("is a pointer"));
131+
ASSERT_THAT(ss.freeze(), HasSubstr("into block"));
132+
ASSERT_THAT(ss.freeze(), HasSubstr("in oop storage"));
133+
ASSERT_THAT(ss.freeze(), HasSubstr("(unaligned)"));
134+
}
135+
}
136+
};
137+
138+
public:
139+
void doit() {
140+
PrintContainingClosure cl;
141+
for (OopStorage* storage : OopStorageSet::Range<OopStorageSet::Id>()) {
142+
storage->oops_do(&cl);
143+
}
144+
}
145+
};
146+
147+
TEST_VM_F(OopStorageSetTest, print_containing) {
148+
// nullptrs print nothing
149+
{
150+
stringStream ss;
151+
bool printed = OopStorageSet::print_containing(nullptr, &ss);
152+
ASSERT_FALSE(printed);
153+
EXPECT_STREQ("", ss.freeze());
154+
}
155+
156+
// Goofy values print nothing: unaligned out of storage pointer.
157+
{
158+
stringStream ss;
159+
bool printed = OopStorageSet::print_containing((char*)0x1, &ss);
160+
ASSERT_FALSE(printed);
161+
EXPECT_STREQ("", ss.freeze());
162+
}
163+
164+
// Goofy values print nothing: aligned out of storage pointer.
165+
{
166+
stringStream ss;
167+
bool printed = OopStorageSet::print_containing((char*)alignof(oop), &ss);
168+
ASSERT_FALSE(printed);
169+
EXPECT_STREQ("", ss.freeze());
170+
}
171+
172+
// All slot addresses should print well.
173+
{
174+
VM_PrintAtSafepoint op;
175+
{
176+
ThreadInVMfromNative invm(JavaThread::current());
177+
VMThread::execute(&op);
178+
}
179+
}
180+
}

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on Sep 23, 2024

@openjdk-notifier[bot]
Please sign in to comment.