Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion ddprof-lib/src/main/cpp/frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,11 @@ class FrameType {
return (FrameTypeId)((bci >> TYPE_SHIFT) & FRAME_TYPE_MASK);
}

// Raw pointers only exist on HotSpot (see hotspotSupport.cpp fillFrameRaw).
// On other VMs an unencoded, VM-supplied bci can coincidentally have bit 30
// set; that must not be mistaken for our raw-pointer encoding.
static inline bool isRawPointer(int bci) {
return bci > 0 && (bci & RAW_POINTER_MASK) != 0;
return VM::isHotspot() && bci > 0 && (bci & RAW_POINTER_MASK) != 0;
}
};

Expand Down
31 changes: 28 additions & 3 deletions ddprof-lib/src/test/cpp/frame_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
#include "../../main/cpp/frame.h"
#include "../../main/cpp/gtest_crash_handler.h"

// VMTestAccessor — friend of VM, lets tests toggle VM::isHotspot() since
// isRawPointer() now gates on it (raw pointers only exist on HotSpot).
class VMTestAccessor {
public:
static bool getHotspot() { return VM::_hotspot; }
static void setHotspot(bool v) { VM::_hotspot = v; }
};

static constexpr char FRAME_TEST_NAME[] = "FrameTest";

class GlobalSetup {
Expand Down Expand Up @@ -139,12 +147,29 @@ TEST(FrameTypeIsRawPointerTest, FalseForEncodedWithoutFlag) {
}
}

TEST(FrameTypeIsRawPointerTest, TrueWhenBit30IsSet) {
// Manually set the raw-pointer flag (bit 30) on an encoded value
TEST(FrameTypeIsRawPointerTest, TrueWhenBit30IsSetOnHotspot) {
// Manually set the raw-pointer flag (bit 30) on an encoded value.
// Raw pointers only exist on HotSpot, so isRawPointer() must be gated on it.
bool saved = VMTestAccessor::getHotspot();
VMTestAccessor::setHotspot(true);
int base = FrameType::encode(FRAME_JIT_COMPILED, 0);
int withFlag = base | (1 << 30);
EXPECT_TRUE(FrameType::isRawPointer(withFlag))
<< "isRawPointer() must be true when bit 30 is set and value is positive";
<< "isRawPointer() must be true when bit 30 is set, value is positive, and VM is HotSpot";
VMTestAccessor::setHotspot(saved);
}

TEST(FrameTypeIsRawPointerTest, FalseWhenBit30IsSetOnNonHotspot) {
// Non-HotSpot VMs can coincidentally produce an unencoded bci with bit 30
// set (e.g. OpenJ9's raw AsyncGetCallTrace output); that must not be
// mistaken for HotSpot's raw-pointer encoding.
bool saved = VMTestAccessor::getHotspot();
VMTestAccessor::setHotspot(false);
int base = FrameType::encode(FRAME_JIT_COMPILED, 0);
int withFlag = base | (1 << 30);
EXPECT_FALSE(FrameType::isRawPointer(withFlag))
<< "isRawPointer() must be false when VM is not HotSpot, even with bit 30 set";
VMTestAccessor::setHotspot(saved);
}
Comment thread
jbachorik marked this conversation as resolved.

TEST(FrameTypeIsRawPointerTest, FalseWithOnlyBit30SetOnNegative) {
Expand Down
Loading