diff agent/src/share/classes/sun/jvm/hotspot/debugger/cdbg/basic/BasicLineNumberMapping.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/debugger/cdbg/basic/BasicLineNumberMapping.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2001 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.debugger.cdbg.basic;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.*;
+import sun.jvm.hotspot.utilities.AddressOps;
+
+public class BasicLineNumberMapping {
+  private List infoList;
+
+  public BasicLineNumberMapping() {
+  }
+
+  /** Add line number information for the given PC. The end PC may be
+      a very loose approximation (i.e., the end of the given DLL) if
+      that information is not available in the debug information.
+      recomputeEndPCs() will recompute them if needed. */
+  public void addLineNumberInfo(BasicLineNumberInfo info) {
+    if (infoList == null) {
+      infoList = new ArrayList();
+    }
+    infoList.add(info);
+  }
+
+  /** Sort the line number information by increasing starting program
+      counter. This must be done before any queries are made. */
+  public void sort() {
+    if (infoList == null) return;
+    Collections.sort(infoList, new Comparator() {
+        public int compare(Object o1, Object o2) {
+          BasicLineNumberInfo l1 = (BasicLineNumberInfo) o1;
+          BasicLineNumberInfo l2 = (BasicLineNumberInfo) o2;
+          Address a1 = l1.getStartPC();
+          Address a2 = l2.getStartPC();
+          if (AddressOps.lt(a1, a2)) { return -1; }
+          if (AddressOps.gt(a1, a2)) { return 1; }
+          return 0;
+        }
+      });
+  }
+
+  /** Recomputes the ending PCs of each interval based on the starting
+      PC of the next one. If this needs to be called, must be called
+      after sort(). */
+  public void recomputeEndPCs() {
+    if (infoList == null) return;
+    for (int i = 0; i < infoList.size() - 1; i++) {
+      BasicLineNumberInfo i1 = get(i);
+      BasicLineNumberInfo i2 = get(i + 1);
+      i1.setEndPC(i2.getStartPC());
+    }
+  }
+
+  public BasicLineNumberInfo lineNumberForPC(Address pc) throws DebuggerException {
+    if (infoList == null) return null;
+    return searchLineNumbers(pc, 0, infoList.size() - 1);
+  }
+
+  public void iterate(LineNumberVisitor v) {
+    if (infoList == null) return;
+    for (int i = 0; i < infoList.size(); i++) {
+      v.doLineNumber(get(i));
+    }
+  }
+
+  //----------------------------------------------------------------------
+  // Internals only below this point
+  //
+
+  private BasicLineNumberInfo get(int i) {
+    return (BasicLineNumberInfo) infoList.get(i);
+  }
+
+  private BasicLineNumberInfo searchLineNumbers(Address addr, int lowIdx, int highIdx) {
+    if (highIdx < lowIdx) return null;
+    if (lowIdx == highIdx) {
+      // Base case: see whether start PC is less than or equal to addr
+      if (check(addr, lowIdx)) {
+        return get(lowIdx);
+      } else {
+        return null;
+      }
+    } else if (lowIdx == highIdx - 1) {
+      if (check(addr, lowIdx)) {
+        return get(lowIdx);
+      } else if (check(addr, highIdx)) {
+        return get(highIdx);
+      } else {
+        return null;
+      }
+    }
+    int midIdx = (lowIdx + highIdx) >> 1;
+    BasicLineNumberInfo info = get(midIdx);
+    if (AddressOps.lt(addr, info.getStartPC())) {
+      // Always move search down
+      return searchLineNumbers(addr, lowIdx, midIdx);
+    } else if (AddressOps.equal(addr, info.getStartPC())) {
+      return info;
+    } else {
+      // Move search up
+      return searchLineNumbers(addr, midIdx, highIdx);
+    }
+  }
+
+  private boolean check(Address addr, int idx) {
+    BasicLineNumberInfo info = get(idx);
+    if (AddressOps.lte(info.getStartPC(), addr)) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+}