void JNICALL RequestManager::HandleMethodExit()

in modules/jpda/src/main/native/jdwp/common/agent/core/RequestManager.cpp [1729:1819]


void JNICALL RequestManager::HandleMethodExit(jvmtiEnv* jvmti, JNIEnv* jni,
        jthread thread, jmethodID method, jboolean was_popped_by_exception,
        jvalue return_value)
{
    JDWP_TRACE_ENTRY("HandleMethodExit(" << jvmti << ',' << jni << ',' << thread
        << ',' << method << ',' << was_popped_by_exception << ',' << &return_value << ')');

    // must be non-agent thread
    if (GetThreadManager().IsAgentThread(jni, thread)) {
        return;
    }

    try {
        jvmtiError err;
        EventInfo eInfo;
        memset(&eInfo, 0, sizeof(eInfo));
        eInfo.kind = JDWP_EVENT_METHOD_EXIT;
        eInfo.thread = thread;
        CombinedEventsInfo::CombinedEventsKind combinedKind = CombinedEventsInfo::COMBINED_EVENT_METHOD_EXIT;

        if (ENABLE_COMBINED_METHOD_EXIT_EVENT) {
            // if this combined event was already prediced, ignore event
            if (GetRequestManager().IsPredictedCombinedEvent(jni, eInfo, combinedKind)) {
                return;
            }
        }

        JVMTI_TRACE(err, GetJvmtiEnv()->GetMethodDeclaringClass(method,
            &eInfo.cls));
        if (err != JVMTI_ERROR_NONE) {
            throw AgentException(err);
        }

        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(eInfo.cls,
            &eInfo.signature, 0));
        JvmtiAutoFree jafSignature(eInfo.signature);
        if (err != JVMTI_ERROR_NONE) {
            throw AgentException(err);
        }

        JVMTI_TRACE(err, GetJvmtiEnv()->GetFrameLocation(thread, 0,
            &eInfo.method, &eInfo.location));
        if (err != JVMTI_ERROR_NONE) {
            throw AgentException(err);
        }
        JDWP_ASSERT(method == eInfo.method);

#ifndef NDEBUG
        if (JDWP_TRACE_ENABLED(LOG_KIND_EVENT)) {
            char* name = 0;
            JVMTI_TRACE(err, GetJvmtiEnv()->GetMethodName(eInfo.method, &name, 0, 0));

            jvmtiThreadInfo info;
            JVMTI_TRACE(err, GetJvmtiEnv()->GetThreadInfo(thread, &info));

            JDWP_TRACE_EVENT("METHOD_EXIT event:"
                << " class=" << JDWP_CHECK_NULL(eInfo.signature) 
                << " method=" << JDWP_CHECK_NULL(name)
                << " loc=" << eInfo.location
                << " thread=" << JDWP_CHECK_NULL(info.name));
        }
#endif // NDEBUG

        // there are no combined events to be generated after METHOD_EXIT event

        jint eventCount = 0;
        RequestID *eventList = 0;
        jdwpSuspendPolicy sp = JDWP_SUSPEND_NONE;
        GetRequestManager().GenerateEvents(jni, eInfo, eventCount, eventList, sp);
        AgentAutoFree aafEL(eventList JDWP_FILE_LINE);

        // post generated events
        if (eventCount > 0) {
            jdwpTypeTag typeTag = GetClassManager().GetJdwpTypeTag(eInfo.cls);
            EventComposer *ec = new EventComposer(GetEventDispatcher().NewId(),
                JDWP_COMMAND_SET_EVENT, JDWP_COMMAND_E_COMPOSITE, sp);
            ec->event.WriteInt(eventCount);
            for (jint i = 0; i < eventCount; i++) {
                ec->event.WriteByte(JDWP_EVENT_METHOD_EXIT);
                ec->event.WriteInt(eventList[i]);
                ec->WriteThread(jni, thread);
                ec->event.WriteLocation(jni,
                    typeTag, eInfo.cls, method, eInfo.location);
            }
            JDWP_TRACE_EVENT("MethodExit: post set of " << eventCount << " events");
            GetEventDispatcher().PostEventSet(jni, ec, JDWP_EVENT_METHOD_EXIT);
        }
    } catch (AgentException& e) {
        JDWP_INFO("JDWP error in METHOD_EXIT: " << e.what() << " [" << e.ErrCode() << "]");
    }
}