bool HeapMonitor::Supported(jvmtiEnv *jvmti) {
jvmtiCapabilities caps;
memset(&caps, 0, sizeof(caps));
if (jvmti->GetPotentialCapabilities(&caps) != JVMTI_ERROR_NONE) {
LOG(WARNING) << "Failed to get potential capabilities, disabling the heap "
<< "sampling monitor";
return false;
}
return caps.can_generate_sampled_object_alloc_events
&& caps.can_generate_garbage_collection_events;
}
For pre-JDK11, you would have a compilation error so you would have to do something like:
bool HeapMonitor::Supported(jvmtiEnv *jvmti) {
#ifdef ENABLE_HEAP_SAMPLING
jvmtiCapabilities caps;
memset(&caps, 0, sizeof(caps));
if (jvmti->GetPotentialCapabilities(&caps) != JVMTI_ERROR_NONE) {
LOG(WARNING) << "Failed to get potential capabilities, disabling the heap "
<< "sampling monitor";
return false;
}
return caps.can_generate_sampled_object_alloc_events
&& caps.can_generate_garbage_collection_events;
#else
return false;
#endif
}
But now you need to know at compile time which JVMTI version is being used to define that macro... So things get pretty messy in the agent code for handling various JDK versions.
#if do not play nice with enums, so the idea is to have something like:
enum {
JVMTI_VERSION_1 = 0x30010000,
JVMTI_VERSION_1_0 = 0x30010000,
JVMTI_VERSION_1_1 = 0x30010100,
JVMTI_VERSION_1_2 = 0x30010200,
JVMTI_VERSION_9 = 0x30090000,
JVMTI_VERSION_11 = 0x300B0000,
JVMTI_VERSION = 0x30000000 + (11 * 0x10000) + (0 * 0x100) + 0 /* version: 11.0.0 */
};
#define JVMTI_LATEST_VERSION (0x30000000 + (11 * 0x10000) + (0 * 0x100) + 0 /* version: 11.0.0 */)
Special note: this would not work:
#define JVMTI_LATEST_VERSION JVMTI_VERSION
Because the macro will get preprocessed into an enum, it won't be able to be used at compilation time correctly. We really need a full explicit literal number for the define.
Also note that this technically means that agents will be playing with the actual format and numeric versioning numbering to do something like:
// Our own agent versioning numbering system so that we can #if with it.
#define JVMTI_VERSION_11 0x300B0000
#if JVMTI_LATEST_VERSION >= JVMTI_VERSION_11
An alternative would be to modify the enum into #defines but it is not sure what are the ramifications of that, ie who is using the enum for type checking.