8333354: ubsan: frame.inline.hpp:91:25: and src/hotspot/share/runtime/frame.inline.hpp:88:29: runtime error: member call on null pointer of type 'const struct SmallRegisterMap'

Backport-of: 8162832832
This commit is contained in:
Matthias Baesken
2024-08-22 17:49:47 +00:00
committed by Vitaly Provodin
parent 07db9458cc
commit 0db245a15a
10 changed files with 67 additions and 81 deletions

View File

@@ -30,8 +30,15 @@
// Java frames don't have callee saved registers (except for rfp), so we can use a smaller RegisterMap
class SmallRegisterMap {
constexpr SmallRegisterMap() = default;
~SmallRegisterMap() = default;
NONCOPYABLE(SmallRegisterMap);
public:
static constexpr SmallRegisterMap* instance = nullptr;
static const SmallRegisterMap* instance() {
static constexpr SmallRegisterMap the_instance{};
return &the_instance;
}
private:
static void assert_is_rfp(VMReg r) NOT_DEBUG_RETURN
DEBUG_ONLY({ assert (r == rfp->as_VMReg() || r == rfp->as_VMReg()->next(), "Reg: %s", r->name()); })
@@ -48,17 +55,6 @@ public:
return map;
}
SmallRegisterMap() {}
SmallRegisterMap(const RegisterMap* map) {
#ifdef ASSERT
for(int i = 0; i < RegisterMap::reg_count; i++) {
VMReg r = VMRegImpl::as_VMReg(i);
if (map->location(r, (intptr_t*)nullptr) != nullptr) assert_is_rfp(r);
}
#endif
}
inline address location(VMReg reg, intptr_t* sp) const {
assert_is_rfp(reg);
return (address)(sp - frame::sender_sp_offset);

View File

@@ -30,8 +30,15 @@
// Java frames don't have callee saved registers (except for rfp), so we can use a smaller RegisterMap
class SmallRegisterMap {
constexpr SmallRegisterMap() = default;
~SmallRegisterMap() = default;
NONCOPYABLE(SmallRegisterMap);
public:
static constexpr SmallRegisterMap* instance = nullptr;
static const SmallRegisterMap* instance() {
static constexpr SmallRegisterMap the_instance{};
return &the_instance;
}
private:
static void assert_is_rfp(VMReg r) NOT_DEBUG_RETURN
DEBUG_ONLY({ Unimplemented(); })
@@ -46,12 +53,6 @@ public:
return map;
}
SmallRegisterMap() {}
SmallRegisterMap(const RegisterMap* map) {
Unimplemented();
}
inline address location(VMReg reg, intptr_t* sp) const {
Unimplemented();
return nullptr;

View File

@@ -30,9 +30,16 @@
// Java frames don't have callee saved registers, so we can use a smaller RegisterMap
class SmallRegisterMap {
constexpr SmallRegisterMap() = default;
~SmallRegisterMap() = default;
NONCOPYABLE(SmallRegisterMap);
public:
static constexpr SmallRegisterMap* instance = nullptr;
public:
static const SmallRegisterMap* instance() {
static constexpr SmallRegisterMap the_instance{};
return &the_instance;
}
// as_RegisterMap is used when we didn't want to templatize and abstract over RegisterMap type to support SmallRegisterMap
// Consider enhancing SmallRegisterMap to support those cases
const RegisterMap* as_RegisterMap() const { return nullptr; }
@@ -44,19 +51,6 @@ public:
return map;
}
SmallRegisterMap() {}
SmallRegisterMap(const RegisterMap* map) {
#ifdef ASSERT
for(int i = 0; i < RegisterMap::reg_count; i++) {
VMReg r = VMRegImpl::as_VMReg(i);
if (map->location(r, (intptr_t*)nullptr) != nullptr) {
assert(false, "Reg: %s", r->name()); // Should not reach here
}
}
#endif
}
inline address location(VMReg reg, intptr_t* sp) const {
assert(false, "Reg: %s", reg->name());
return nullptr;

View File

@@ -30,8 +30,15 @@
// Java frames don't have callee saved registers (except for fp), so we can use a smaller RegisterMap
class SmallRegisterMap {
constexpr SmallRegisterMap() = default;
~SmallRegisterMap() = default;
NONCOPYABLE(SmallRegisterMap);
public:
static constexpr SmallRegisterMap* instance = nullptr;
static const SmallRegisterMap* instance() {
static constexpr SmallRegisterMap the_instance{};
return &the_instance;
}
private:
static void assert_is_fp(VMReg r) NOT_DEBUG_RETURN
DEBUG_ONLY({ assert (r == fp->as_VMReg() || r == fp->as_VMReg()->next(), "Reg: %s", r->name()); })
@@ -48,17 +55,6 @@ public:
return map;
}
SmallRegisterMap() {}
SmallRegisterMap(const RegisterMap* map) {
#ifdef ASSERT
for(int i = 0; i < RegisterMap::reg_count; i++) {
VMReg r = VMRegImpl::as_VMReg(i);
if (map->location(r, (intptr_t*)nullptr) != nullptr) assert_is_fp(r);
}
#endif
}
inline address location(VMReg reg, intptr_t* sp) const {
assert_is_fp(reg);
return (address)(sp - 2);

View File

@@ -30,8 +30,15 @@
// Java frames don't have callee saved registers (except for rfp), so we can use a smaller RegisterMap
class SmallRegisterMap {
constexpr SmallRegisterMap() = default;
~SmallRegisterMap() = default;
NONCOPYABLE(SmallRegisterMap);
public:
static constexpr SmallRegisterMap* instance = nullptr;
static const SmallRegisterMap* instance() {
static constexpr SmallRegisterMap the_instance{};
return &the_instance;
}
private:
static void assert_is_rfp(VMReg r) NOT_DEBUG_RETURN
DEBUG_ONLY({ Unimplemented(); })
@@ -46,12 +53,6 @@ public:
return map;
}
SmallRegisterMap() {}
SmallRegisterMap(const RegisterMap* map) {
Unimplemented();
}
inline address location(VMReg reg, intptr_t* sp) const {
Unimplemented();
return nullptr;

View File

@@ -30,8 +30,16 @@
// Java frames don't have callee saved registers (except for rbp), so we can use a smaller RegisterMap
class SmallRegisterMap {
constexpr SmallRegisterMap() = default;
~SmallRegisterMap() = default;
NONCOPYABLE(SmallRegisterMap);
public:
static constexpr SmallRegisterMap* instance = nullptr;
static const SmallRegisterMap* instance() {
static constexpr SmallRegisterMap the_instance{};
return &the_instance;
}
private:
static void assert_is_rbp(VMReg r) NOT_DEBUG_RETURN
DEBUG_ONLY({ assert(r == rbp->as_VMReg() || r == rbp->as_VMReg()->next(), "Reg: %s", r->name()); })
@@ -48,17 +56,6 @@ public:
return map;
}
SmallRegisterMap() {}
SmallRegisterMap(const RegisterMap* map) {
#ifdef ASSERT
for(int i = 0; i < RegisterMap::reg_count; i++) {
VMReg r = VMRegImpl::as_VMReg(i);
if (map->location(r, (intptr_t*)nullptr) != nullptr) assert_is_rbp(r);
}
#endif
}
inline address location(VMReg reg, intptr_t* sp) const {
assert_is_rbp(reg);
return (address)(sp - frame::sender_sp_offset);

View File

@@ -30,8 +30,15 @@
// Java frames don't have callee saved registers (except for rfp), so we can use a smaller RegisterMap
class SmallRegisterMap {
constexpr SmallRegisterMap() = default;
~SmallRegisterMap() = default;
NONCOPYABLE(SmallRegisterMap);
public:
static constexpr SmallRegisterMap* instance = nullptr;
static const SmallRegisterMap* instance() {
static constexpr SmallRegisterMap the_instance{};
return &the_instance;
}
private:
static void assert_is_rfp(VMReg r) NOT_DEBUG_RETURN
DEBUG_ONLY({ Unimplemented(); })
@@ -46,12 +53,6 @@ public:
return map;
}
SmallRegisterMap() {}
SmallRegisterMap(const RegisterMap* map) {
Unimplemented();
}
inline address location(VMReg reg, intptr_t* sp) const {
Unimplemented();
return nullptr;

View File

@@ -125,7 +125,7 @@ static int num_java_frames(const StackChunkFrameStream<ChunkFrames::Mixed>& f) {
int stackChunkOopDesc::num_java_frames() const {
int n = 0;
for (StackChunkFrameStream<ChunkFrames::Mixed> f(const_cast<stackChunkOopDesc*>(this)); !f.is_done();
f.next(SmallRegisterMap::instance)) {
f.next(SmallRegisterMap::instance())) {
if (!f.is_stub()) {
n += ::num_java_frames(f);
}

View File

@@ -201,7 +201,7 @@ inline void stackChunkOopDesc::iterate_stack(StackChunkFrameClosureType* closure
template <ChunkFrames frame_kind, class StackChunkFrameClosureType>
inline void stackChunkOopDesc::iterate_stack(StackChunkFrameClosureType* closure) {
const SmallRegisterMap* map = SmallRegisterMap::instance;
const SmallRegisterMap* map = SmallRegisterMap::instance();
assert(!map->in_cont(), "");
StackChunkFrameStream<frame_kind> f(this);

View File

@@ -1860,7 +1860,7 @@ int ThawBase::remove_top_compiled_frame_from_chunk(stackChunkOop chunk, int &arg
const int frame_size = f.cb()->frame_size();
argsize = f.stack_argsize();
f.next(SmallRegisterMap::instance, true /* stop */);
f.next(SmallRegisterMap::instance(), true /* stop */);
empty = f.is_done();
assert(!empty || argsize == chunk->argsize(), "");
@@ -2070,7 +2070,7 @@ bool ThawBase::recurse_thaw_java_frame(frame& caller, int num_frames) {
int argsize = _stream.stack_argsize();
_stream.next(SmallRegisterMap::instance);
_stream.next(SmallRegisterMap::instance());
assert(_stream.to_frame().is_empty() == _stream.is_done(), "");
// we never leave a compiled caller of an interpreted frame as the top frame in the chunk
@@ -2178,7 +2178,7 @@ NOINLINE void ThawBase::recurse_thaw_interpreted_frame(const frame& hf, frame& c
assert(hf.is_interpreted_frame(), "");
if (UNLIKELY(seen_by_gc())) {
_cont.tail()->do_barriers<stackChunkOopDesc::BarrierType::Store>(_stream, SmallRegisterMap::instance);
_cont.tail()->do_barriers<stackChunkOopDesc::BarrierType::Store>(_stream, SmallRegisterMap::instance());
}
const bool is_bottom_frame = recurse_thaw_java_frame<ContinuationHelper::InterpretedFrame>(caller, num_frames);
@@ -2221,7 +2221,7 @@ NOINLINE void ThawBase::recurse_thaw_interpreted_frame(const frame& hf, frame& c
if (!is_bottom_frame) {
// can only fix caller once this frame is thawed (due to callee saved regs)
_cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance);
_cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance());
} else if (_cont.tail()->has_bitmap() && locals > 0) {
assert(hf.is_heap_frame(), "should be");
address start = (address)(heap_frame_bottom - locals);
@@ -2238,7 +2238,7 @@ void ThawBase::recurse_thaw_compiled_frame(const frame& hf, frame& caller, int n
assert(_cont.is_preempted() || !stub_caller, "stub caller not at preemption");
if (!stub_caller && UNLIKELY(seen_by_gc())) { // recurse_thaw_stub_frame already invoked our barriers with a full regmap
_cont.tail()->do_barriers<stackChunkOopDesc::BarrierType::Store>(_stream, SmallRegisterMap::instance);
_cont.tail()->do_barriers<stackChunkOopDesc::BarrierType::Store>(_stream, SmallRegisterMap::instance());
}
const bool is_bottom_frame = recurse_thaw_java_frame<ContinuationHelper::CompiledFrame>(caller, num_frames);
@@ -2297,7 +2297,7 @@ void ThawBase::recurse_thaw_compiled_frame(const frame& hf, frame& caller, int n
if (!is_bottom_frame) {
// can only fix caller once this frame is thawed (due to callee saved regs); this happens on the stack
_cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance);
_cont.tail()->fix_thawed_frame(caller, SmallRegisterMap::instance());
} else if (_cont.tail()->has_bitmap() && added_argsize > 0) {
address start = (address)(heap_frame_top + ContinuationHelper::CompiledFrame::size(hf) + frame::metadata_words_at_top);
int stack_args_slots = f.cb()->as_nmethod()->num_stack_arg_slots(false /* rounded */);
@@ -2379,7 +2379,7 @@ void ThawBase::finish_thaw(frame& f) {
f.set_sp(align_down(f.sp(), frame::frame_alignment));
}
push_return_frame(f);
chunk->fix_thawed_frame(f, SmallRegisterMap::instance); // can only fix caller after push_return_frame (due to callee saved regs)
chunk->fix_thawed_frame(f, SmallRegisterMap::instance()); // can only fix caller after push_return_frame (due to callee saved regs)
assert(_cont.is_empty() == _cont.last_frame().is_empty(), "");