diff agent/src/share/classes/sun/jvm/hotspot/runtime/RegisterMap.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/RegisterMap.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2000-2006 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.runtime;
+
+import java.io.*;
+import java.util.*;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.interpreter.*;
+import sun.jvm.hotspot.code.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+/** <P> A companion structure used for stack traversal. The
+    RegisterMap contains misc. information needed in order to do
+    correct stack traversal of stack frames.  Hence, it must always be
+    passed in as an argument to Frame.sender(RegisterMap). </P>
+
+    <P> The use of RegisterMaps is slightly different in the
+    Serviceability Agent APIs than in the VM itself. In the VM, a
+    RegisterMap is created either for a particular thread or cloned
+    from another RegisterMap. In these APIs, a JavaThread is the
+    top-level factory for RegisterMaps, and RegisterMaps know how to
+    copy themselves (through either the clone() or copy()
+    methods). </P> */
+
+public abstract class RegisterMap implements Cloneable {
+  /** Location of registers */
+  protected Address[]  location;
+  // FIXME: don't know about LocationValidType
+  protected long[]     locationValid;
+  /** Should include argument_oop marked locations for compiler */
+  protected boolean    includeArgumentOops;
+  /** Reference to current thread */
+  protected JavaThread thread;
+  /** Tells if the register map needs to be updated when traversing the stack */
+  protected boolean    updateMap;
+  /** Location of a frame where the pc is not at a call (NULL if no frame exists) */
+  protected static int regCount;
+  protected static int locationValidTypeSize;
+  protected static int locationValidSize;
+
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static void initialize(TypeDataBase db) {
+    regCount = db.lookupIntConstant("ConcreteRegisterImpl::number_of_registers").intValue();
+    // FIXME: don't know about LocationValidType. The LocationValidType is typedef'ed as julong
+    // so used julong to get the size of LocationValidType.
+    locationValidTypeSize = (int)db.lookupType("julong").getSize() * 8;
+    locationValidSize = (regCount + locationValidTypeSize - 1) / locationValidTypeSize;
+  }
+
+  protected RegisterMap(JavaThread thread, boolean updateMap) {
+    this.thread    = thread;
+    this.updateMap = updateMap;
+    location      = new Address[regCount];
+    locationValid = new long[locationValidSize];
+    clear();
+  }
+
+  /** Makes a copy of map into this */
+  protected RegisterMap(RegisterMap map) {
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(map != null, "RegisterMap must be present");
+    }
+    this.thread              = map.getThread();
+    this.updateMap           = map.getUpdateMap();
+    this.includeArgumentOops = map.getIncludeArgumentOops();
+    location                 = new Address[map.location.length];
+    locationValid            = new long[map.locationValid.length];
+    initializeFromPD(map);
+    if (updateMap) {
+      for (int i = 0; i < locationValidSize; i++) {
+        long bits = (!getUpdateMap()) ? 0 : map.locationValid[i];
+        locationValid[i] = bits;
+        // for whichever bits are set, pull in the corresponding map->_location
+        int j = i*locationValidTypeSize;
+        while (bits != 0) {
+          if ((bits & 1) != 0) {
+            if (Assert.ASSERTS_ENABLED) {
+              Assert.that(0 <= j && j < regCount, "range check");
+            }
+            location[j] = map.location[j];
+          }
+          bits >>>= 1;
+          j += 1;
+        }
+      }
+    }
+  }
+
+  public abstract Object clone();
+
+  public RegisterMap copy() {
+    return (RegisterMap) clone();
+  }
+
+  public void clear() {
+    setIncludeArgumentOops(true);
+    if (!VM.getVM().isCore()) {
+      if (updateMap) {
+        for (int i = 0; i < locationValid.length; i++) {
+          locationValid[i] = 0;
+        }
+        clearPD();
+      } else {
+        initializePD();
+      }
+    }
+  }
+
+  public Address getLocation(VMReg reg) {
+    int i = reg.getValue();
+    int index = i / locationValidTypeSize;
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(0 <= i && i < regCount, "sanity check");
+      Assert.that(0 <= index && index < locationValidSize, "sanity check");
+    }
+    if ((locationValid[index] & (1 << i % locationValidTypeSize)) != 0) {
+      return location[i];
+    } else {
+      return getLocationPD(reg);
+    }
+  }
+
+  public void setLocation(VMReg reg, Address loc) {
+    int i = reg.getValue();
+    int index = i / locationValidTypeSize;
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(0 <= i && i < regCount, "sanity check");
+      Assert.that(0 <= index && index < locationValidSize, "sanity check");
+      Assert.that(updateMap, "updating map that does not need updating");
+    }
+    location[i]          = loc;
+    locationValid[index] |= (1 << (i % locationValidTypeSize));
+  }
+
+  public boolean getIncludeArgumentOops() {
+    return includeArgumentOops;
+  }
+
+  public void setIncludeArgumentOops(boolean f) {
+    includeArgumentOops = f;
+  }
+
+  public JavaThread getThread() {
+    return thread;
+  }
+
+  public boolean getUpdateMap() {
+    return updateMap;
+  }
+
+  public void print() {
+    printOn(System.out);
+  }
+
+  public void printOn(PrintStream tty) {
+    tty.println("Register map");
+    for (int i = 0; i < location.length; i++) {
+      Address src = getLocation(new VMReg(i));
+      if (src != null) {
+        tty.print("  " + VMRegImpl.getRegisterName(i) +
+                  " [" + src + "] = ");
+        if (src.andWithMask(VM.getVM().getAddressSize() - 1) != null) {
+          tty.print("<misaligned>");
+        } else {
+          tty.print(src.getAddressAt(0));
+        }
+      }
+    }
+  }
+
+  /** Platform-dependent clear() functionality */
+  protected abstract void clearPD();
+  /** Platform-dependent initialize() functionality */
+  protected abstract void initializePD();
+  /** Platform-dependent initializeFrom() functionality */
+  protected abstract void initializeFromPD(RegisterMap map);
+  /** Platform-dependent getLocation() functionality */
+  protected abstract Address getLocationPD(VMReg reg);
+}