History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/tools/jdi/EventSetImpl.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/tools/jdi/EventSetImpl.java+874−0
@@ -0,0 +1,874 @@
1+/*
2+ * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package com.sun.tools.jdi;
27+
28+import com.sun.jdi.*;
29+import com.sun.jdi.event.*;
30+import com.sun.jdi.request.*;
31+
32+import java.util.*;
33+enum EventDestination {UNKNOWN_EVENT, INTERNAL_EVENT, CLIENT_EVENT};
34+
35+/*
36+ * An EventSet is normally created by the transport reader thread when
37+ * it reads a JDWP Composite command. The constructor doesn't unpack
38+ * the events contained in the Composite command and create EventImpls
39+ * for them because that process might involve calling back into the back-end
40+ * which should not be done by the transport reader thread. Instead,
41+ * the raw bytes of the packet are read and stored in the EventSet.
42+ * The EventSet is then added to each EventQueue. When an EventSet is
43+ * removed from an EventQueue, the EventSetImpl.build() method is called.
44+ * This method reads the packet bytes and creates the actual EventImpl objects.
45+ * build() also filters out events for our internal handler and puts them in
46+ * their own EventSet. This means that the EventImpls that are in the EventSet
47+ * that is on the queues are all for client requests.
48+ */
49+public class EventSetImpl extends ArrayList<Event> implements EventSet {
50+
51+ private VirtualMachineImpl vm; // we implement Mirror
52+ private Packet pkt;
53+ private byte suspendPolicy;
54+ private EventSetImpl internalEventSet;
55+
56+ public String toString() {
57+ String string = "event set, policy:" + suspendPolicy +
58+ ", count:" + this.size() + " = {";
59+ boolean first = true;
60+ for (Event event : this) {
61+ if (!first) {
62+ string += ", ";
63+ }
64+ string += event.toString();
65+ first = false;
66+ }
67+ string += "}";
68+ return string;
69+ }
70+
71+ abstract class EventImpl extends MirrorImpl implements Event {
72+
73+ private final byte eventCmd;
74+ private final int requestID;
75+ // This is set only for client requests, not internal requests.
76+ private final EventRequest request;
77+
78+ /**
79+ * Constructor for events.
80+ */
81+ protected EventImpl(JDWP.Event.Composite.Events.EventsCommon evt,
82+ int requestID) {
83+ super(EventSetImpl.this.vm);
84+ this.eventCmd = evt.eventKind();
85+ this.requestID = requestID;
86+ EventRequestManagerImpl ermi = EventSetImpl.this.
87+ vm.eventRequestManagerImpl();
88+ this.request = ermi.request(eventCmd, requestID);
89+ }
90+
91+ /*
92+ * Override superclass back to default equality
93+ */
94+ public boolean equals(Object obj) {
95+ return this == obj;
96+ }
97+
98+ public int hashCode() {
99+ return System.identityHashCode(this);
100+ }
101+
102+ /**
103+ * Constructor for VM disconnected events.
104+ */
105+ protected EventImpl(byte eventCmd) {
106+ super(EventSetImpl.this.vm);
107+ this.eventCmd = eventCmd;
108+ this.requestID = 0;
109+ this.request = null;
110+ }
111+
112+ public EventRequest request() {
113+ return request;
114+ }
115+
116+ int requestID() {
117+ return requestID;
118+ }
119+
120+ EventDestination destination() {
121+ /*
122+ * We need to decide if this event is for
123+ * 1. an internal request
124+ * 2. a client request that is no longer available, ie
125+ * it has been deleted, or disabled and re-enabled
126+ * which gives it a new ID.
127+ * 3. a current client request that is disabled
128+ * 4. a current enabled client request.
129+ *
130+ * We will filter this set into a set
131+ * that contains only 1s for our internal queue
132+ * and a set that contains only 4s for our client queue.
133+ * If we get an EventSet that contains only 2 and 3
134+ * then we have to resume it if it is not SUSPEND_NONE
135+ * because no one else will.
136+ */
137+ if (requestID == 0) {
138+ /* An unsolicited event. These have traditionally
139+ * been treated as client events.
140+ */
141+ return EventDestination.CLIENT_EVENT;
142+ }
143+
144+ // Is this an event for a current client request?
145+ if (request == null) {
146+ // Nope. Is it an event for an internal request?
147+ EventRequestManagerImpl ermi = this.vm.getInternalEventRequestManager();
148+ if (ermi.request(eventCmd, requestID) != null) {
149+ // Yep
150+ return EventDestination.INTERNAL_EVENT;
151+ }
152+ return EventDestination.UNKNOWN_EVENT;
153+ }
154+
155+ // We found a client request
156+ if (request.isEnabled()) {
157+ return EventDestination.CLIENT_EVENT;
158+ }
159+ return EventDestination.UNKNOWN_EVENT;
160+ }
161+
162+ abstract String eventName();
163+
164+ public String toString() {
165+ return eventName();
166+ }
167+
168+ }
169+
170+ abstract class ThreadedEventImpl extends EventImpl {
171+ private ThreadReference thread;
172+
173+ ThreadedEventImpl(JDWP.Event.Composite.Events.EventsCommon evt,
174+ int requestID, ThreadReference thread) {
175+ super(evt, requestID);
176+ this.thread = thread;
177+ }
178+
179+ public ThreadReference thread() {
180+ return thread;
181+ }
182+
183+ public String toString() {
184+ return eventName() + " in thread " + thread.name();
185+ }
186+ }
187+
188+ abstract class LocatableEventImpl extends ThreadedEventImpl
189+ implements Locatable {
190+ private Location location;
191+
192+ LocatableEventImpl(JDWP.Event.Composite.Events.EventsCommon evt,
193+ int requestID,
194+ ThreadReference thread, Location location) {
195+ super(evt, requestID, thread);
196+ this.location = location;
197+ }
198+
199+ public Location location() {
200+ return location;
201+ }
202+
203+ /**
204+ * For MethodEntry and MethodExit
205+ */
206+ public Method method() {
207+ return location.method();
208+ }
209+
210+ public String toString() {
211+ return eventName() + "@" +
212+ ((location() == null) ? " null" : location().toString()) +
213+ " in thread " + thread().name();
214+ }
215+ }
216+
217+ class BreakpointEventImpl extends LocatableEventImpl
218+ implements BreakpointEvent {
219+ BreakpointEventImpl(JDWP.Event.Composite.Events.Breakpoint evt) {
220+ super(evt, evt.requestID, evt.thread, evt.location);
221+ }
222+
223+ String eventName() {
224+ return "BreakpointEvent";
225+ }
226+ }
227+
228+ class StepEventImpl extends LocatableEventImpl implements StepEvent {
229+ StepEventImpl(JDWP.Event.Composite.Events.SingleStep evt) {
230+ super(evt, evt.requestID, evt.thread, evt.location);
231+ }
232+
233+ String eventName() {
234+ return "StepEvent";
235+ }
236+ }
237+
238+ class MethodEntryEventImpl extends LocatableEventImpl
239+ implements MethodEntryEvent {
240+ MethodEntryEventImpl(JDWP.Event.Composite.Events.MethodEntry evt) {
241+ super(evt, evt.requestID, evt.thread, evt.location);
242+ }
243+
244+ String eventName() {
245+ return "MethodEntryEvent";
246+ }
247+ }
248+
249+ class MethodExitEventImpl extends LocatableEventImpl
250+ implements MethodExitEvent {
251+ private Value returnVal = null;
252+
253+ MethodExitEventImpl(JDWP.Event.Composite.Events.MethodExit evt) {
254+ super(evt, evt.requestID, evt.thread, evt.location);
255+ }
256+
257+ MethodExitEventImpl(JDWP.Event.Composite.Events.MethodExitWithReturnValue evt) {
258+ super(evt, evt.requestID, evt.thread, evt.location);
259+ returnVal = evt.value;
260+ }
261+
262+ String eventName() {
263+ return "MethodExitEvent";
264+ }
265+
266+ public Value returnValue() {
267+ if (!this.vm.canGetMethodReturnValues()) {
268+ throw new UnsupportedOperationException(
269+ "target does not support return values in MethodExit events");
270+ }
271+ return returnVal;
272+ }
273+
274+ }
275+
276+ class MonitorContendedEnterEventImpl extends LocatableEventImpl
277+ implements MonitorContendedEnterEvent {
278+ private ObjectReference monitor = null;
279+
280+ MonitorContendedEnterEventImpl(JDWP.Event.Composite.Events.MonitorContendedEnter evt) {
281+ super(evt, evt.requestID, evt.thread, evt.location);
282+ this.monitor = evt.object;
283+ }
284+
285+ String eventName() {
286+ return "MonitorContendedEnter";
287+ }
288+
289+ public ObjectReference monitor() {
290+ return monitor;
291+ };
292+
293+ }
294+
295+ class MonitorContendedEnteredEventImpl extends LocatableEventImpl
296+ implements MonitorContendedEnteredEvent {
297+ private ObjectReference monitor = null;
298+
299+ MonitorContendedEnteredEventImpl(JDWP.Event.Composite.Events.MonitorContendedEntered evt) {
300+ super(evt, evt.requestID, evt.thread, evt.location);
301+ this.monitor = evt.object;
302+ }
303+
304+ String eventName() {
305+ return "MonitorContendedEntered";
306+ }
307+
308+ public ObjectReference monitor() {
309+ return monitor;
310+ };
311+
312+ }
313+
314+ class MonitorWaitEventImpl extends LocatableEventImpl
315+ implements MonitorWaitEvent {
316+ private ObjectReference monitor = null;
317+ private long timeout;
318+
319+ MonitorWaitEventImpl(JDWP.Event.Composite.Events.MonitorWait evt) {
320+ super(evt, evt.requestID, evt.thread, evt.location);
321+ this.monitor = evt.object;
322+ this.timeout = evt.timeout;
323+ }
324+
325+ String eventName() {
326+ return "MonitorWait";
327+ }
328+
329+ public ObjectReference monitor() {
330+ return monitor;
331+ };
332+
333+ public long timeout() {
334+ return timeout;
335+ }
336+ }
337+
338+ class MonitorWaitedEventImpl extends LocatableEventImpl
339+ implements MonitorWaitedEvent {
340+ private ObjectReference monitor = null;
341+ private boolean timed_out;
342+
343+ MonitorWaitedEventImpl(JDWP.Event.Composite.Events.MonitorWaited evt) {
344+ super(evt, evt.requestID, evt.thread, evt.location);
345+ this.monitor = evt.object;
346+ this.timed_out = evt.timed_out;
347+ }
348+
349+ String eventName() {
350+ return "MonitorWaited";
351+ }
352+
353+ public ObjectReference monitor() {
354+ return monitor;
355+ };
356+
357+ public boolean timedout() {
358+ return timed_out;
359+ }
360+ }
361+
362+ class ClassPrepareEventImpl extends ThreadedEventImpl
363+ implements ClassPrepareEvent {
364+ private ReferenceType referenceType;
365+
366+ ClassPrepareEventImpl(JDWP.Event.Composite.Events.ClassPrepare evt) {
367+ super(evt, evt.requestID, evt.thread);
368+ referenceType = this.vm.referenceType(evt.typeID, evt.refTypeTag,
369+ evt.signature);
370+ ((ReferenceTypeImpl)referenceType).setStatus(evt.status);
371+ }
372+
373+ public ReferenceType referenceType() {
374+ return referenceType;
375+ }
376+
377+ String eventName() {
378+ return "ClassPrepareEvent";
379+ }
380+ }
381+
382+ class ClassUnloadEventImpl extends EventImpl implements ClassUnloadEvent {
383+ private String classSignature;
384+
385+ ClassUnloadEventImpl(JDWP.Event.Composite.Events.ClassUnload evt) {
386+ super(evt, evt.requestID);
387+ this.classSignature = evt.signature;
388+ }
389+
390+ public String className() {
391+ return classSignature.substring(1, classSignature.length()-1)
392+ .replace('/', '.');
393+ }
394+
395+ public String classSignature() {
396+ return classSignature;
397+ }
398+
399+ String eventName() {
400+ return "ClassUnloadEvent";
401+ }
402+ }
403+
404+ class ExceptionEventImpl extends LocatableEventImpl
405+ implements ExceptionEvent {
406+ private ObjectReference exception;
407+ private Location catchLocation;
408+
409+ ExceptionEventImpl(JDWP.Event.Composite.Events.Exception evt) {
410+ super(evt, evt.requestID, evt.thread, evt.location);
411+ this.exception = evt.exception;
412+ this.catchLocation = evt.catchLocation;
413+ }
414+
415+ public ObjectReference exception() {
416+ return exception;
417+ }
418+
419+ public Location catchLocation() {
420+ return catchLocation;
421+ }
422+
423+ String eventName() {
424+ return "ExceptionEvent";
425+ }
426+ }
427+
428+ class ThreadDeathEventImpl extends ThreadedEventImpl
429+ implements ThreadDeathEvent {
430+ ThreadDeathEventImpl(JDWP.Event.Composite.Events.ThreadDeath evt) {
431+ super(evt, evt.requestID, evt.thread);
432+ }
433+
434+ String eventName() {
435+ return "ThreadDeathEvent";
436+ }
437+ }
438+
439+ class ThreadStartEventImpl extends ThreadedEventImpl
440+ implements ThreadStartEvent {
441+ ThreadStartEventImpl(JDWP.Event.Composite.Events.ThreadStart evt) {
442+ super(evt, evt.requestID, evt.thread);
443+ }
444+
445+ String eventName() {
446+ return "ThreadStartEvent";
447+ }
448+ }
449+
450+ class VMStartEventImpl extends ThreadedEventImpl
451+ implements VMStartEvent {
452+ VMStartEventImpl(JDWP.Event.Composite.Events.VMStart evt) {
453+ super(evt, evt.requestID, evt.thread);
454+ }
455+
456+ String eventName() {
457+ return "VMStartEvent";
458+ }
459+ }
460+
461+ class VMDeathEventImpl extends EventImpl implements VMDeathEvent {
462+
463+ VMDeathEventImpl(JDWP.Event.Composite.Events.VMDeath evt) {
464+ super(evt, evt.requestID);
465+ }
466+
467+ String eventName() {
468+ return "VMDeathEvent";
469+ }
470+ }
471+
472+ class VMDisconnectEventImpl extends EventImpl
473+ implements VMDisconnectEvent {
474+
475+ VMDisconnectEventImpl() {
476+ super((byte)JDWP.EventKind.VM_DISCONNECTED);
477+ }
478+
479+ String eventName() {
480+ return "VMDisconnectEvent";
481+ }
482+ }
483+
484+ abstract class WatchpointEventImpl extends LocatableEventImpl
485+ implements WatchpointEvent {
486+ private final ReferenceTypeImpl refType;
487+ private final long fieldID;
488+ private final ObjectReference object;
489+ private Field field = null;
490+
491+ WatchpointEventImpl(JDWP.Event.Composite.Events.EventsCommon evt,
492+ int requestID,
493+ ThreadReference thread, Location location,
494+ byte refTypeTag, long typeID, long fieldID,
495+ ObjectReference object) {
496+ super(evt, requestID, thread, location);
497+ this.refType = this.vm.referenceType(typeID, refTypeTag);
498+ this.fieldID = fieldID;
499+ this.object = object;
500+ }
501+
502+ public Field field() {
503+ if (field == null) {
504+ field = refType.getFieldMirror(fieldID);
505+ }
506+ return field;
507+ }
508+
509+ public ObjectReference object() {
510+ return object;
511+ }
512+
513+ public Value valueCurrent() {
514+ if (object == null) {
515+ return refType.getValue(field());
516+ } else {
517+ return object.getValue(field());
518+ }
519+ }
520+ }
521+
522+ class AccessWatchpointEventImpl extends WatchpointEventImpl
523+ implements AccessWatchpointEvent {
524+
525+ AccessWatchpointEventImpl(JDWP.Event.Composite.Events.FieldAccess evt) {
526+ super(evt, evt.requestID, evt.thread, evt.location,
527+ evt.refTypeTag, evt.typeID, evt.fieldID, evt.object);
528+ }
529+
530+ String eventName() {
531+ return "AccessWatchpoint";
532+ }
533+ }
534+
535+ class ModificationWatchpointEventImpl extends WatchpointEventImpl
536+ implements ModificationWatchpointEvent {
537+ Value newValue;
538+
539+ ModificationWatchpointEventImpl(
540+ JDWP.Event.Composite.Events.FieldModification evt) {
541+ super(evt, evt.requestID, evt.thread, evt.location,
542+ evt.refTypeTag, evt.typeID, evt.fieldID, evt.object);
543+ this.newValue = evt.valueToBe;
544+ }
545+
546+ public Value valueToBe() {
547+ return newValue;
548+ }
549+
550+ String eventName() {
551+ return "ModificationWatchpoint";
552+ }
553+ }
554+
555+ /**
556+ * Events are constructed on the thread which reads all data from the
557+ * transport. This means that the packet cannot be converted to real
558+ * JDI objects as that may involve further communications with the
559+ * back end which would deadlock.
560+ *
561+ * Hence the {@link #build()} method below called by EventQueue.
562+ */
563+ EventSetImpl(VirtualMachine aVm, Packet pkt) {
564+ super();
565+
566+ // From "MirrorImpl":
567+ // Yes, its a bit of a hack. But by doing it this
568+ // way, this is the only place we have to change
569+ // typing to substitute a new impl.
570+ vm = (VirtualMachineImpl)aVm;
571+
572+ this.pkt = pkt;
573+ }
574+
575+ /**
576+ * Constructor for special events like VM disconnected
577+ */
578+ EventSetImpl(VirtualMachine aVm, byte eventCmd) {
579+ this(aVm, null);
580+ suspendPolicy = JDWP.SuspendPolicy.NONE;
581+ switch (eventCmd) {
582+ case JDWP.EventKind.VM_DISCONNECTED:
583+ addEvent(new VMDisconnectEventImpl());
584+ break;
585+
586+ default:
587+ throw new InternalException("Bad singleton event code");
588+ }
589+ }
590+
591+ private void addEvent(EventImpl evt) {
592+ // Note that this class has a public add method that throws
593+ // an exception so that clients can't modify the EventSet
594+ super.add(evt);
595+ }
596+
597+ /*
598+ * Complete the construction of an EventSet. This is called from
599+ * an event handler thread. It upacks the JDWP events inside
600+ * the packet and creates EventImpls for them. The EventSet is already
601+ * on EventQueues when this is called, so it has to be synch.
602+ */
603+ synchronized void build() {
604+ if (pkt == null) {
605+ return;
606+ }
607+ PacketStream ps = new PacketStream(vm, pkt);
608+ JDWP.Event.Composite compEvt = new JDWP.Event.Composite(vm, ps);
609+ suspendPolicy = compEvt.suspendPolicy;
610+ if ((vm.traceFlags & vm.TRACE_EVENTS) != 0) {
611+ switch(suspendPolicy) {
612+ case JDWP.SuspendPolicy.ALL:
613+ vm.printTrace("EventSet: SUSPEND_ALL");
614+ break;
615+
616+ case JDWP.SuspendPolicy.EVENT_THREAD:
617+ vm.printTrace("EventSet: SUSPEND_EVENT_THREAD");
618+ break;
619+
620+ case JDWP.SuspendPolicy.NONE:
621+ vm.printTrace("EventSet: SUSPEND_NONE");
622+ break;
623+ }
624+ }
625+
626+ ThreadReference fix6485605 = null;
627+ for (int i = 0; i < compEvt.events.length; i++) {
628+ EventImpl evt = createEvent(compEvt.events[i]);
629+ if ((vm.traceFlags & vm.TRACE_EVENTS) != 0) {
630+ try {
631+ vm.printTrace("Event: " + evt);
632+ } catch (VMDisconnectedException ee) {
633+ // ignore - see bug 6502716
634+ }
635+ }
636+
637+ switch (evt.destination()) {
638+ case UNKNOWN_EVENT:
639+ // Ignore disabled, deleted, unknown events, but
640+ // save the thread if there is one since we might
641+ // have to resume it. Note that events for different
642+ // threads can't be in the same event set.
643+ if (evt instanceof ThreadedEventImpl &&
644+ suspendPolicy == JDWP.SuspendPolicy.EVENT_THREAD) {
645+ fix6485605 = ((ThreadedEventImpl)evt).thread();
646+ }
647+ continue;
648+ case CLIENT_EVENT:
649+ addEvent(evt);
650+ break;
651+ case INTERNAL_EVENT:
652+ if (internalEventSet == null) {
653+ internalEventSet = new EventSetImpl(this.vm, null);
654+ }
655+ internalEventSet.addEvent(evt);
656+ break;
657+ default:
658+ throw new InternalException("Invalid event destination");
659+ }
660+ }
661+ pkt = null; // No longer needed - free it up
662+
663+ // Avoid hangs described in 6296125, 6293795
664+ if (super.size() == 0) {
665+ // This set has no client events. If we don't do
666+ // needed resumes, no one else is going to.
667+ if (suspendPolicy == JDWP.SuspendPolicy.ALL) {
668+ vm.resume();
669+ } else if (suspendPolicy == JDWP.SuspendPolicy.EVENT_THREAD) {
670+ // See bug 6485605.
671+ if (fix6485605 != null) {
672+ fix6485605.resume();
673+ } else {
674+ // apparently, there is nothing to resume.
675+ }
676+ }
677+ suspendPolicy = JDWP.SuspendPolicy.NONE;
678+
679+ }
680+
681+ }
682+
683+ /**
684+ * Filter out internal events
685+ */
686+ EventSet userFilter() {
687+ return this;
688+ }
689+
690+ /**
691+ * Filter out user events.
692+ */
693+ EventSet internalFilter() {
694+ return this.internalEventSet;
695+ }
696+
697+ EventImpl createEvent(JDWP.Event.Composite.Events evt) {
698+ JDWP.Event.Composite.Events.EventsCommon comm = evt.aEventsCommon;
699+ switch (evt.eventKind) {
700+ case JDWP.EventKind.THREAD_START:
701+ return new ThreadStartEventImpl(
702+ (JDWP.Event.Composite.Events.ThreadStart)comm);
703+
704+ case JDWP.EventKind.THREAD_END:
705+ return new ThreadDeathEventImpl(
706+ (JDWP.Event.Composite.Events.ThreadDeath)comm);
707+
708+ case JDWP.EventKind.EXCEPTION:
709+ return new ExceptionEventImpl(
710+ (JDWP.Event.Composite.Events.Exception)comm);
711+
712+ case JDWP.EventKind.BREAKPOINT:
713+ return new BreakpointEventImpl(
714+ (JDWP.Event.Composite.Events.Breakpoint)comm);
715+
716+ case JDWP.EventKind.METHOD_ENTRY:
717+ return new MethodEntryEventImpl(
718+ (JDWP.Event.Composite.Events.MethodEntry)comm);
719+
720+ case JDWP.EventKind.METHOD_EXIT:
721+ return new MethodExitEventImpl(
722+ (JDWP.Event.Composite.Events.MethodExit)comm);
723+
724+ case JDWP.EventKind.METHOD_EXIT_WITH_RETURN_VALUE:
725+ return new MethodExitEventImpl(
726+ (JDWP.Event.Composite.Events.MethodExitWithReturnValue)comm);
727+
728+ case JDWP.EventKind.FIELD_ACCESS:
729+ return new AccessWatchpointEventImpl(
730+ (JDWP.Event.Composite.Events.FieldAccess)comm);
731+
732+ case JDWP.EventKind.FIELD_MODIFICATION:
733+ return new ModificationWatchpointEventImpl(
734+ (JDWP.Event.Composite.Events.FieldModification)comm);
735+
736+ case JDWP.EventKind.SINGLE_STEP:
737+ return new StepEventImpl(
738+ (JDWP.Event.Composite.Events.SingleStep)comm);
739+
740+ case JDWP.EventKind.CLASS_PREPARE:
741+ return new ClassPrepareEventImpl(
742+ (JDWP.Event.Composite.Events.ClassPrepare)comm);
743+
744+ case JDWP.EventKind.CLASS_UNLOAD:
745+ return new ClassUnloadEventImpl(
746+ (JDWP.Event.Composite.Events.ClassUnload)comm);
747+
748+ case JDWP.EventKind.MONITOR_CONTENDED_ENTER:
749+ return new MonitorContendedEnterEventImpl(
750+ (JDWP.Event.Composite.Events.MonitorContendedEnter)comm);
751+
752+ case JDWP.EventKind.MONITOR_CONTENDED_ENTERED:
753+ return new MonitorContendedEnteredEventImpl(
754+ (JDWP.Event.Composite.Events.MonitorContendedEntered)comm);
755+
756+ case JDWP.EventKind.MONITOR_WAIT:
757+ return new MonitorWaitEventImpl(
758+ (JDWP.Event.Composite.Events.MonitorWait)comm);
759+
760+ case JDWP.EventKind.MONITOR_WAITED:
761+ return new MonitorWaitedEventImpl(
762+ (JDWP.Event.Composite.Events.MonitorWaited)comm);
763+
764+ case JDWP.EventKind.VM_START:
765+ return new VMStartEventImpl(
766+ (JDWP.Event.Composite.Events.VMStart)comm);
767+
768+ case JDWP.EventKind.VM_DEATH:
769+ return new VMDeathEventImpl(
770+ (JDWP.Event.Composite.Events.VMDeath)comm);
771+
772+ default:
773+ // Ignore unknown event types
774+ System.err.println("Ignoring event cmd " +
775+ evt.eventKind + " from the VM");
776+ return null;
777+ }
778+ }
779+
780+ public VirtualMachine virtualMachine() {
781+ return vm;
782+ }
783+
784+ public int suspendPolicy() {
785+ return EventRequestManagerImpl.JDWPtoJDISuspendPolicy(suspendPolicy);
786+ }
787+
788+ private ThreadReference eventThread() {
789+ for (Event event : this) {
790+ if (event instanceof ThreadedEventImpl) {
791+ return ((ThreadedEventImpl)event).thread();
792+ }
793+ }
794+ return null;
795+ }
796+
797+ public void resume() {
798+ switch (suspendPolicy()) {
799+ case EventRequest.SUSPEND_ALL:
800+ vm.resume();
801+ break;
802+ case EventRequest.SUSPEND_EVENT_THREAD:
803+ ThreadReference thread = eventThread();
804+ if (thread == null) {
805+ throw new InternalException("Inconsistent suspend policy");
806+ }
807+ thread.resume();
808+ break;
809+ case EventRequest.SUSPEND_NONE:
810+ // Do nothing
811+ break;
812+ default:
813+ throw new InternalException("Invalid suspend policy");
814+ }
815+ }
816+
817+ public Iterator<Event> iterator() {
818+ return new Itr();
819+ }
820+
821+ public EventIterator eventIterator() {
822+ return new Itr();
823+ }
824+
825+ public class Itr implements EventIterator {
826+ /**
827+ * Index of element to be returned by subsequent call to next.
828+ */
829+ int cursor = 0;
830+
831+ public boolean hasNext() {
832+ return cursor != size();
833+ }
834+
835+ public Event next() {
836+ try {
837+ Event nxt = get(cursor);
838+ ++cursor;
839+ return nxt;
840+ } catch(IndexOutOfBoundsException e) {
841+ throw new NoSuchElementException();
842+ }
843+ }
844+
845+ public Event nextEvent() {
846+ return next();
847+ }
848+
849+ public void remove() {
850+ throw new UnsupportedOperationException();
851+ }
852+ }
853+
854+ /* below make this unmodifiable */
855+
856+ public boolean add(Event o){
857+ throw new UnsupportedOperationException();
858+ }
859+ public boolean remove(Object o) {
860+ throw new UnsupportedOperationException();
861+ }
862+ public boolean addAll(Collection<? extends Event> coll) {
863+ throw new UnsupportedOperationException();
864+ }
865+ public boolean removeAll(Collection<?> coll) {
866+ throw new UnsupportedOperationException();
867+ }
868+ public boolean retainAll(Collection<?> coll) {
869+ throw new UnsupportedOperationException();
870+ }
871+ public void clear() {
872+ throw new UnsupportedOperationException();
873+ }
874+}