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 + -
显示快捷键?