/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 in the LICENSE file that
* accompanied this code).
*
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.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
*/
/*
* Event helper thread command singleKinds
*/
typedef struct EventCommandSingle {
typedef struct UnloadCommandSingle {
char *classSignature;
typedef struct FrameEventCommandSingle {
/* If typeKey is 0, then no return value is needed */
typedef struct CommandSingle {
union {
} u;
typedef struct ReportInvokeDoneCommand {
typedef struct ReportVMInitCommand {
typedef struct SuspendThreadCommand {
typedef struct ReportEventCompositeCommand {
typedef struct HelperCommand {
union {
/* NOTE: Each of the structs below must have the same first field */
} u;
/* composite array expand out, put nothing after */
typedef struct {
} CommandQueue;
static jint
{
/*
* One event is accounted for in the Helper Command. If there are
* more, add to size here.
*/
/*LINTED*/
size += ((int)sizeof(CommandSingle) *
}
return size;
}
static void
{
return;
}
static void
{
}
if (vmDeathReported) {
/* send no more events after VMDeath and don't wait */
} else {
currentQueueSize += size;
} else {
}
if (reportingVMDeath) {
}
}
if (wait) {
}
}
}
static void
{
} else {
}
}
static HelperCommand *
dequeueCommand(void)
{
}
}
/*
* Immediately close out any commands enqueued from a
* previously attached debugger.
*/
}
/*
* There's room in the queue for more.
*/
currentQueueSize -= size;
}
return command;
}
void eventHelper_holdEvents(void)
{
}
void eventHelper_releaseEvents(void)
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
/* clazz of evinfo was set to class of monitor object for monitor wait event class filtering.
* So get the method class to write location info.
* See cbMonitorWait() and cbMonitorWaited() function in eventHandler.c.
*/
}
/* This runs in a command loop and this thread may not return to java.
* So we need to delete the local ref created by jvmti GetMethodDeclaringClass.
*/
} else {
}
}
static void
{
if (error != JVMTI_ERROR_NONE) {
}
}
static void
{
}
static void
{
case EI_SINGLE_STEP:
break;
case EI_BREAKPOINT:
break;
case EI_FIELD_ACCESS:
break;
case EI_FIELD_MODIFICATION:
break;
case EI_EXCEPTION:
break;
case EI_THREAD_START:
case EI_THREAD_END:
break;
case EI_CLASS_LOAD:
case EI_CLASS_PREPARE:
break;
case EI_MONITOR_WAIT:
case EI_MONITOR_WAITED:
break;
case EI_VM_DEATH:
break;
default:
break;
}
}
static void
{
}
static void
{
} else {
}
}
}
}
static void
{
(void)threadControl_suspendAll();
} else {
}
}
static void
{
jint i;
/* must determine thread to interrupt before writing */
/* since writing destroys it */
for (i = 0; i < count; i++) {
switch (single->singleKind) {
case COMMAND_SINGLE_EVENT:
break;
break;
}
break;
}
}
(void)threadControl_suspendAll();
} else {
}
}
for (i = 0; i < count; i++) {
switch (single->singleKind) {
case COMMAND_SINGLE_EVENT:
&single->u.eventCommand);
break;
case COMMAND_SINGLE_UNLOAD:
&single->u.unloadCommand);
break;
&single->u.frameEventCommand);
break;
}
}
}
static void
{
}
static void
{
(void)threadControl_suspendAll();
}
/* Why aren't we tossing this: tossGlobalRef(env, &(command->thread)); */
}
static void
{
/*
* For the moment, there's nothing that can be done with the
* return code, so we don't check it here.
*/
}
static void
{
switch (command->commandKind) {
&command->u.reportEventComposite);
break;
break;
case COMMAND_REPORT_VM_INIT:
break;
case COMMAND_SUSPEND_THREAD:
break;
default:
break;
}
}
/*
* There was an assumption that only one event with a suspend-all
* policy could be processed by commandLoop() at one time. It was
* assumed that native thread suspension from the first suspend-all
* event would prevent the second suspend-all event from making it
* into the command queue. For the Classic VM, this was a reasonable
* assumption. However, in HotSpot all thread suspension requires a
* VM operation and VM operations take time.
*
* The solution is to add a mechanism to prevent commandLoop() from
* processing more than one event with a suspend-all policy. This is
* accomplished by forcing commandLoop() to wait for either
* ThreadReferenceImpl.c: resume() or VirtualMachineImpl.c: resume()
* when an event with a suspend-all policy has been completed.
*/
/*
* We wait for either ThreadReferenceImpl.c: resume() or
* VirtualMachineImpl.c: resume() to be called.
*/
static void
doBlockCommandLoop(void) {
while (blockCommandLoop == JNI_TRUE) {
}
}
/*
* If the command that we are about to execute has a suspend-all
* policy, then prepare for either ThreadReferenceImpl.c: resume()
* or VirtualMachineImpl.c: resume() to be called.
*/
static jboolean
return JNI_TRUE;
}
return JNI_FALSE;
}
/*
* Used by either ThreadReferenceImpl.c: resume() or
* VirtualMachineImpl.c: resume() to resume commandLoop().
*/
void
unblockCommandLoop(void) {
}
/*
* The event helper thread. Dequeues commands and processes them.
*/
static void JNICALL
{
LOG_MISC(("Begin command loop thread"));
while (JNI_TRUE) {
/*
* Setup for a potential doBlockCommand() call before calling
* handleCommand() to prevent any races.
*/
/* if we just finished a suspend-all cmd, then we block here */
if (doBlock) {
}
}
}
/* This loop never ends, even as connections come and go with server=y */
}
void
{
/* Start the event handler thread */
func = &commandLoop;
}
void
{
}
/*
* Provide a means for threadControl to ensure that crucial locks are not
* held by suspended threads.
*/
void
eventHelper_lock(void)
{
}
void
eventHelper_unlock(void)
{
}
/* Change all references to global in the EventInfo struct */
static void
{
char sig;
}
}
}
case EI_FIELD_MODIFICATION:
}
}
}
break;
case EI_FIELD_ACCESS:
}
break;
case EI_EXCEPTION:
}
break;
default:
break;
}
}
}
static void
{
char sig;
}
}
}
case EI_FIELD_MODIFICATION:
}
}
}
break;
case EI_FIELD_ACCESS:
}
break;
case EI_EXCEPTION:
}
break;
default:
break;
}
}
struct bag *
{
}
/* Return the combined suspend policy for the event set
*/
static jboolean
{
switch(command->singleKind) {
case COMMAND_SINGLE_EVENT:
break;
break;
default:
}
/* Expand running policy value if this policy demands it */
*policy = thisPolicy;
thisPolicy : *policy;
}
/* Short circuit if we reached maximal suspend policy */
return JNI_FALSE;
} else {
return JNI_TRUE;
}
}
/* Determine whether we are reporting VM death
*/
static jboolean
{
return JNI_FALSE;
}
}
return JNI_TRUE;
}
struct singleTracker {
int index;
};
static jboolean
{
sizeof(CommandSingle));
return JNI_TRUE;
}
{
int command_size;
if (size == 0) {
return suspendPolicy;
}
/*LINTED*/
command_size = (int)(sizeof(HelperCommand) +
/*
* We must wait if this thread (the event thread) is to be
* suspended or if the VM is about to die. (Waiting in the latter
* case ensures that we get the event out before the process dies.)
*/
return suspendPolicy;
}
void
{
}
/*
* Copy the event into the command so that it can be used
* asynchronously by the event helper thread.
*/
}
void
{
}
}
void
int needReturnValue,
{
}
if (needReturnValue) {
/*
* V or B C D F I J S Z L <classname> ; [ ComponentType
*/
returnValue.l != NULL) {
} else {
}
} else {
/* This is not a JDWP METHOD_EXIT_WITH_RETURN_VALUE request,
* so signal this by setting typeKey = 0 which is not
* a legal typekey.
*/
frameCommand->typeKey = 0;
}
}
void
{
}
}
/*
* This, currently, cannot go through the normal event handling code
* because the JVMTI event does not contain a thread.
*/
void
{
}
}
void
{
}
}