955 lines · 30.2 KB · Java
RawDownload
/* * Copyright (c) 1998, 2005, 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.request.*;import com.sun.tools.jdi.JDWP; import java.util.*; /** * This interface is used to create and remove Breakpoints, Watchpoints, * etc. * It include implementations of all the request interfaces.. */// Warnings from List filters and List[] requestLists is  hard to fix.// Remove SuppressWarning when we fix the warnings from List filters// and List[] requestLists. The generic array is not supported.@SuppressWarnings("unchecked")class EventRequestManagerImpl extends MirrorImpl                                       implements EventRequestManager{    List[] requestLists;    private static int methodExitEventCmd = 0;     static int JDWPtoJDISuspendPolicy(byte jdwpPolicy) {        switch(jdwpPolicy) {            case JDWP.SuspendPolicy.ALL:                return EventRequest.SUSPEND_ALL;            case JDWP.SuspendPolicy.EVENT_THREAD:                return EventRequest.SUSPEND_EVENT_THREAD;        case JDWP.SuspendPolicy.NONE:                return EventRequest.SUSPEND_NONE;            default:                throw new IllegalArgumentException("Illegal policy constant: " + jdwpPolicy);        }    }     static byte JDItoJDWPSuspendPolicy(int jdiPolicy) {        switch(jdiPolicy) {            case EventRequest.SUSPEND_ALL:                return JDWP.SuspendPolicy.ALL;            case EventRequest.SUSPEND_EVENT_THREAD:                return JDWP.SuspendPolicy.EVENT_THREAD;            case EventRequest.SUSPEND_NONE:                return JDWP.SuspendPolicy.NONE;            default:                throw new IllegalArgumentException("Illegal policy constant: " + jdiPolicy);        }    }     /*     * Override superclass back to default equality     */    public boolean equals(Object obj) {        return this == obj;    }     public int hashCode() {        return System.identityHashCode(this);    }     abstract class EventRequestImpl extends MirrorImpl implements EventRequest {        int id;         /*         * This list is not protected by a synchronized wrapper. All         * access/modification should be protected by synchronizing on         * the enclosing instance of EventRequestImpl.         */        List filters = new ArrayList();         boolean isEnabled = false;        boolean deleted = false;        byte suspendPolicy = JDWP.SuspendPolicy.ALL;        private Map<Object, Object> clientProperties = null;         EventRequestImpl() {            super(EventRequestManagerImpl.this.vm);        }          /*         * Override superclass back to default equality         */        public boolean equals(Object obj) {            return this == obj;        }         public int hashCode() {            return System.identityHashCode(this);        }         abstract int eventCmd();         InvalidRequestStateException invalidState() {            return new InvalidRequestStateException(toString());        }         String state() {            return deleted? " (deleted)" :                (isEnabled()? " (enabled)" : " (disabled)");        }         /**         * @return all the event request of this kind         */        List requestList() {            return EventRequestManagerImpl.this.requestList(eventCmd());        }         /**         * delete the event request         */        void delete() {            if (!deleted) {                requestList().remove(this);                disable(); /* must do BEFORE delete */                deleted = true;            }        }         public boolean isEnabled() {            return isEnabled;        }         public void enable() {            setEnabled(true);        }         public void disable() {            setEnabled(false);        }         public synchronized void setEnabled(boolean val) {            if (deleted) {                throw invalidState();            } else {                if (val != isEnabled) {                    if (isEnabled) {                        clear();                    } else {                        set();                    }                }            }        }         public synchronized void addCountFilter(int count) {            if (isEnabled() || deleted) {                throw invalidState();            }            if (count < 1) {                throw new IllegalArgumentException("count is less than one");            }            filters.add(JDWP.EventRequest.Set.Modifier.Count.create(count));        }         public void setSuspendPolicy(int policy) {            if (isEnabled() || deleted) {                throw invalidState();            }            suspendPolicy = JDItoJDWPSuspendPolicy(policy);        }         public int suspendPolicy() {            return JDWPtoJDISuspendPolicy(suspendPolicy);        }         /**         * set (enable) the event request         */        synchronized void set() {            JDWP.EventRequest.Set.Modifier[] mods =                (JDWP.EventRequest.Set.Modifier[])                filters.toArray(                    new JDWP.EventRequest.Set.Modifier[filters.size()]);            try {                id = JDWP.EventRequest.Set.process(vm, (byte)eventCmd(),                                                   suspendPolicy, mods).requestID;            } catch (JDWPException exc) {                throw exc.toJDIException();            }            isEnabled = true;        }         synchronized void clear() {            try {                JDWP.EventRequest.Clear.process(vm, (byte)eventCmd(), id);            } catch (JDWPException exc) {                throw exc.toJDIException();            }            isEnabled = false;        }         /**         * @return a small Map         * @see #putProperty         * @see #getProperty         */        private Map<Object, Object> getProperties() {            if (clientProperties == null) {                clientProperties = new HashMap<Object, Object>(2);            }            return clientProperties;        }         /**         * Returns the value of the property with the specified key.  Only         * properties added with <code>putProperty</code> will return         * a non-null value.         *         * @return the value of this property or null         * @see #putProperty         */        public final Object getProperty(Object key) {            if (clientProperties == null) {                return null;            } else {                return getProperties().get(key);            }        }         /**         * Add an arbitrary key/value "property" to this component.         *         * @see #getProperty         */        public final void putProperty(Object key, Object value) {            if (value != null) {                getProperties().put(key, value);            } else {                getProperties().remove(key);            }        }    }     abstract class ThreadVisibleEventRequestImpl extends EventRequestImpl {        public synchronized void addThreadFilter(ThreadReference thread) {            validateMirror(thread);            if (isEnabled() || deleted) {                throw invalidState();            }            filters.add(JDWP.EventRequest.Set.Modifier.ThreadOnly                                      .create((ThreadReferenceImpl)thread));        }    }     abstract class ClassVisibleEventRequestImpl                                  extends ThreadVisibleEventRequestImpl {        public synchronized void addClassFilter(ReferenceType clazz) {            validateMirror(clazz);            if (isEnabled() || deleted) {                throw invalidState();            }            filters.add(JDWP.EventRequest.Set.Modifier.ClassOnly                                      .create((ReferenceTypeImpl)clazz));        }         public synchronized void addClassFilter(String classPattern) {            if (isEnabled() || deleted) {                throw invalidState();            }            if (classPattern == null) {                throw new NullPointerException();            }            filters.add(JDWP.EventRequest.Set.Modifier.ClassMatch                                      .create(classPattern));        }         public synchronized void addClassExclusionFilter(String classPattern) {            if (isEnabled() || deleted) {                throw invalidState();            }            if (classPattern == null) {                throw new NullPointerException();            }            filters.add(JDWP.EventRequest.Set.Modifier.ClassExclude                                      .create(classPattern));        }         public synchronized void addInstanceFilter(ObjectReference instance) {            validateMirror(instance);            if (isEnabled() || deleted) {                throw invalidState();            }            if (!vm.canUseInstanceFilters()) {                throw new UnsupportedOperationException(                     "target does not support instance filters");            }            filters.add(JDWP.EventRequest.Set.Modifier.InstanceOnly                                      .create((ObjectReferenceImpl)instance));        }    }     class BreakpointRequestImpl extends ClassVisibleEventRequestImpl                                     implements BreakpointRequest {        private final Location location;         BreakpointRequestImpl(Location location) {            this.location = location;            filters.add(0,JDWP.EventRequest.Set.Modifier.LocationOnly                                                 .create(location));            requestList().add(this);        }         public Location location() {            return location;        }         int eventCmd() {            return JDWP.EventKind.BREAKPOINT;        }         public String toString() {            return "breakpoint request " + location() + state();        }    }     class ClassPrepareRequestImpl extends ClassVisibleEventRequestImpl                                     implements ClassPrepareRequest {        ClassPrepareRequestImpl() {            requestList().add(this);        }         int eventCmd() {            return JDWP.EventKind.CLASS_PREPARE;        }         public synchronized void addSourceNameFilter(String sourceNamePattern) {            if (isEnabled() || deleted) {                throw invalidState();            }            if (!vm.canUseSourceNameFilters()) {                throw new UnsupportedOperationException(                     "target does not support source name filters");            }            if (sourceNamePattern == null) {                throw new NullPointerException();            }             filters.add(JDWP.EventRequest.Set.Modifier.SourceNameMatch                                      .create(sourceNamePattern));        }         public String toString() {            return "class prepare request " + state();        }    }     class ClassUnloadRequestImpl extends ClassVisibleEventRequestImpl                                     implements ClassUnloadRequest {        ClassUnloadRequestImpl() {            requestList().add(this);        }         int eventCmd() {            return JDWP.EventKind.CLASS_UNLOAD;        }         public String toString() {            return "class unload request " + state();        }    }     class ExceptionRequestImpl extends ClassVisibleEventRequestImpl                                      implements ExceptionRequest {        ReferenceType exception = null;        boolean caught = true;        boolean uncaught = true;         ExceptionRequestImpl(ReferenceType refType,                          boolean notifyCaught, boolean notifyUncaught) {            exception = refType;            caught = notifyCaught;            uncaught = notifyUncaught;            {                ReferenceTypeImpl exc;                if (exception == null) {                    exc = new ClassTypeImpl(vm, 0);                } else {                    exc = (ReferenceTypeImpl)exception;                }                filters.add(JDWP.EventRequest.Set.Modifier.ExceptionOnly.                            create(exc, caught, uncaught));            }            requestList().add(this);        }         public ReferenceType exception() {            return exception;        }         public boolean notifyCaught() {            return caught;        }         public boolean notifyUncaught() {            return uncaught;        }         int eventCmd() {            return JDWP.EventKind.EXCEPTION;        }         public String toString() {            return "exception request " + exception() + state();        }    }     class MethodEntryRequestImpl extends ClassVisibleEventRequestImpl                                      implements MethodEntryRequest {        MethodEntryRequestImpl() {            requestList().add(this);        }         int eventCmd() {            return JDWP.EventKind.METHOD_ENTRY;        }         public String toString() {            return "method entry request " + state();        }    }     class MethodExitRequestImpl extends ClassVisibleEventRequestImpl                                      implements MethodExitRequest {        MethodExitRequestImpl() {            if (methodExitEventCmd == 0) {                /*                 * If we can get return values, then we always get them.                 * Thus, for JDI MethodExitRequests, we always use the                 * same JDWP EventKind.  Here we decide which to use and                 * save it so that it will be used for all future                 * MethodExitRequests.                 *                 * This call to canGetMethodReturnValues can't                 * be done in the EventRequestManager ctor because that is too early.                 */                if (vm.canGetMethodReturnValues()) {                    methodExitEventCmd = JDWP.EventKind.METHOD_EXIT_WITH_RETURN_VALUE;                } else {                    methodExitEventCmd = JDWP.EventKind.METHOD_EXIT;                }            }            requestList().add(this);        }         int eventCmd() {            return EventRequestManagerImpl.methodExitEventCmd;        }         public String toString() {            return "method exit request " + state();        }    }     class MonitorContendedEnterRequestImpl extends ClassVisibleEventRequestImpl                                      implements MonitorContendedEnterRequest {        MonitorContendedEnterRequestImpl() {            requestList().add(this);        }         int eventCmd() {            return JDWP.EventKind.MONITOR_CONTENDED_ENTER;        }         public String toString() {            return "monitor contended enter request " + state();        }    }     class MonitorContendedEnteredRequestImpl extends ClassVisibleEventRequestImpl                                      implements MonitorContendedEnteredRequest {        MonitorContendedEnteredRequestImpl() {            requestList().add(this);        }

Lines 1–500 of 955.