in jvmti-access/src/main/jni/VirtualThreadSupport.cpp [86:151]
ReturnCode VirtualThreadSupport::init(JNIEnv* env, jvmtiEnv* jvmti) {
this->jvmti = jvmti;
this->unsupportedReason = "Not yet initialized";
this->eventsEnabled = false;
jint version;
auto error = jvmti->GetVersionNumber(&version);
if (error != JVMTI_ERROR_NONE) {
return raiseExceptionAndReturn(env, ReturnCode::ERROR, "jvmti->GetVersionNumber() returned error code ", error);
}
if (version < JVMTI_VERSION_21) {
this->unsupportedReason = "This JVM does not support JVMTI version 21+";
return ReturnCode::SUCCESS;
}
jvmtiCapabilities supportedCapabilities;
auto supErr =jvmti->GetPotentialCapabilities(&supportedCapabilities);
if(supErr != JVMTI_ERROR_NONE) {
return raiseExceptionAndReturn(env, ReturnCode::ERROR, "Failed to get JVMTI supported capabilities", supErr);
}
bool virtualThreadsCapabilitySupported = supportedCapabilities.can_support_virtual_threads != 0;
if (!virtualThreadsCapabilitySupported) {
this->unsupportedReason = "The JVMTI environment can not support the can_support_virtual_threads capability";
return ReturnCode::SUCCESS;
}
jvmtiCapabilities caps = {};
caps.can_support_virtual_threads = 1;
auto capErr = jvmti->AddCapabilities(&caps);
if(capErr != JVMTI_ERROR_NONE) {
return raiseExceptionAndReturn(env, ReturnCode::ERROR, "Failed to add virtual threads capability, return code is", capErr);
}
jint extensionCount;
jvmtiExtensionEventInfo* extensionInfos;
error = jvmti->GetExtensionEvents(&extensionCount, &extensionInfos);
if (error != JVMTI_ERROR_NONE) {
return raiseExceptionAndReturn(env, ReturnCode::ERROR, "jvmti->GetExtensionEvents() returned error code ", error);
}
mountEventIdx = -1;
unmountEventIdx = -1;
for(int i=0; i<extensionCount; i++) {
if(isExpectedMountEvent(extensionInfos[i])) {
mountEventIdx = extensionInfos[i].extension_event_index;
}
if(isExpectedUnmountEvent(extensionInfos[i])) {
unmountEventIdx = extensionInfos[i].extension_event_index;
}
}
jvmti->Deallocate((unsigned char*) extensionInfos);
if (mountEventIdx == -1) {
this->unsupportedReason = "This JVM does not support the JVMTI com.sun.hotspot.events.VirtualThreadMount event";
return ReturnCode::SUCCESS;
}
if (unmountEventIdx == -1) {
this->unsupportedReason = "This JVM does not support the JVMTI com.sun.hotspot.events.VirtualThreadUnmount event";
return ReturnCode::SUCCESS;
}
this->unsupportedReason = "";
return ReturnCode::SUCCESS;
}