View Javadoc
1   /*
2    * Copyright (c) 2002, 2003, 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.
8    *
9    * This code is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12   * version 2 for more details (a copy is included in the LICENSE file that
13   * accompanied this code).
14   *
15   * You should have received a copy of the GNU General Public License version
16   * 2 along with this work; if not, write to the Free Software Foundation,
17   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18   *
19   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20   * or visit www.oracle.com if you need additional information or have any
21   * questions.
22   *
23   */
24  
25  package sun.jvm.hotspot.jdi;
26  
27  import sun.jvm.hotspot.oops.Oop;
28  import sun.jvm.hotspot.oops.Instance;
29  import sun.jvm.hotspot.oops.Klass;
30  import sun.jvm.hotspot.memory.SystemDictionary;
31  import sun.jvm.hotspot.memory.Universe;
32  import sun.jvm.hotspot.runtime.VM;
33  
34  import com.sun.jdi.*;
35  import java.util.*;
36  
37  public class ClassLoaderReferenceImpl
38      extends ObjectReferenceImpl
39      implements ClassLoaderReference
40  {
41       // because we work on process snapshot or core we can
42       // cache visibleClasses & definedClasses always (i.e., no suspension)
43       private List visibleClassesCache;
44       private List definedClassesCache;
45  
46       ClassLoaderReferenceImpl(VirtualMachine aVm, Instance oRef) {
47           super(aVm, oRef);
48       }
49  
50       protected String description() {
51           return "ClassLoaderReference " + uniqueID();
52       }
53  
54       public List definedClasses() {
55           if (definedClassesCache == null) {
56               definedClassesCache = new ArrayList();
57               Iterator iter = vm.allClasses().iterator();
58               while (iter.hasNext()) {
59                   ReferenceType type = (ReferenceType)iter.next();
60                   if (equals(type.classLoader())) {  /* thanks OTI */
61                       definedClassesCache.add(type);
62                   }
63               }
64           }
65           return definedClassesCache;
66       }
67  
68       private SystemDictionary getSystemDictionary() {
69           return vm.saSystemDictionary();
70       }
71  
72       private Universe getUniverse() {
73           return vm.saUniverse();
74       }
75  
76       public List visibleClasses() {
77           if (visibleClassesCache != null)
78              return visibleClassesCache;
79  
80           visibleClassesCache = new ArrayList();
81  
82           // refer to getClassLoaderClasses in jvmtiGetLoadedClasses.cpp
83           //  a. SystemDictionary::classes_do doesn't include arrays of primitive types (any dimensions)
84           SystemDictionary sysDict = getSystemDictionary();
85           sysDict.classesDo(
86                             new SystemDictionary.ClassAndLoaderVisitor() {
87                                  public void visit(Klass k, Oop loader) {
88                                      if (ref().equals(loader)) {
89                                          for (Klass l = k; l != null; l = l.arrayKlassOrNull()) {
90                                              visibleClassesCache.add(vm.referenceType(l));
91                                          }
92                                      }
93                                  }
94                             }
95                             );
96  
97           // b. multi dimensional arrays of primitive types
98           sysDict.primArrayClassesDo(
99                                      new SystemDictionary.ClassAndLoaderVisitor() {
100                                          public void visit(Klass k, Oop loader) {
101                                              if (ref().equals(loader)) {
102                                                  visibleClassesCache.add(vm.referenceType(k));
103                                              }
104                                          }
105                                      }
106                                      );
107 
108          // c. single dimensional primitive array klasses from Universe
109          // these are not added to SystemDictionary
110          getUniverse().basicTypeClassesDo(
111                             new SystemDictionary.ClassVisitor() {
112                                 public void visit(Klass k) {
113                                     visibleClassesCache.add(vm.referenceType(k));
114                                 }
115                             }
116                             );
117 
118          return visibleClassesCache;
119      }
120 
121      Type findType(String signature) throws ClassNotLoadedException {
122          List types = visibleClasses();
123          Iterator iter = types.iterator();
124          while (iter.hasNext()) {
125              ReferenceType type = (ReferenceType)iter.next();
126              if (type.signature().equals(signature)) {
127                  return type;
128              }
129          }
130          JNITypeParser parser = new JNITypeParser(signature);
131          throw new ClassNotLoadedException(parser.typeName(),
132                                           "Class " + parser.typeName() + " not loaded");
133      }
134 }