blob: 6e89799e1ca213b6f3a0c7f290e73fcf95dddce4 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-2005 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.tools.jdi;
27
28import com.sun.jdi.*;
29import com.sun.jdi.request.*;
30import com.sun.tools.jdi.JDWP;
31
32import java.util.*;
33
34/**
35 * This interface is used to create and remove Breakpoints, Watchpoints,
36 * etc.
37 * It include implementations of all the request interfaces..
38 */
39// Warnings from List filters and List[] requestLists is hard to fix.
40// Remove SuppressWarning when we fix the warnings from List filters
41// and List[] requestLists. The generic array is not supported.
42@SuppressWarnings("unchecked")
43class EventRequestManagerImpl extends MirrorImpl
44 implements EventRequestManager
45{
46 List[] requestLists;
47 private static int methodExitEventCmd = 0;
48
49 static int JDWPtoJDISuspendPolicy(byte jdwpPolicy) {
50 switch(jdwpPolicy) {
51 case JDWP.SuspendPolicy.ALL:
52 return EventRequest.SUSPEND_ALL;
53 case JDWP.SuspendPolicy.EVENT_THREAD:
54 return EventRequest.SUSPEND_EVENT_THREAD;
55 case JDWP.SuspendPolicy.NONE:
56 return EventRequest.SUSPEND_NONE;
57 default:
58 throw new IllegalArgumentException("Illegal policy constant: " + jdwpPolicy);
59 }
60 }
61
62 static byte JDItoJDWPSuspendPolicy(int jdiPolicy) {
63 switch(jdiPolicy) {
64 case EventRequest.SUSPEND_ALL:
65 return JDWP.SuspendPolicy.ALL;
66 case EventRequest.SUSPEND_EVENT_THREAD:
67 return JDWP.SuspendPolicy.EVENT_THREAD;
68 case EventRequest.SUSPEND_NONE:
69 return JDWP.SuspendPolicy.NONE;
70 default:
71 throw new IllegalArgumentException("Illegal policy constant: " + jdiPolicy);
72 }
73 }
74
75 /*
76 * Override superclass back to default equality
77 */
78 public boolean equals(Object obj) {
79 return this == obj;
80 }
81
82 public int hashCode() {
83 return System.identityHashCode(this);
84 }
85
86 abstract class EventRequestImpl extends MirrorImpl implements EventRequest {
87 int id;
88
89 /*
90 * This list is not protected by a synchronized wrapper. All
91 * access/modification should be protected by synchronizing on
92 * the enclosing instance of EventRequestImpl.
93 */
94 List filters = new ArrayList();
95
96 boolean isEnabled = false;
97 boolean deleted = false;
98 byte suspendPolicy = JDWP.SuspendPolicy.ALL;
99 private Map<Object, Object> clientProperties = null;
100
101 EventRequestImpl() {
102 super(EventRequestManagerImpl.this.vm);
103 }
104
105
106 /*
107 * Override superclass back to default equality
108 */
109 public boolean equals(Object obj) {
110 return this == obj;
111 }
112
113 public int hashCode() {
114 return System.identityHashCode(this);
115 }
116
117 abstract int eventCmd();
118
119 InvalidRequestStateException invalidState() {
120 return new InvalidRequestStateException(toString());
121 }
122
123 String state() {
124 return deleted? " (deleted)" :
125 (isEnabled()? " (enabled)" : " (disabled)");
126 }
127
128 /**
129 * @return all the event request of this kind
130 */
131 List requestList() {
132 return EventRequestManagerImpl.this.requestList(eventCmd());
133 }
134
135 /**
136 * delete the event request
137 */
138 void delete() {
139 if (!deleted) {
140 requestList().remove(this);
141 disable(); /* must do BEFORE delete */
142 deleted = true;
143 }
144 }
145
146 public boolean isEnabled() {
147 return isEnabled;
148 }
149
150 public void enable() {
151 setEnabled(true);
152 }
153
154 public void disable() {
155 setEnabled(false);
156 }
157
158 public synchronized void setEnabled(boolean val) {
159 if (deleted) {
160 throw invalidState();
161 } else {
162 if (val != isEnabled) {
163 if (isEnabled) {
164 clear();
165 } else {
166 set();
167 }
168 }
169 }
170 }
171
172 public synchronized void addCountFilter(int count) {
173 if (isEnabled() || deleted) {
174 throw invalidState();
175 }
176 if (count < 1) {
177 throw new IllegalArgumentException("count is less than one");
178 }
179 filters.add(JDWP.EventRequest.Set.Modifier.Count.create(count));
180 }
181
182 public void setSuspendPolicy(int policy) {
183 if (isEnabled() || deleted) {
184 throw invalidState();
185 }
186 suspendPolicy = JDItoJDWPSuspendPolicy(policy);
187 }
188
189 public int suspendPolicy() {
190 return JDWPtoJDISuspendPolicy(suspendPolicy);
191 }
192
193 /**
194 * set (enable) the event request
195 */
196 synchronized void set() {
197 JDWP.EventRequest.Set.Modifier[] mods =
198 (JDWP.EventRequest.Set.Modifier[])
199 filters.toArray(
200 new JDWP.EventRequest.Set.Modifier[filters.size()]);
201 try {
202 id = JDWP.EventRequest.Set.process(vm, (byte)eventCmd(),
203 suspendPolicy, mods).requestID;
204 } catch (JDWPException exc) {
205 throw exc.toJDIException();
206 }
207 isEnabled = true;
208 }
209
210 synchronized void clear() {
211 try {
212 JDWP.EventRequest.Clear.process(vm, (byte)eventCmd(), id);
213 } catch (JDWPException exc) {
214 throw exc.toJDIException();
215 }
216 isEnabled = false;
217 }
218
219 /**
220 * @return a small Map
221 * @see #putProperty
222 * @see #getProperty
223 */
224 private Map<Object, Object> getProperties() {
225 if (clientProperties == null) {
226 clientProperties = new HashMap<Object, Object>(2);
227 }
228 return clientProperties;
229 }
230
231 /**
232 * Returns the value of the property with the specified key. Only
233 * properties added with <code>putProperty</code> will return
234 * a non-null value.
235 *
236 * @return the value of this property or null
237 * @see #putProperty
238 */
239 public final Object getProperty(Object key) {
240 if (clientProperties == null) {
241 return null;
242 } else {
243 return getProperties().get(key);
244 }
245 }
246
247 /**
248 * Add an arbitrary key/value "property" to this component.
249 *
250 * @see #getProperty
251 */
252 public final void putProperty(Object key, Object value) {
253 if (value != null) {
254 getProperties().put(key, value);
255 } else {
256 getProperties().remove(key);
257 }
258 }
259 }
260
261 abstract class ThreadVisibleEventRequestImpl extends EventRequestImpl {
262 public synchronized void addThreadFilter(ThreadReference thread) {
263 validateMirror(thread);
264 if (isEnabled() || deleted) {
265 throw invalidState();
266 }
267 filters.add(JDWP.EventRequest.Set.Modifier.ThreadOnly
268 .create((ThreadReferenceImpl)thread));
269 }
270 }
271
272 abstract class ClassVisibleEventRequestImpl
273 extends ThreadVisibleEventRequestImpl {
274 public synchronized void addClassFilter(ReferenceType clazz) {
275 validateMirror(clazz);
276 if (isEnabled() || deleted) {
277 throw invalidState();
278 }
279 filters.add(JDWP.EventRequest.Set.Modifier.ClassOnly
280 .create((ReferenceTypeImpl)clazz));
281 }
282
283 public synchronized void addClassFilter(String classPattern) {
284 if (isEnabled() || deleted) {
285 throw invalidState();
286 }
287 if (classPattern == null) {
288 throw new NullPointerException();
289 }
290 filters.add(JDWP.EventRequest.Set.Modifier.ClassMatch
291 .create(classPattern));
292 }
293
294 public synchronized void addClassExclusionFilter(String classPattern) {
295 if (isEnabled() || deleted) {
296 throw invalidState();
297 }
298 if (classPattern == null) {
299 throw new NullPointerException();
300 }
301 filters.add(JDWP.EventRequest.Set.Modifier.ClassExclude
302 .create(classPattern));
303 }
304
305 public synchronized void addInstanceFilter(ObjectReference instance) {
306 validateMirror(instance);
307 if (isEnabled() || deleted) {
308 throw invalidState();
309 }
310 if (!vm.canUseInstanceFilters()) {
311 throw new UnsupportedOperationException(
312 "target does not support instance filters");
313 }
314 filters.add(JDWP.EventRequest.Set.Modifier.InstanceOnly
315 .create((ObjectReferenceImpl)instance));
316 }
317 }
318
319 class BreakpointRequestImpl extends ClassVisibleEventRequestImpl
320 implements BreakpointRequest {
321 private final Location location;
322
323 BreakpointRequestImpl(Location location) {
324 this.location = location;
325 filters.add(0,JDWP.EventRequest.Set.Modifier.LocationOnly
326 .create(location));
327 requestList().add(this);
328 }
329
330 public Location location() {
331 return location;
332 }
333
334 int eventCmd() {
335 return JDWP.EventKind.BREAKPOINT;
336 }
337
338 public String toString() {
339 return "breakpoint request " + location() + state();
340 }
341 }
342
343 class ClassPrepareRequestImpl extends ClassVisibleEventRequestImpl
344 implements ClassPrepareRequest {
345 ClassPrepareRequestImpl() {
346 requestList().add(this);
347 }
348
349 int eventCmd() {
350 return JDWP.EventKind.CLASS_PREPARE;
351 }
352
353 public synchronized void addSourceNameFilter(String sourceNamePattern) {
354 if (isEnabled() || deleted) {
355 throw invalidState();
356 }
357 if (!vm.canUseSourceNameFilters()) {
358 throw new UnsupportedOperationException(
359 "target does not support source name filters");
360 }
361 if (sourceNamePattern == null) {
362 throw new NullPointerException();
363 }
364
365 filters.add(JDWP.EventRequest.Set.Modifier.SourceNameMatch
366 .create(sourceNamePattern));
367 }
368
369 public String toString() {
370 return "class prepare request " + state();
371 }
372 }
373
374 class ClassUnloadRequestImpl extends ClassVisibleEventRequestImpl
375 implements ClassUnloadRequest {
376 ClassUnloadRequestImpl() {
377 requestList().add(this);
378 }
379
380 int eventCmd() {
381 return JDWP.EventKind.CLASS_UNLOAD;
382 }
383
384 public String toString() {
385 return "class unload request " + state();
386 }
387 }
388
389 class ExceptionRequestImpl extends ClassVisibleEventRequestImpl
390 implements ExceptionRequest {
391 ReferenceType exception = null;
392 boolean caught = true;
393 boolean uncaught = true;
394
395 ExceptionRequestImpl(ReferenceType refType,
396 boolean notifyCaught, boolean notifyUncaught) {
397 exception = refType;
398 caught = notifyCaught;
399 uncaught = notifyUncaught;
400 {
401 ReferenceTypeImpl exc;
402 if (exception == null) {
403 exc = new ClassTypeImpl(vm, 0);
404 } else {
405 exc = (ReferenceTypeImpl)exception;
406 }
407 filters.add(JDWP.EventRequest.Set.Modifier.ExceptionOnly.
408 create(exc, caught, uncaught));
409 }
410 requestList().add(this);
411 }
412
413 public ReferenceType exception() {
414 return exception;
415 }
416
417 public boolean notifyCaught() {
418 return caught;
419 }
420
421 public boolean notifyUncaught() {
422 return uncaught;
423 }
424
425 int eventCmd() {
426 return JDWP.EventKind.EXCEPTION;
427 }
428
429 public String toString() {
430 return "exception request " + exception() + state();
431 }
432 }
433
434 class MethodEntryRequestImpl extends ClassVisibleEventRequestImpl
435 implements MethodEntryRequest {
436 MethodEntryRequestImpl() {
437 requestList().add(this);
438 }
439
440 int eventCmd() {
441 return JDWP.EventKind.METHOD_ENTRY;
442 }
443
444 public String toString() {
445 return "method entry request " + state();
446 }
447 }
448
449 class MethodExitRequestImpl extends ClassVisibleEventRequestImpl
450 implements MethodExitRequest {
451 MethodExitRequestImpl() {
452 if (methodExitEventCmd == 0) {
453 /*
454 * If we can get return values, then we always get them.
455 * Thus, for JDI MethodExitRequests, we always use the
456 * same JDWP EventKind. Here we decide which to use and
457 * save it so that it will be used for all future
458 * MethodExitRequests.
459 *
460 * This call to canGetMethodReturnValues can't
461 * be done in the EventRequestManager ctor because that is too early.
462 */
463 if (vm.canGetMethodReturnValues()) {
464 methodExitEventCmd = JDWP.EventKind.METHOD_EXIT_WITH_RETURN_VALUE;
465 } else {
466 methodExitEventCmd = JDWP.EventKind.METHOD_EXIT;
467 }
468 }
469 requestList().add(this);
470 }
471
472 int eventCmd() {
473 return EventRequestManagerImpl.methodExitEventCmd;
474 }
475
476 public String toString() {
477 return "method exit request " + state();
478 }
479 }
480
481 class MonitorContendedEnterRequestImpl extends ClassVisibleEventRequestImpl
482 implements MonitorContendedEnterRequest {
483 MonitorContendedEnterRequestImpl() {
484 requestList().add(this);
485 }
486
487 int eventCmd() {
488 return JDWP.EventKind.MONITOR_CONTENDED_ENTER;
489 }
490
491 public String toString() {
492 return "monitor contended enter request " + state();
493 }
494 }
495
496 class MonitorContendedEnteredRequestImpl extends ClassVisibleEventRequestImpl
497 implements MonitorContendedEnteredRequest {
498 MonitorContendedEnteredRequestImpl() {
499 requestList().add(this);
500 }
501
502 int eventCmd() {
503 return JDWP.EventKind.MONITOR_CONTENDED_ENTERED;
504 }
505
506 public String toString() {
507 return "monitor contended entered request " + state();
508 }
509 }
510
511 class MonitorWaitRequestImpl extends ClassVisibleEventRequestImpl
512 implements MonitorWaitRequest {
513 MonitorWaitRequestImpl() {
514 requestList().add(this);
515 }
516
517 int eventCmd() {
518 return JDWP.EventKind.MONITOR_WAIT;
519 }
520
521 public String toString() {
522 return "monitor wait request " + state();
523 }
524 }
525
526 class MonitorWaitedRequestImpl extends ClassVisibleEventRequestImpl
527 implements MonitorWaitedRequest {
528 MonitorWaitedRequestImpl() {
529 requestList().add(this);
530 }
531
532 int eventCmd() {
533 return JDWP.EventKind.MONITOR_WAITED;
534 }
535
536 public String toString() {
537 return "monitor waited request " + state();
538 }
539 }
540
541 class StepRequestImpl extends ClassVisibleEventRequestImpl
542 implements StepRequest {
543 ThreadReferenceImpl thread;
544 int size;
545 int depth;
546
547 StepRequestImpl(ThreadReference thread, int size, int depth) {
548 this.thread = (ThreadReferenceImpl)thread;
549 this.size = size;
550 this.depth = depth;
551
552 /*
553 * Translate size and depth to corresponding JDWP values.
554 */
555 int jdwpSize;
556 switch (size) {
557 case STEP_MIN:
558 jdwpSize = JDWP.StepSize.MIN;
559 break;
560 case STEP_LINE:
561 jdwpSize = JDWP.StepSize.LINE;
562 break;
563 default:
564 throw new IllegalArgumentException("Invalid step size");
565 }
566
567 int jdwpDepth;
568 switch (depth) {
569 case STEP_INTO:
570 jdwpDepth = JDWP.StepDepth.INTO;
571 break;
572 case STEP_OVER:
573 jdwpDepth = JDWP.StepDepth.OVER;
574 break;
575 case STEP_OUT:
576 jdwpDepth = JDWP.StepDepth.OUT;
577 break;
578 default:
579 throw new IllegalArgumentException("Invalid step depth");
580 }
581
582 /*
583 * Make sure this isn't a duplicate
584 */
585 List requests = stepRequests();
586 Iterator iter = requests.iterator();
587 while (iter.hasNext()) {
588 StepRequest request = (StepRequest)iter.next();
589 if ((request != this) &&
590 request.isEnabled() &&
591 request.thread().equals(thread)) {
592 throw new DuplicateRequestException(
593 "Only one step request allowed per thread");
594 }
595 }
596
597 filters.add(JDWP.EventRequest.Set.Modifier.Step.
598 create(this.thread, jdwpSize, jdwpDepth));
599 requestList().add(this);
600
601 }
602 public int depth() {
603 return depth;
604 }
605
606 public int size() {
607 return size;
608 }
609
610 public ThreadReference thread() {
611 return thread;
612 }
613
614 int eventCmd() {
615 return JDWP.EventKind.SINGLE_STEP;
616 }
617
618 public String toString() {
619 return "step request " + thread() + state();
620 }
621 }
622
623 class ThreadDeathRequestImpl extends ThreadVisibleEventRequestImpl
624 implements ThreadDeathRequest {
625 ThreadDeathRequestImpl() {
626 requestList().add(this);
627 }
628
629 int eventCmd() {
630 return JDWP.EventKind.THREAD_DEATH;
631 }
632
633 public String toString() {
634 return "thread death request " + state();
635 }
636 }
637
638 class ThreadStartRequestImpl extends ThreadVisibleEventRequestImpl
639 implements ThreadStartRequest {
640 ThreadStartRequestImpl() {
641 requestList().add(this);
642 }
643
644 int eventCmd() {
645 return JDWP.EventKind.THREAD_START;
646 }
647
648 public String toString() {
649 return "thread start request " + state();
650 }
651 }
652
653 abstract class WatchpointRequestImpl extends ClassVisibleEventRequestImpl
654 implements WatchpointRequest {
655 final Field field;
656
657 WatchpointRequestImpl(Field field) {
658 this.field = field;
659 filters.add(0,
660 JDWP.EventRequest.Set.Modifier.FieldOnly.create(
661 (ReferenceTypeImpl)field.declaringType(),
662 ((FieldImpl)field).ref()));
663 }
664
665 public Field field() {
666 return field;
667 }
668 }
669
670 class AccessWatchpointRequestImpl extends WatchpointRequestImpl
671 implements AccessWatchpointRequest {
672 AccessWatchpointRequestImpl(Field field) {
673 super(field);
674 requestList().add(this);
675 }
676
677 int eventCmd() {
678 return JDWP.EventKind.FIELD_ACCESS;
679 }
680
681 public String toString() {
682 return "access watchpoint request " + field + state();
683 }
684 }
685
686 class ModificationWatchpointRequestImpl extends WatchpointRequestImpl
687 implements ModificationWatchpointRequest {
688 ModificationWatchpointRequestImpl(Field field) {
689 super(field);
690 requestList().add(this);
691 }
692
693 int eventCmd() {
694 return JDWP.EventKind.FIELD_MODIFICATION;
695 }
696
697 public String toString() {
698 return "modification watchpoint request " + field + state();
699 }
700 }
701
702 class VMDeathRequestImpl extends EventRequestImpl
703 implements VMDeathRequest {
704 VMDeathRequestImpl() {
705 requestList().add(this);
706 }
707
708 int eventCmd() {
709 return JDWP.EventKind.VM_DEATH;
710 }
711
712 public String toString() {
713 return "VM death request " + state();
714 }
715 }
716
717 /**
718 * Constructor.
719 */
720 EventRequestManagerImpl(VirtualMachine vm) {
721 super(vm);
722 java.lang.reflect.Field[] ekinds =
723 JDWP.EventKind.class.getDeclaredFields();
724 int highest = 0;
725 for (int i = 0; i < ekinds.length; ++i) {
726 int val;
727 try {
728 val = ekinds[i].getInt(null);
729 } catch (IllegalAccessException exc) {
730 throw new RuntimeException("Got: " + exc);
731 }
732 if (val > highest) {
733 highest = val;
734 }
735 }
736 requestLists = new List[highest+1];
737 for (int i=0; i <= highest; i++) {
738 requestLists[i] = new ArrayList();
739 }
740 }
741
742 public ClassPrepareRequest createClassPrepareRequest() {
743 return new ClassPrepareRequestImpl();
744 }
745
746 public ClassUnloadRequest createClassUnloadRequest() {
747 return new ClassUnloadRequestImpl();
748 }
749
750 public ExceptionRequest createExceptionRequest(ReferenceType refType,
751 boolean notifyCaught,
752 boolean notifyUncaught) {
753 validateMirrorOrNull(refType);
754 return new ExceptionRequestImpl(refType, notifyCaught, notifyUncaught);
755 }
756
757 public StepRequest createStepRequest(ThreadReference thread,
758 int size, int depth) {
759 validateMirror(thread);
760 return new StepRequestImpl(thread, size, depth);
761 }
762
763 public ThreadDeathRequest createThreadDeathRequest() {
764 return new ThreadDeathRequestImpl();
765 }
766
767 public ThreadStartRequest createThreadStartRequest() {
768 return new ThreadStartRequestImpl();
769 }
770
771 public MethodEntryRequest createMethodEntryRequest() {
772 return new MethodEntryRequestImpl();
773 }
774
775 public MethodExitRequest createMethodExitRequest() {
776 return new MethodExitRequestImpl();
777 }
778
779 public MonitorContendedEnterRequest createMonitorContendedEnterRequest() {
780 if (!vm.canRequestMonitorEvents()) {
781 throw new UnsupportedOperationException(
782 "target VM does not support requesting Monitor events");
783 }
784 return new MonitorContendedEnterRequestImpl();
785 }
786
787 public MonitorContendedEnteredRequest createMonitorContendedEnteredRequest() {
788 if (!vm.canRequestMonitorEvents()) {
789 throw new UnsupportedOperationException(
790 "target VM does not support requesting Monitor events");
791 }
792 return new MonitorContendedEnteredRequestImpl();
793 }
794
795 public MonitorWaitRequest createMonitorWaitRequest() {
796 if (!vm.canRequestMonitorEvents()) {
797 throw new UnsupportedOperationException(
798 "target VM does not support requesting Monitor events");
799 }
800 return new MonitorWaitRequestImpl();
801 }
802
803 public MonitorWaitedRequest createMonitorWaitedRequest() {
804 if (!vm.canRequestMonitorEvents()) {
805 throw new UnsupportedOperationException(
806 "target VM does not support requesting Monitor events");
807 }
808 return new MonitorWaitedRequestImpl();
809 }
810
811 public BreakpointRequest createBreakpointRequest(Location location) {
812 validateMirror(location);
813 if (location.codeIndex() == -1) {
814 throw new NativeMethodException("Cannot set breakpoints on native methods");
815 }
816 return new BreakpointRequestImpl(location);
817 }
818
819 public AccessWatchpointRequest
820 createAccessWatchpointRequest(Field field) {
821 validateMirror(field);
822 if (!vm.canWatchFieldAccess()) {
823 throw new UnsupportedOperationException(
824 "target VM does not support access watchpoints");
825 }
826 return new AccessWatchpointRequestImpl(field);
827 }
828
829 public ModificationWatchpointRequest
830 createModificationWatchpointRequest(Field field) {
831 validateMirror(field);
832 if (!vm.canWatchFieldModification()) {
833 throw new UnsupportedOperationException(
834 "target VM does not support modification watchpoints");
835 }
836 return new ModificationWatchpointRequestImpl(field);
837 }
838
839 public VMDeathRequest createVMDeathRequest() {
840 if (!vm.canRequestVMDeathEvent()) {
841 throw new UnsupportedOperationException(
842 "target VM does not support requesting VM death events");
843 }
844 return new VMDeathRequestImpl();
845 }
846
847 public void deleteEventRequest(EventRequest eventRequest) {
848 validateMirror(eventRequest);
849 ((EventRequestImpl)eventRequest).delete();
850 }
851
852 public void deleteEventRequests(List<? extends EventRequest> eventRequests) {
853 validateMirrors(eventRequests);
854 // copy the eventRequests to avoid ConcurrentModificationException
855 Iterator iter = (new ArrayList(eventRequests)).iterator();
856 while (iter.hasNext()) {
857 ((EventRequestImpl)iter.next()).delete();
858 }
859 }
860
861 public void deleteAllBreakpoints() {
862 requestList(JDWP.EventKind.BREAKPOINT).clear();
863
864 try {
865 JDWP.EventRequest.ClearAllBreakpoints.process(vm);
866 } catch (JDWPException exc) {
867 throw exc.toJDIException();
868 }
869 }
870
871 public List<StepRequest> stepRequests() {
872 return unmodifiableRequestList(JDWP.EventKind.SINGLE_STEP);
873 }
874
875 public List<ClassPrepareRequest> classPrepareRequests() {
876 return unmodifiableRequestList(JDWP.EventKind.CLASS_PREPARE);
877 }
878
879 public List<ClassUnloadRequest> classUnloadRequests() {
880 return unmodifiableRequestList(JDWP.EventKind.CLASS_UNLOAD);
881 }
882
883 public List<ThreadStartRequest> threadStartRequests() {
884 return unmodifiableRequestList(JDWP.EventKind.THREAD_START);
885 }
886
887 public List<ThreadDeathRequest> threadDeathRequests() {
888 return unmodifiableRequestList(JDWP.EventKind.THREAD_DEATH);
889 }
890
891 public List<ExceptionRequest> exceptionRequests() {
892 return unmodifiableRequestList(JDWP.EventKind.EXCEPTION);
893 }
894
895 public List<BreakpointRequest> breakpointRequests() {
896 return unmodifiableRequestList(JDWP.EventKind.BREAKPOINT);
897 }
898
899 public List<AccessWatchpointRequest> accessWatchpointRequests() {
900 return unmodifiableRequestList(JDWP.EventKind.FIELD_ACCESS);
901 }
902
903 public List<ModificationWatchpointRequest> modificationWatchpointRequests() {
904 return unmodifiableRequestList(JDWP.EventKind.FIELD_MODIFICATION);
905 }
906
907 public List<MethodEntryRequest> methodEntryRequests() {
908 return unmodifiableRequestList(JDWP.EventKind.METHOD_ENTRY);
909 }
910
911 public List<MethodExitRequest> methodExitRequests() {
912 return unmodifiableRequestList(
913 EventRequestManagerImpl.methodExitEventCmd);
914 }
915
916 public List<MonitorContendedEnterRequest> monitorContendedEnterRequests() {
917 return unmodifiableRequestList(JDWP.EventKind.MONITOR_CONTENDED_ENTER);
918 }
919
920 public List<MonitorContendedEnteredRequest> monitorContendedEnteredRequests() {
921 return unmodifiableRequestList(JDWP.EventKind.MONITOR_CONTENDED_ENTERED);
922 }
923
924 public List<MonitorWaitRequest> monitorWaitRequests() {
925 return unmodifiableRequestList(JDWP.EventKind.MONITOR_WAIT);
926 }
927
928 public List<MonitorWaitedRequest> monitorWaitedRequests() {
929 return unmodifiableRequestList(JDWP.EventKind.MONITOR_WAITED);
930 }
931
932 public List<VMDeathRequest> vmDeathRequests() {
933 return unmodifiableRequestList(JDWP.EventKind.VM_DEATH);
934 }
935
936 List unmodifiableRequestList(int eventCmd) {
937 return Collections.unmodifiableList(requestList(eventCmd));
938 }
939
940 EventRequest request(int eventCmd, int requestId) {
941 List rl = requestList(eventCmd);
942 for (int i = rl.size() - 1; i >= 0; i--) {
943 EventRequestImpl er = (EventRequestImpl)rl.get(i);
944 if (er.id == requestId) {
945 return er;
946 }
947 }
948 return null;
949 }
950
951 List<? extends EventRequest> requestList(int eventCmd) {
952 return requestLists[eventCmd];
953 }
954
955}