Mercurial > hg > truffle
diff agent/src/share/classes/sun/jvm/hotspot/jdi/ClassTypeImpl.java @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | c18cbe5936b8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/ClassTypeImpl.java Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,241 @@ +/* + * Copyright 2002-2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package sun.jvm.hotspot.jdi; + +import com.sun.jdi.*; +import sun.jvm.hotspot.oops.Klass; +import sun.jvm.hotspot.oops.InstanceKlass; + +import java.util.*; +import java.lang.ref.SoftReference; + +public class ClassTypeImpl extends ReferenceTypeImpl + implements ClassType +{ + private SoftReference interfacesCache = null; + private SoftReference allInterfacesCache = null; + private SoftReference subclassesCache = null; + + protected ClassTypeImpl(VirtualMachine aVm, InstanceKlass aRef) { + super(aVm, aRef); + } + + public ClassType superclass() { + InstanceKlass kk = (InstanceKlass)ref().getSuper(); + if (kk == null) { + return null; + } + return (ClassType) vm.referenceType(kk); + } + + public List interfaces() { + List interfaces = (interfacesCache != null)? (List) interfacesCache.get() : null; + if (interfaces == null) { + checkPrepared(); + interfaces = Collections.unmodifiableList(getInterfaces()); + interfacesCache = new SoftReference(interfaces); + } + return interfaces; + } + + void addInterfaces(List list) { + List immediate = interfaces(); + + HashSet hashList = new HashSet(list); + hashList.addAll(immediate); + list.clear(); + list.addAll(hashList); + + Iterator iter = immediate.iterator(); + while (iter.hasNext()) { + InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); + interfaze.addSuperinterfaces(list); + } + + ClassTypeImpl superclass = (ClassTypeImpl)superclass(); + if (superclass != null) { + superclass.addInterfaces(list); + } + } + + public List allInterfaces() { + List allinterfaces = (allInterfacesCache != null)? (List) allInterfacesCache.get() : null; + if (allinterfaces == null) { + checkPrepared(); + allinterfaces = new ArrayList(); + addInterfaces(allinterfaces); + allinterfaces = Collections.unmodifiableList(allinterfaces); + allInterfacesCache = new SoftReference(allinterfaces); + } + return allinterfaces; + } + + public List subclasses() { + List subclasses = (subclassesCache != null)? (List) subclassesCache.get() : null; + if (subclasses == null) { + List all = vm.allClasses(); + subclasses = new ArrayList(0); + Iterator iter = all.iterator(); + while (iter.hasNext()) { + ReferenceType refType = (ReferenceType)iter.next(); + if (refType instanceof ClassType) { + ClassType clazz = (ClassType)refType; + ClassType superclass = clazz.superclass(); + if ((superclass != null) && superclass.equals(this)) { + subclasses.add(refType); + } + } + } + subclasses = Collections.unmodifiableList(subclasses); + subclassesCache = new SoftReference(subclasses); + } + return subclasses; + } + + public Method concreteMethodByName(String name, String signature) { + checkPrepared(); + List methods = visibleMethods(); + Method method = null; + Iterator iter = methods.iterator(); + while (iter.hasNext()) { + Method candidate = (Method)iter.next(); + if (candidate.name().equals(name) && + candidate.signature().equals(signature) && + !candidate.isAbstract()) { + + method = candidate; + break; + } + } + return method; + } + + List getAllMethods() { + ArrayList list = new ArrayList(methods()); + ClassType clazz = superclass(); + while (clazz != null) { + list.addAll(clazz.methods()); + clazz = clazz.superclass(); + } + /* + * Avoid duplicate checking on each method by iterating through + * duplicate-free allInterfaces() rather than recursing + */ + Iterator iter = allInterfaces().iterator(); + while (iter.hasNext()) { + InterfaceType interfaze = (InterfaceType)iter.next(); + list.addAll(interfaze.methods()); + } + return list; + } + + List inheritedTypes() { + List inherited = new ArrayList(interfaces()); + if (superclass() != null) { + inherited.add(0, superclass()); /* insert at front */ + } + return inherited; + } + + public boolean isEnum() { + ClassTypeImpl superclass = (ClassTypeImpl) superclass(); + if (superclass != null) { + return superclass.typeNameAsSymbol().equals(vm.javaLangEnum()); + } else { + return false; + } + } + + public void setValue(Field field, Value value) + throws InvalidTypeException, ClassNotLoadedException { + vm.throwNotReadOnlyException("ClassType.setValue(...)"); + } + + + public Value invokeMethod(ThreadReference threadIntf, Method methodIntf, + List arguments, int options) + throws InvalidTypeException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvocationException { + vm.throwNotReadOnlyException("ClassType.invokeMethod(...)"); + return null; + } + + public ObjectReference newInstance(ThreadReference threadIntf, + Method methodIntf, + List arguments, int options) + throws InvalidTypeException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvocationException { + vm.throwNotReadOnlyException("ClassType.newInstance(...)"); + return null; + } + + void addVisibleMethods(Map methodMap) { + /* + * Add methods from + * parent types first, so that the methods in this class will + * overwrite them in the hash table + */ + + Iterator iter = interfaces().iterator(); + while (iter.hasNext()) { + InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); + interfaze.addVisibleMethods(methodMap); + } + + ClassTypeImpl clazz = (ClassTypeImpl)superclass(); + if (clazz != null) { + clazz.addVisibleMethods(methodMap); + } + + addToMethodMap(methodMap, methods()); + } + + boolean isAssignableTo(ReferenceType type) { + ClassTypeImpl superclazz = (ClassTypeImpl)superclass(); + if (this.equals(type)) { + return true; + } else if ((superclazz != null) && superclazz.isAssignableTo(type)) { + return true; + } else { + List interfaces = interfaces(); + Iterator iter = interfaces.iterator(); + while (iter.hasNext()) { + InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next(); + if (interfaze.isAssignableTo(type)) { + return true; + } + } + return false; + } + } + + public String toString() { + return "class " + name() + "(" + loaderString() + ")"; + } +}