View Javadoc
1   /*
2    * Copyright (c) 2004, 2012, 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.utilities.soql;
26  
27  import java.lang.ref.*;
28  import java.util.*;
29  import sun.jvm.hotspot.oops.*;
30  import sun.jvm.hotspot.runtime.*;
31  import sun.jvm.hotspot.utilities.*;
32  
33  public class JSJavaFactoryImpl implements JSJavaFactory {
34     public JSJavaObject newJSJavaObject(Oop oop) {
35        if (oop == null) return null;
36        SoftReference sref = (SoftReference) om.get(oop);
37        JSJavaObject res = (sref != null)? (JSJavaObject) sref.get() : null;
38        if (res == null) {
39           if (oop instanceof TypeArray) {
40              res = new JSJavaTypeArray((TypeArray)oop, this);
41           } else if (oop instanceof ObjArray) {
42               res = new JSJavaObjArray((ObjArray)oop, this);
43           } else if (oop instanceof Instance) {
44              res = newJavaInstance((Instance) oop);
45           }
46        }
47        if (res != null) {
48           om.put(oop, new SoftReference(res));
49        }
50        return res;
51     }
52  
53     public JSJavaKlass newJSJavaKlass(Klass klass) {
54        JSJavaKlass res = null;
55        if (klass instanceof InstanceKlass) {
56            res = new JSJavaInstanceKlass((InstanceKlass) klass, this);
57        } else if (klass instanceof ObjArrayKlass) {
58            res = new JSJavaObjArrayKlass((ObjArrayKlass) klass, this);
59        } else if (klass instanceof TypeArrayKlass) {
60            res = new JSJavaTypeArrayKlass((TypeArrayKlass) klass, this);
61        }
62        if (res != null) {
63           om.put(klass, new SoftReference(res));
64        }
65        return res;
66     }
67  
68     public JSJavaMethod newJSJavaMethod(Method method) {
69        JSJavaMethod res = new JSJavaMethod(method, this);
70        if (res != null) {
71           om.put(method, new SoftReference(res));
72        }
73        return res;
74     }
75  
76     public JSJavaField newJSJavaField(Field field) {
77        if (field == null) return null;
78        return new JSJavaField(field, this);
79     }
80  
81     public JSJavaThread newJSJavaThread(JavaThread jthread) {
82        if (jthread == null) return null;
83        return new JSJavaThread(jthread, this);
84     }
85  
86     public JSJavaFrame newJSJavaFrame(JavaVFrame jvf) {
87        if (jvf == null) return null;
88        return new JSJavaFrame(jvf, this);
89     }
90  
91     public JSList newJSList(List list) {
92        if (list == null) return null;
93        return new JSList(list, this);
94     }
95  
96     public JSMap newJSMap(Map map) {
97        if (map == null) return null;
98        return new JSMap(map, this);
99     }
100 
101    public Object newJSJavaWrapper(Object item) {
102       if (item == null) return null;
103       if (item instanceof Oop) {
104          return newJSJavaObject((Oop) item);
105       } else if (item instanceof Field) {
106          return newJSJavaField((Field) item);
107       } else if (item instanceof JavaThread) {
108          return newJSJavaThread((JavaThread) item);
109       } else if (item instanceof JavaVFrame) {
110          return newJSJavaFrame((JavaVFrame) item);
111       } else if (item instanceof List) {
112          return newJSList((List) item);
113       } else if (item instanceof Map) {
114          return newJSMap((Map) item);
115       } else {
116          // not-a-special-type, just return the input item
117          return item;
118       }
119    }
120 
121    public JSJavaHeap newJSJavaHeap() {
122       return new JSJavaHeap(this);
123    }
124 
125    public JSJavaVM newJSJavaVM() {
126       return new JSJavaVM(this);
127    }
128 
129    // -- Internals only below this point
130    private Symbol javaLangString() {
131       if (javaLangString == null) {
132          javaLangString = getSymbol("java/lang/String");
133       }
134       return javaLangString;
135    }
136 
137    private Symbol javaLangThread() {
138       if (javaLangThread == null) {
139          javaLangThread = getSymbol("java/lang/Thread");
140       }
141       return javaLangThread;
142    }
143 
144    private Symbol javaLangClass() {
145       if (javaLangClass == null) {
146          javaLangClass = getSymbol("java/lang/Class");
147       }
148       return javaLangClass;
149    }
150 
151    private Symbol getSymbol(String str) {
152       return VM.getVM().getSymbolTable().probe(str);
153    }
154 
155    private JSJavaObject newJavaInstance(Instance instance) {
156       // look for well-known classes
157       Symbol className = instance.getKlass().getName();
158       if (Assert.ASSERTS_ENABLED) {
159          Assert.that(className != null, "Null class name");
160       }
161       JSJavaObject res = null;
162       if (className.equals(javaLangString())) {
163          res = new JSJavaString(instance, this);
164       } else if (className.equals(javaLangThread())) {
165          res = new JSJavaThread(instance, this);
166       } else if (className.equals(javaLangClass())) {
167          Klass reflectedType = java_lang_Class.asKlass(instance);
168          if (reflectedType != null) {
169              JSJavaKlass jk = newJSJavaKlass(reflectedType);
170              // we don't support mirrors of VM internal Klasses
171              if (jk == null) return null;
172              res = new JSJavaClass(instance, jk, this);
173          } else {
174              // for primitive Classes, the reflected type is null
175              return null;
176          }
177       } else {
178          // not a well-known class. But the base class may be
179          // one of the known classes.
180          Klass kls = instance.getKlass().getSuper();
181          while (kls != null) {
182             className = kls.getName();
183             // java.lang.Class and java.lang.String are final classes
184             if (className.equals(javaLangThread())) {
185                res = new JSJavaThread(instance, this);
186                break;
187             }
188             kls = kls.getSuper();
189          }
190       }
191       if (res == null) {
192          res = new JSJavaInstance(instance, this);
193       }
194       return res;
195    }
196 
197    // Map<Oop, SoftReference<JSJavaObject>>
198    private Map om = new HashMap();
199    private Symbol javaLangString;
200    private Symbol javaLangThread;
201    private Symbol javaLangClass;
202 }