eventhelper.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,130 行 · 第 1/3 页

C
1,130
字号
/* * @(#)eventHelper.c	1.45 06/10/25 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation.  *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt).  *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA  *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions.  */#include "util.h"#include "outStream.h"#include "eventHandler.h"#include "threadControl.h"#include "invoker.h"/* * Event helper thread command commandKinds */#define COMMAND_REPORT_EVENT_COMPOSITE          1#define COMMAND_REPORT_INVOKE_DONE              2#define COMMAND_REPORT_VM_INIT                  3#define COMMAND_SUSPEND_THREAD                  4/* * Event helper thread command singleKinds */#define COMMAND_SINGLE_EVENT                    11#define COMMAND_SINGLE_UNLOAD                   12#define COMMAND_SINGLE_FRAME_EVENT              13typedef struct EventCommandSingle {    jbyte suspendPolicy; /* NOTE: Must be the first field */    jint id;    EventInfo info;} EventCommandSingle;typedef struct UnloadCommandSingle {    char *classSignature;    jint id;} UnloadCommandSingle;typedef struct FrameEventCommandSingle {    jbyte suspendPolicy; /* NOTE: Must be the first field */    jint id;    EventIndex ei;    jthread thread;    jclass clazz;    jmethodID method;    jlocation location;    char typeKey;         /* Not used for method entry events */                          /* If typeKey is 0, then no return value is needed */    jvalue returnValue;   /* Not used for method entry events */} FrameEventCommandSingle;typedef struct CommandSingle {    jint singleKind;    union {        EventCommandSingle eventCommand;        UnloadCommandSingle unloadCommand;        FrameEventCommandSingle frameEventCommand;    } u;} CommandSingle;typedef struct ReportInvokeDoneCommand {    jthread thread;} ReportInvokeDoneCommand;typedef struct ReportVMInitCommand {    jbyte suspendPolicy; /* NOTE: Must be the first field */    jthread thread;} ReportVMInitCommand;typedef struct SuspendThreadCommand {    jthread thread;} SuspendThreadCommand;typedef struct ReportEventCompositeCommand {    jbyte suspendPolicy; /* NOTE: Must be the first field */    jint eventCount;    CommandSingle singleCommand[1]; /* variable length */} ReportEventCompositeCommand;typedef struct HelperCommand {    jint commandKind;    jboolean done;    jboolean waiting;    jbyte sessionID;    struct HelperCommand *next;    union {        /* NOTE: Each of the structs below must have the same first field */        ReportEventCompositeCommand reportEventComposite;        ReportInvokeDoneCommand     reportInvokeDone;        ReportVMInitCommand         reportVMInit;        SuspendThreadCommand        suspendThread;    } u;    /* composite array expand out, put nothing after */} HelperCommand;typedef struct {    HelperCommand *head;    HelperCommand *tail;} CommandQueue;static CommandQueue commandQueue;static jrawMonitorID commandQueueLock;static jrawMonitorID commandCompleteLock;static jrawMonitorID blockCommandLoopLock;static jint maxQueueSize = 50 * 1024; /* TO DO: Make this configurable */static jboolean holdEvents;static jboolean shutdownEvents = JNI_FALSE;static jint currentQueueSize = 0;static jint currentSessionID;static void saveEventInfoRefs(JNIEnv *env, EventInfo *evinfo);static void tossEventInfoRefs(JNIEnv *env, EventInfo *evinfo);static jint commandSize(HelperCommand *command) {    jint size = sizeof(HelperCommand);    if (command->commandKind == COMMAND_REPORT_EVENT_COMPOSITE) {        /*          * One event is accounted for in the Helper Command. If there are         * more, add to size here.          */        /*LINTED*/        size += ((int)sizeof(CommandSingle) *                      (command->u.reportEventComposite.eventCount - 1));    }    return size;}static voidfreeCommand(HelperCommand *command){    if ( command == NULL )        return;    jvmtiDeallocate(command);}static voidenqueueCommand(HelperCommand *command,                jboolean wait, jboolean reportingVMDeath) {    static jboolean vmDeathReported = JNI_FALSE;    CommandQueue *queue = &commandQueue;    jint size = commandSize(command);        command->done = JNI_FALSE;    command->waiting = wait;    command->next = NULL;    debugMonitorEnter(commandQueueLock);    while (size + currentQueueSize > maxQueueSize) {        debugMonitorWait(commandQueueLock);    }    log_debugee_location("enqueueCommand(): HelperCommand being processed", NULL, NULL, 0);    if (vmDeathReported) {        /* send no more events after VMDeath and don't wait */        wait = JNI_FALSE;    } else {        currentQueueSize += size;        if (queue->head == NULL) {            queue->head = command;        } else {            queue->tail->next = command;        }        queue->tail = command;        if (reportingVMDeath) {            vmDeathReported = JNI_TRUE;        }    }    debugMonitorNotifyAll(commandQueueLock);    debugMonitorExit(commandQueueLock);        if (wait) {        debugMonitorEnter(commandCompleteLock);        while (!command->done) {            log_debugee_location("enqueueCommand(): HelperCommand wait", NULL, NULL, 0);            debugMonitorWait(commandCompleteLock);        }        freeCommand(command);        debugMonitorExit(commandCompleteLock);    }}static void completeCommand(HelperCommand *command) {    if (command->waiting) {        debugMonitorEnter(commandCompleteLock);        command->done = JNI_TRUE;        log_debugee_location("completeCommand(): HelperCommand done waiting", NULL, NULL, 0);        debugMonitorNotifyAll(commandCompleteLock);        debugMonitorExit(commandCompleteLock);    } else {        freeCommand(command);    }}static HelperCommand *dequeueCommand(void){    HelperCommand *command = NULL;    CommandQueue *queue = &commandQueue;    jint size;    debugMonitorEnter(commandQueueLock);    while (command == NULL) {        while (holdEvents || (queue->head == NULL && !shutdownEvents)) {            debugMonitorWait(commandQueueLock);        }        if (shutdownEvents) {          break;        }        JDI_ASSERT(queue->head);        command = queue->head;        queue->head = command->next;        if (queue->tail == command) {            queue->tail = NULL;        }            log_debugee_location("dequeueCommand(): command being dequeued", NULL, NULL, 0);                size = commandSize(command);        /*         * Immediately close out any commands enqueued from a          * previously attached debugger.          */        if (command->sessionID != currentSessionID) {            log_debugee_location("dequeueCommand(): command session removal", NULL, NULL, 0);            completeCommand(command);            command = NULL;        }        /*         * There's room in the queue for more.         */        currentQueueSize -= size;        debugMonitorNotifyAll(commandQueueLock);    }    debugMonitorExit(commandQueueLock);    return command;}void eventHelper_holdEvents(void){    debugMonitorEnter(commandQueueLock);    holdEvents = JNI_TRUE;    debugMonitorNotifyAll(commandQueueLock);    debugMonitorExit(commandQueueLock);}void eventHelper_releaseEvents(void){    debugMonitorEnter(commandQueueLock);    holdEvents = JNI_FALSE;    debugMonitorNotifyAll(commandQueueLock);    debugMonitorExit(commandQueueLock);}static void writeSingleStepEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo){    (void)outStream_writeObjectRef(env, out, evinfo->thread);    writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);}static void writeBreakpointEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo){    (void)outStream_writeObjectRef(env, out, evinfo->thread);    writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);}static void writeFieldAccessEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo){    jbyte fieldClassTag;    fieldClassTag = referenceTypeTag(evinfo->u.field_access.field_clazz);    (void)outStream_writeObjectRef(env, out, evinfo->thread);    writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);    (void)outStream_writeByte(out, fieldClassTag);    (void)outStream_writeObjectRef(env, out, evinfo->u.field_access.field_clazz);    (void)outStream_writeFieldID(out, evinfo->u.field_access.field);    (void)outStream_writeObjectTag(env, out, evinfo->object);    (void)outStream_writeObjectRef(env, out, evinfo->object);}static void writeFieldModificationEvent(JNIEnv *env, PacketOutputStream *out,                             EventInfo *evinfo){    jbyte fieldClassTag;    fieldClassTag = referenceTypeTag(evinfo->u.field_modification.field_clazz);    (void)outStream_writeObjectRef(env, out, evinfo->thread);    writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);    (void)outStream_writeByte(out, fieldClassTag);    (void)outStream_writeObjectRef(env, out, evinfo->u.field_modification.field_clazz);    (void)outStream_writeFieldID(out, evinfo->u.field_modification.field);    (void)outStream_writeObjectTag(env, out, evinfo->object);    (void)outStream_writeObjectRef(env, out, evinfo->object);    (void)outStream_writeValue(env, out, (jbyte)evinfo->u.field_modification.signature_type,                          evinfo->u.field_modification.new_value);}static void writeExceptionEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo){    (void)outStream_writeObjectRef(env, out, evinfo->thread);    writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);    (void)outStream_writeObjectTag(env, out, evinfo->object);    (void)outStream_writeObjectRef(env, out, evinfo->object);    writeCodeLocation(out, evinfo->u.exception.catch_clazz,                       evinfo->u.exception.catch_method, evinfo->u.exception.catch_location);}static void writeThreadEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo){    (void)outStream_writeObjectRef(env, out, evinfo->thread);}static void writeMonitorEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo){    (void)outStream_writeObjectRef(env, out, evinfo->thread);    (void)outStream_writeObjectTag(env, out, evinfo->object);    (void)outStream_writeObjectRef(env, out, evinfo->object);    writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);    if (evinfo->ei == EI_MONITOR_WAIT) {        (void)outStream_writeLong(out, evinfo->u.monitor.timeout);    } else  if (evinfo->ei == EI_MONITOR_WAITED) {        (void)outStream_writeBoolean(out, evinfo->u.monitor.timed_out);    }}static void writeClassEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo){    jbyte classTag;    jint status;    char *signature = NULL;    jvmtiError error;    classTag = referenceTypeTag(evinfo->clazz);    error = classSignature(evinfo->clazz, &signature, NULL);    if (error != JVMTI_ERROR_NONE) {        EXIT_ERROR(error,"signature");    }    status = classStatus(evinfo->clazz);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?