ReturnCode VirtualThreadSupport::init()

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;
        }