diff agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicType.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children ba764ed4b6f2
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicType.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2000-2005 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.types.basic;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+/** <P> This is a basic implementation of the Type interface which
+    should be complete enough to be portable across platforms. The
+    only issue will be the construction of these objects and their
+    components from the platform-specific debugging information; see
+    BasicTypeDataBase. </P>
+
+    <P> There are two types of clients of this class. The first is
+    that which builds the TypeDatabase. This kind of client uses the
+    additional public methods beyond those in the Type interface to
+    properly configure the BasicType objects. The second is the
+    consumer of these types; this kind of client should deal only with
+    the Type interfaces. </P> */
+
+public class BasicType implements Type {
+  protected BasicTypeDataBase db;
+
+  private String name;
+  private long size;
+  private boolean isJavaPrimitiveType;
+  private boolean isOopType;
+  // These are only the fields defined in this class, not any of this
+  // class's superclasses.
+  private Map nameToFieldMap = new HashMap();
+  private List fieldList = new LinkedList();
+  // Superclass, or null if none. Primitive types do not have any
+  // inheritance relationship.
+  private Type superclass;
+
+  /** superclass may be null */
+  public BasicType(BasicTypeDataBase db, String name, Type superclass) {
+    if (name == null) {
+      throw new IllegalArgumentException("name may not be null");
+    }
+    this.db = db;
+    this.name = name;
+    this.superclass = superclass;
+  }
+
+  /** Equivalent to BasicType(db, name, null) */
+  public BasicType(BasicTypeDataBase db, String name) {
+    this(db, name, null);
+  }
+
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+
+    if (!(obj instanceof BasicType)) {
+      return false;
+    }
+
+    BasicType arg = (BasicType) obj;
+
+    if (!name.equals(arg.name)) {
+      return false;
+    }
+
+    return true;
+  }
+
+  public int hashCode() {
+    return name.hashCode();
+  }
+
+  public String toString() {
+    return name;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  /** This should only be called at most once, and only by the builder
+      of the type database */
+  public void setSuperclass(Type superclass) {
+    this.superclass = superclass;
+  }
+
+  public Type getSuperclass() {
+    return superclass;
+  }
+
+  /** This should only be called at most once, and only by the builder
+      of the type database */
+  public void setSize(long sizeInBytes) {
+    this.size = sizeInBytes;
+  }
+
+  public long getSize() {
+    return size;
+  }
+
+  /** Overridden by BasicCIntegerType */
+  public boolean isCIntegerType() {
+    return false;
+  }
+
+  public boolean isCStringType() {
+    if (isPointerType()) {
+      Type target = ((PointerType)this).getTargetType();
+      return target.isCIntegerType() &&
+             target.getName().equals("const char");
+    } else {
+      return false;
+    }
+  }
+
+  public boolean isJavaPrimitiveType() {
+    return isJavaPrimitiveType;
+  }
+
+  /** This should only be called at most once, and only by the builder
+      of the type database */
+  public void setIsJavaPrimitiveType(boolean isJavaPrimitiveType) {
+    this.isJavaPrimitiveType = isJavaPrimitiveType;
+  }
+
+  public boolean isOopType() {
+    return isOopType;
+  }
+
+  /** Overridden by BasicPointerType */
+  public boolean isPointerType() {
+    return false;
+  }
+
+  /** This should only be called at most once, and only by the builder
+      of the type database */
+  public void setIsOopType(boolean isOopType) {
+    this.isOopType = isOopType;
+  }
+
+  public Field getField(String fieldName, boolean searchSuperclassFields,
+                        boolean throwExceptionIfNotFound) {
+    Field field = null;
+    if (nameToFieldMap != null) {
+      field = (Field) nameToFieldMap.get(fieldName);
+
+      if (field != null) {
+        return field;
+      }
+    }
+
+    if (searchSuperclassFields) {
+      if (superclass != null) {
+        field = superclass.getField(fieldName, searchSuperclassFields, false);
+      }
+    }
+
+    if (field == null && throwExceptionIfNotFound) {
+      throw new RuntimeException("field \"" + fieldName + "\" not found in type " + name);
+    }
+
+    return field;
+  }
+
+  public Field getField(String fieldName, boolean searchSuperclassFields) {
+    return getField(fieldName, searchSuperclassFields, true);
+  }
+
+  public Field getField(String fieldName) {
+    return getField(fieldName, true);
+  }
+
+  public Field getField(String fieldName, Type declaredType,
+                        boolean searchSuperclassFields) throws WrongTypeException {
+    Field res = getField(fieldName, searchSuperclassFields);
+    if (res == null) {
+      return null;
+    }
+    if (!res.getType().equals(declaredType)) {
+      throw new WrongTypeException("field \"" + fieldName + "\" in type " + name +
+                                    " is not of type " + declaredType +
+                                    ", but instead of type " + res.getType());
+    }
+    return res;
+  }
+
+  public Field getField(String fieldName, Type declaredType) throws WrongTypeException {
+    return getField(fieldName, declaredType, false);
+  }
+
+  /** The returned iterator's "remove" method must not be called */
+  public Iterator getFields() {
+    return new ConstIterator(fieldList.iterator());
+  }
+
+  //--------------------------------------------------------------------------------
+  // Specialized field type accessors
+  //
+
+  public JBooleanField getJBooleanField(String fieldName) throws WrongTypeException {
+    return (JBooleanField) getField(fieldName, db.getJBooleanType());
+  }
+
+  public JByteField    getJByteField(String fieldName) throws WrongTypeException {
+    return (JByteField) getField(fieldName, db.getJByteType());
+  }
+
+  public JCharField    getJCharField(String fieldName) throws WrongTypeException {
+    return (JCharField) getField(fieldName, db.getJCharType());
+  }
+
+  public JDoubleField  getJDoubleField(String fieldName) throws WrongTypeException {
+    return (JDoubleField) getField(fieldName, db.getJDoubleType());
+  }
+
+  public JFloatField   getJFloatField(String fieldName) throws WrongTypeException {
+    return (JFloatField) getField(fieldName, db.getJFloatType());
+  }
+
+  public JIntField     getJIntField(String fieldName) throws WrongTypeException {
+    return (JIntField) getField(fieldName, db.getJIntType());
+  }
+
+  public JLongField    getJLongField(String fieldName) throws WrongTypeException {
+    return (JLongField) getField(fieldName, db.getJLongType());
+  }
+
+  public JShortField   getJShortField(String fieldName) throws WrongTypeException {
+    return (JShortField) getField(fieldName, db.getJShortType());
+  }
+
+  public CIntegerField getCIntegerField(String fieldName) throws WrongTypeException {
+    Field field = getField(fieldName);
+    if (!(field.getType() instanceof CIntegerType)) {
+      throw new WrongTypeException("field \"" + fieldName + "\" in type " + name +
+                                   " is not of C integer type, but instead of type " +
+                                   field.getType());
+    }
+    return (CIntegerField) field;
+  }
+
+  public OopField getOopField(String fieldName) throws WrongTypeException {
+    Field field = getField(fieldName);
+    if (!field.getType().isOopType()) {
+      throw new WrongTypeException("field \"" + fieldName + "\" in type " + name +
+                                   " is not of oop type, but instead of type " +
+                                   field.getType());
+    }
+    return (OopField) field;
+  }
+
+  public AddressField getAddressField(String fieldName) {
+    // This type can not be inferred (for now), so provide a wrapper
+    Field field = getField(fieldName);
+    if (field == null) {
+      return null;
+    }
+    return new BasicAddressFieldWrapper(field);
+  }
+
+  /** This method should only be used by the builder of the
+      TypeDataBase. Throws a RuntimeException if a field with this
+      name was already present in this class. */
+  public void addField(Field field) {
+    if (nameToFieldMap.get(field.getName()) != null) {
+      throw new RuntimeException("field of name \"" + field.getName() + "\" already present");
+    }
+
+    nameToFieldMap.put(field.getName(), field);
+    fieldList.add(field);
+  }
+
+  /** This method should only be used by the builder of the
+      TypeDataBase. Throws a RuntimeException if a field with this
+      name was not present in this class. */
+  public void removeField(Field field) {
+    if (nameToFieldMap.remove(field.getName()) == null) {
+      throw new RuntimeException("field of name \"" + field.getName() + "\" was not present");
+    }
+    fieldList.remove(field);
+  }
+}