diff agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java @ 3939:f6f3bb0ee072

7088955: add C2 IR support to the SA Reviewed-by: kvn
author never
date Sun, 11 Sep 2011 14:48:24 -0700
parents c18cbe5936b8
children 117bb0519114
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java	Sat Sep 10 17:29:02 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java	Sun Sep 11 14:48:24 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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
@@ -150,6 +150,19 @@
     return VM.getVM().getOopSize();
   }
 
+  static HashMap typeToVtbl = new HashMap();
+
+  private Address vtblForType(Type type) {
+    Address vtblAddr = (Address)typeToVtbl.get(type);
+    if (vtblAddr == null) {
+      vtblAddr = vtblAccess.getVtblForType(type);
+      if (vtblAddr != null) {
+        typeToVtbl.put(type, vtblAddr);
+      }
+    }
+    return vtblAddr;
+  }
+
   public boolean addressTypeIsEqualToType(Address addr, Type type) {
     if (addr == null) {
       return false;
@@ -158,7 +171,7 @@
     // This implementation should be suitably platform-independent; we
     // search nearby memory for the vtbl value of the given type.
 
-    Address vtblAddr = vtblAccess.getVtblForType(type);
+    Address vtblAddr = vtblForType(type);
 
     if (vtblAddr == null) {
       // Type was not polymorphic, or an error occurred during lookup
@@ -251,6 +264,78 @@
     return false;
   }
 
+  public Type findDynamicTypeForAddress(Address addr, Type baseType) {
+    // This implementation should be suitably platform-independent; we
+    // search nearby memory for the vtbl value of the given type.
+
+    if (vtblForType(baseType) == null) {
+      // Type was not polymorphic which is an error of some sort
+      throw new InternalError(baseType + " does not appear to be polymorphic");
+    }
+
+    // This is a more restricted version of guessTypeForAddress since
+    // that function has some limitations since it doesn't really know
+    // where in the hierarchy a virtual type starts and just poking
+    // around in memory is likely to trip over some vtable address,
+    // resulting in false positives.  Eventually all uses should
+    // switch to this logic but in the interests of stability it will
+    // be separate for the moment.
+
+    // Assuming that the base type is truly the first polymorphic type
+    // then the vtbl for all subclasss should be at several defined
+    // locations so only those locations will be checked.  It's also
+    // required that the caller knows that the static type is at least
+    // baseType.  See the notes in guessTypeForAddress for the logic of
+    // the locations searched.
+
+    Address loc1 = addr.getAddressAt(0);
+    Address loc2 = null;
+    Address loc3 = null;
+    long offset2 = baseType.getSize();
+    // I don't think this should be misaligned under any
+    // circumstances, but I'm not sure (FIXME: also not sure which
+    // way to go here, up or down -- assuming down)
+    offset2 = offset2 - (offset2 % getAddressSize()) - getAddressSize();
+    if (offset2 > 0) {
+      loc2 = addr.getAddressAt(offset2);
+    }
+    long offset3 = offset2 - getAddressSize();
+    if (offset3 > 0) {
+      loc3 = addr.getAddressAt(offset3);
+    }
+
+    Type loc2Match = null;
+    Type loc3Match = null;
+    for (Iterator iter = getTypes(); iter.hasNext(); ) {
+      Type type = (Type) iter.next();
+      Type superClass = type;
+      while (superClass != baseType && superClass != null) {
+        superClass = superClass.getSuperclass();
+      }
+      if (superClass == null) continue;
+      Address vtblAddr = vtblForType(type);
+      if (vtblAddr == null) {
+        // This occurs sometimes for intermediate types that are never
+        // instantiated.
+        if (DEBUG) {
+          System.err.println("null vtbl for " + type);
+        }
+        continue;
+      }
+      // Prefer loc1 match
+      if (vtblAddr.equals(loc1)) return type;
+      if (loc2 != null && loc2Match == null && vtblAddr.equals(loc2)) {
+          loc2Match = type;
+      }
+      if (loc3 != null && loc3Match == null && vtblAddr.equals(loc3)) {
+          loc3Match = type;
+      }
+    }
+    if (loc2Match != null) return loc2Match;
+    if (loc3Match != null) return loc3Match;
+    return null;
+  }
+
   public Type guessTypeForAddress(Address addr) {
     for (Iterator iter = getTypes(); iter.hasNext(); ) {
       Type t = (Type) iter.next();