874 lines · 28.4 KB · Java
RawDownload
/* * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code 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.  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. */ package com.sun.tools.jdi; import com.sun.jdi.*;import com.sun.jdi.event.*;import com.sun.jdi.request.*; import java.util.*;enum EventDestination {UNKNOWN_EVENT, INTERNAL_EVENT, CLIENT_EVENT}; /* * An EventSet is normally created by the transport reader thread when * it reads a JDWP Composite command.  The constructor doesn't unpack * the events contained in the Composite command and create EventImpls * for them because that process might involve calling back into the back-end * which should not be done by the transport reader thread.  Instead, * the raw bytes of the packet are read and stored in the EventSet. * The EventSet is then added to each EventQueue. When an EventSet is * removed from an EventQueue, the EventSetImpl.build() method is called. * This method reads the packet bytes and creates the actual EventImpl objects. * build() also filters out events for our internal handler and puts them in * their own EventSet.  This means that the EventImpls that are in the EventSet * that is on the queues are all for client requests. */public class EventSetImpl extends ArrayList<Event> implements EventSet {     private VirtualMachineImpl vm; // we implement Mirror    private Packet pkt;    private byte suspendPolicy;    private EventSetImpl internalEventSet;     public String toString() {        String string = "event set, policy:" + suspendPolicy +                        ", count:" + this.size() + " = {";        boolean first = true;        for (Event event : this) {            if (!first) {                string += ", ";            }            string += event.toString();            first = false;        }        string += "}";        return string;    }     abstract class EventImpl extends MirrorImpl implements Event {         private final byte eventCmd;        private final int requestID;        // This is set only for client requests, not internal requests.        private final EventRequest request;         /**         * Constructor for events.         */        protected EventImpl(JDWP.Event.Composite.Events.EventsCommon evt,                            int requestID) {            super(EventSetImpl.this.vm);            this.eventCmd = evt.eventKind();            this.requestID = requestID;            EventRequestManagerImpl ermi = EventSetImpl.this.                vm.eventRequestManagerImpl();            this.request =  ermi.request(eventCmd, requestID);        }         /*         * Override superclass back to default equality         */        public boolean equals(Object obj) {            return this == obj;        }         public int hashCode() {            return System.identityHashCode(this);        }         /**         * Constructor for VM disconnected events.         */        protected EventImpl(byte eventCmd) {            super(EventSetImpl.this.vm);            this.eventCmd = eventCmd;            this.requestID = 0;            this.request = null;        }         public EventRequest request() {            return request;        }         int requestID() {            return requestID;        }         EventDestination destination() {            /*             * We need to decide if this event is for             * 1. an internal request             * 2. a client request that is no longer available, ie             *    it has been deleted, or disabled and re-enabled             *    which gives it a new ID.             * 3. a current client request that is disabled             * 4. a current enabled client request.             *             * We will filter this set into a set             * that contains only 1s for our internal queue             * and a set that contains only 4s for our client queue.             * If we get an EventSet that contains only 2 and 3             * then we have to resume it if it is not SUSPEND_NONE             * because no one else will.             */            if (requestID == 0) {                /* An unsolicited event.  These have traditionally                 * been treated as client events.                 */                return EventDestination.CLIENT_EVENT;            }             // Is this an event for a current client request?            if (request == null) {                // Nope.  Is it an event for an internal request?                EventRequestManagerImpl ermi = this.vm.getInternalEventRequestManager();                if (ermi.request(eventCmd, requestID) != null) {                    // Yep                    return EventDestination.INTERNAL_EVENT;                }                return EventDestination.UNKNOWN_EVENT;            }             // We found a client request            if (request.isEnabled()) {                return EventDestination.CLIENT_EVENT;            }            return EventDestination.UNKNOWN_EVENT;        }         abstract String eventName();         public String toString() {            return eventName();        }     }     abstract class ThreadedEventImpl extends EventImpl {        private ThreadReference thread;         ThreadedEventImpl(JDWP.Event.Composite.Events.EventsCommon evt,                          int requestID, ThreadReference thread) {            super(evt, requestID);            this.thread = thread;        }         public ThreadReference thread() {            return thread;        }         public String toString() {            return eventName() + " in thread " + thread.name();        }    }     abstract class LocatableEventImpl extends ThreadedEventImpl                                            implements Locatable {        private Location location;         LocatableEventImpl(JDWP.Event.Composite.Events.EventsCommon evt,                           int requestID,                           ThreadReference thread, Location location) {            super(evt, requestID, thread);            this.location = location;        }         public Location location() {            return location;        }         /**         * For MethodEntry and MethodExit         */        public Method method() {            return location.method();        }         public String toString() {            return eventName() + "@" +                   ((location() == null) ? " null" : location().toString()) +                   " in thread " + thread().name();        }    }     class BreakpointEventImpl extends LocatableEventImpl                            implements BreakpointEvent {        BreakpointEventImpl(JDWP.Event.Composite.Events.Breakpoint evt) {            super(evt, evt.requestID, evt.thread, evt.location);        }         String eventName() {            return "BreakpointEvent";        }    }     class StepEventImpl extends LocatableEventImpl implements StepEvent {        StepEventImpl(JDWP.Event.Composite.Events.SingleStep evt) {            super(evt, evt.requestID, evt.thread, evt.location);        }         String eventName() {            return "StepEvent";        }    }     class MethodEntryEventImpl extends LocatableEventImpl                            implements MethodEntryEvent {        MethodEntryEventImpl(JDWP.Event.Composite.Events.MethodEntry evt) {            super(evt, evt.requestID, evt.thread, evt.location);        }         String eventName() {            return "MethodEntryEvent";        }    }     class MethodExitEventImpl extends LocatableEventImpl                            implements MethodExitEvent {        private Value returnVal = null;         MethodExitEventImpl(JDWP.Event.Composite.Events.MethodExit evt) {            super(evt, evt.requestID, evt.thread, evt.location);        }         MethodExitEventImpl(JDWP.Event.Composite.Events.MethodExitWithReturnValue evt) {            super(evt, evt.requestID, evt.thread, evt.location);            returnVal = evt.value;        }         String eventName() {            return "MethodExitEvent";        }         public Value returnValue() {            if (!this.vm.canGetMethodReturnValues()) {                throw new UnsupportedOperationException(                "target does not support return values in MethodExit events");            }            return returnVal;        }     }     class MonitorContendedEnterEventImpl extends LocatableEventImpl                            implements MonitorContendedEnterEvent {        private ObjectReference monitor = null;         MonitorContendedEnterEventImpl(JDWP.Event.Composite.Events.MonitorContendedEnter evt) {            super(evt, evt.requestID, evt.thread, evt.location);            this.monitor = evt.object;        }         String eventName() {            return "MonitorContendedEnter";        }         public ObjectReference  monitor() {            return monitor;        };     }     class MonitorContendedEnteredEventImpl extends LocatableEventImpl                            implements MonitorContendedEnteredEvent {        private ObjectReference monitor = null;         MonitorContendedEnteredEventImpl(JDWP.Event.Composite.Events.MonitorContendedEntered evt) {            super(evt, evt.requestID, evt.thread, evt.location);            this.monitor = evt.object;        }         String eventName() {            return "MonitorContendedEntered";        }         public ObjectReference  monitor() {            return monitor;        };     }     class MonitorWaitEventImpl extends LocatableEventImpl                            implements MonitorWaitEvent {        private ObjectReference monitor = null;        private long timeout;         MonitorWaitEventImpl(JDWP.Event.Composite.Events.MonitorWait evt) {            super(evt, evt.requestID, evt.thread, evt.location);            this.monitor = evt.object;            this.timeout = evt.timeout;        }         String eventName() {            return "MonitorWait";        }         public ObjectReference  monitor() {            return monitor;        };         public long timeout() {            return timeout;        }    }     class MonitorWaitedEventImpl extends LocatableEventImpl                            implements MonitorWaitedEvent {        private ObjectReference monitor = null;        private boolean timed_out;         MonitorWaitedEventImpl(JDWP.Event.Composite.Events.MonitorWaited evt) {            super(evt, evt.requestID, evt.thread, evt.location);            this.monitor = evt.object;            this.timed_out = evt.timed_out;        }         String eventName() {            return "MonitorWaited";        }         public ObjectReference  monitor() {            return monitor;        };         public boolean timedout() {            return timed_out;        }    }     class ClassPrepareEventImpl extends ThreadedEventImpl                            implements ClassPrepareEvent {        private ReferenceType referenceType;         ClassPrepareEventImpl(JDWP.Event.Composite.Events.ClassPrepare evt) {            super(evt, evt.requestID, evt.thread);            referenceType = this.vm.referenceType(evt.typeID, evt.refTypeTag,                                                  evt.signature);            ((ReferenceTypeImpl)referenceType).setStatus(evt.status);        }         public ReferenceType referenceType() {            return referenceType;        }         String eventName() {            return "ClassPrepareEvent";        }    }     class ClassUnloadEventImpl extends EventImpl implements ClassUnloadEvent {        private String classSignature;         ClassUnloadEventImpl(JDWP.Event.Composite.Events.ClassUnload evt) {            super(evt, evt.requestID);            this.classSignature = evt.signature;        }         public String className() {            return classSignature.substring(1, classSignature.length()-1)                .replace('/', '.');        }         public String classSignature() {            return classSignature;        }         String eventName() {            return "ClassUnloadEvent";        }    }     class ExceptionEventImpl extends LocatableEventImpl                                             implements ExceptionEvent {        private ObjectReference exception;        private Location catchLocation;         ExceptionEventImpl(JDWP.Event.Composite.Events.Exception evt) {            super(evt, evt.requestID, evt.thread, evt.location);            this.exception = evt.exception;            this.catchLocation = evt.catchLocation;        }         public ObjectReference exception() {            return exception;        }         public Location catchLocation() {            return catchLocation;        }         String eventName() {            return "ExceptionEvent";        }    }     class ThreadDeathEventImpl extends ThreadedEventImpl                                        implements ThreadDeathEvent {        ThreadDeathEventImpl(JDWP.Event.Composite.Events.ThreadDeath evt) {            super(evt, evt.requestID, evt.thread);        }         String eventName() {            return "ThreadDeathEvent";        }    }     class ThreadStartEventImpl extends ThreadedEventImpl                                        implements ThreadStartEvent {        ThreadStartEventImpl(JDWP.Event.Composite.Events.ThreadStart evt) {            super(evt, evt.requestID, evt.thread);        }         String eventName() {            return "ThreadStartEvent";        }    }     class VMStartEventImpl extends ThreadedEventImpl                                        implements VMStartEvent {        VMStartEventImpl(JDWP.Event.Composite.Events.VMStart evt) {            super(evt, evt.requestID, evt.thread);        }         String eventName() {            return "VMStartEvent";        }    }     class VMDeathEventImpl extends EventImpl implements VMDeathEvent {         VMDeathEventImpl(JDWP.Event.Composite.Events.VMDeath evt) {            super(evt, evt.requestID);        }         String eventName() {            return "VMDeathEvent";        }    }     class VMDisconnectEventImpl extends EventImpl                                         implements VMDisconnectEvent {         VMDisconnectEventImpl() {            super((byte)JDWP.EventKind.VM_DISCONNECTED);        }         String eventName() {            return "VMDisconnectEvent";        }    }     abstract class WatchpointEventImpl extends LocatableEventImpl                                            implements WatchpointEvent {        private final ReferenceTypeImpl refType;        private final long fieldID;        private final ObjectReference object;        private Field field = null;         WatchpointEventImpl(JDWP.Event.Composite.Events.EventsCommon evt,                            int requestID,                            ThreadReference thread, Location location,                            byte refTypeTag, long typeID, long fieldID,                            ObjectReference object) {            super(evt, requestID, thread, location);            this.refType = this.vm.referenceType(typeID, refTypeTag);            this.fieldID = fieldID;            this.object = object;        }

Lines 1–500 of 874.