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 String javaLangString() {
 131       if (javaLangString == null) {
 132          javaLangString = "java/lang/String";
 133       }
 134       return javaLangString;
 135    }
 136 
 137    private String javaLangThread() {
 138       if (javaLangThread == null) {
 139          javaLangThread = "java/lang/Thread";
 140       }
 141       return javaLangThread;
 142    }
 143 
 144    private String javaLangClass() {
 145       if (javaLangClass == null) {
 146          javaLangClass = "java/lang/Class";
 147       }
 148       return javaLangClass;
 149    }
 150 
 151    private JSJavaObject newJavaInstance(Instance instance) {
 152       // look for well-known classes
 153       Symbol className = instance.getKlass().getName();
 154       if (Assert.ASSERTS_ENABLED) {
 155          Assert.that(className != null, "Null class name");
 156       }
 157       JSJavaObject res = null;
 158       if (className.equals(javaLangString())) {
 159          res = new JSJavaString(instance, this);
 160       } else if (className.equals(javaLangThread())) {
 161          res = new JSJavaThread(instance, this);
 162       } else if (className.equals(javaLangClass())) {
 163          Klass reflectedType = java_lang_Class.asKlass(instance);
 164          if (reflectedType != null) {
 165              JSJavaKlass jk = newJSJavaKlass(reflectedType);
 166              // we don't support mirrors of VM internal Klasses
 167              if (jk == null) return null;
 168              res = new JSJavaClass(instance, jk, this);
 169          } else {
 170              // for primitive Classes, the reflected type is null
 171              return null;
 172          }
 173       } else {
 174          // not a well-known class. But the base class may be
 175          // one of the known classes.
 176          Klass kls = instance.getKlass().getSuper();
 177          while (kls != null) {
 178             className = kls.getName();
 179             // java.lang.Class and java.lang.String are final classes
 180             if (className.equals(javaLangThread())) {
 181                res = new JSJavaThread(instance, this);
 182                break;
 183             }
 184             kls = kls.getSuper();
 185          }
 186       }
 187       if (res == null) {
 188          res = new JSJavaInstance(instance, this);
 189       }
 190       return res;
 191    }
 192 
 193    // Map<Oop, SoftReference<JSJavaObject>>
 194    private Map om = new HashMap();
 195    private String javaLangString;
 196    private String javaLangThread;
 197    private String javaLangClass;
 198 }