src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java
author erikj
Tue, 12 Sep 2017 19:03:39 +0200
changeset 47216 71c04702a3d5
parent 46729 hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java@c62d2e8b2728
child 48787 7638bf98a312
permissions -rw-r--r--
8187443: Forest Consolidation: Move files to unified layout Reviewed-by: darcy, ihse
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
46729
c62d2e8b2728 7133093: Improve system dictionary performance
coleenp
parents: 35217
diff changeset
     2
 * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 670
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 670
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 670
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
package sun.jvm.hotspot.utilities;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
import java.io.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
import java.util.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
import sun.jvm.hotspot.debugger.*;
46729
c62d2e8b2728 7133093: Improve system dictionary performance
coleenp
parents: 35217
diff changeset
    30
import sun.jvm.hotspot.classfile.*;
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 13728
diff changeset
    31
import sun.jvm.hotspot.gc.shared.*;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
import sun.jvm.hotspot.memory.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
import sun.jvm.hotspot.oops.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
import sun.jvm.hotspot.runtime.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
import sun.jvm.hotspot.utilities.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
/** For a set of known roots, descends recursively into the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
    graph, for each object recording those objects (and their fields)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
    which point to it. NOTE: currently only a subset of the roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
    known to the VM is exposed to the SA: objects on the stack, static
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
    fields in classes, and JNI handles. These should be most of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
    user-level roots keeping objects alive. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
public class ReversePtrsAnalysis {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  // Used for debugging this code
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  private static final boolean DEBUG = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  public ReversePtrsAnalysis() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  /** Sets an optional progress thunk */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  public void setHeapProgressThunk(HeapProgressThunk thunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
    progressThunk = thunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  /** Runs the analysis algorithm */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  public void run() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
    if (VM.getVM().getRevPtrs() != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
      return; // Assume already done
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
    VM vm = VM.getVM();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
    rp = new ReversePtrs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
    vm.setRevPtrs(rp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
    Universe universe = vm.getUniverse();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
    CollectedHeap collHeap = universe.heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    usedSize = collHeap.used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
    visitedSize = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
    // Note that an experiment to iterate the heap linearly rather
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
    // than in recursive-descent order has been done. It turns out
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
    // that the recursive-descent algorithm is nearly twice as fast
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
    // due to the fact that it scans only live objects and (currently)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
    // only a fraction of the perm gen, namely the static fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
    // contained in instanceKlasses. (Iterating the heap linearly
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
    // would also change the semantics of the result so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
    // ReversePtrs.get() would return a non-null value even for dead
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
    // objects.) Nonetheless, the reverse pointer computation is still
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
    // quite slow and optimization in field iteration of objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
    // should be done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    if (progressThunk != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
      // Get it started
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
      progressThunk.heapIterationFractionUpdate(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
    // Allocate mark bits for heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
    markBits = new MarkBits(collHeap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    // Get a hold of the object heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    heap = vm.getObjectHeap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    // Do each thread's roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    for (JavaThread thread = VM.getVM().getThreads().first();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
         thread != null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
         thread = thread.next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
      thread.printThreadIDOn(new PrintStream(bos));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
      String threadDesc =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
        " in thread \"" + thread.getThreadName() +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
        "\" (id " + bos.toString() + ")";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
      doStack(thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
              new RootVisitor("Stack root" + threadDesc));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
      doJNIHandleBlock(thread.activeHandles(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
                       new RootVisitor("JNI handle root" + threadDesc));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
    // Do global JNI handles
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    JNIHandles handles = VM.getVM().getJNIHandles();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    doJNIHandleBlock(handles.globalHandles(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
                     new RootVisitor("Global JNI handle root"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    doJNIHandleBlock(handles.weakGlobalHandles(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
                     new RootVisitor("Weak global JNI handle root"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 8878
diff changeset
   116
    // Do Java-level static fields
46729
c62d2e8b2728 7133093: Improve system dictionary performance
coleenp
parents: 35217
diff changeset
   117
    ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
c62d2e8b2728 7133093: Improve system dictionary performance
coleenp
parents: 35217
diff changeset
   118
    cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 8878
diff changeset
   119
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 8878
diff changeset
   120
            public void visit(Klass k) {
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 8878
diff changeset
   121
                if (k instanceof InstanceKlass) {
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 8878
diff changeset
   122
                    final InstanceKlass ik = (InstanceKlass)k;
8878
a6283814032c 7031614: jmap -permstat fails with java.lang.InternalError in sun.jvm.hotspot.oops.OopField.getValue
never
parents: 5547
diff changeset
   123
            ik.iterateStaticFields(
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
               new DefaultOopVisitor() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
                   public void doOop(OopField field, boolean isVMField) {
8878
a6283814032c 7031614: jmap -permstat fails with java.lang.InternalError in sun.jvm.hotspot.oops.OopField.getValue
never
parents: 5547
diff changeset
   126
                     Oop next = field.getValue(getObj());
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 8878
diff changeset
   127
                                                   NamedFieldIdentifier nfi = new NamedFieldIdentifier("Static field \"" +
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
                                                field.getID().getName() +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
                                                "\" in class \"" +
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 8878
diff changeset
   130
                                                                                                       ik.getName().asString() + "\"");
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 8878
diff changeset
   131
                                                   LivenessPathElement lp = new LivenessPathElement(null, nfi);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
                     rp.put(lp, next);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
                     try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
                       markAndTraverse(next);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
                     } catch (AddressException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
                       System.err.print("RevPtrs analysis: WARNING: AddressException at 0x" +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
                                        Long.toHexString(e.getAddress()) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
                                        " while traversing static fields of InstanceKlass ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
                       ik.printValueOn(System.err);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
                       System.err.println();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
                     } catch (UnknownOopException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
                       System.err.println("RevPtrs analysis: WARNING: UnknownOopException while " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
                                          "traversing static fields of InstanceKlass ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
                       ik.printValueOn(System.err);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
                       System.err.println();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
                     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
                   }
8878
a6283814032c 7031614: jmap -permstat fails with java.lang.InternalError in sun.jvm.hotspot.oops.OopField.getValue
never
parents: 5547
diff changeset
   148
                 });
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
      });
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
    if (progressThunk != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
      progressThunk.heapIterationComplete();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
    // Clear out markBits
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    markBits = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  //---------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  // Internals only below this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  private HeapProgressThunk   progressThunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  private long                usedSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  private long                visitedSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  private double              lastNotificationFraction;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  private static final double MINIMUM_NOTIFICATION_FRACTION = 0.01;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  private ObjectHeap          heap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  private MarkBits            markBits;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  private int                 depth; // Debugging only
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  private ReversePtrs         rp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  private void markAndTraverse(OopHandle handle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
      markAndTraverse(heap.newOop(handle));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
    } catch (AddressException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
      System.err.println("RevPtrs analysis: WARNING: AddressException at 0x" +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
                         Long.toHexString(e.getAddress()) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
                         " while traversing oop at " + handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    } catch (UnknownOopException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
      System.err.println("RevPtrs analysis: WARNING: UnknownOopException for " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
                         "oop at " + handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  private void printHeader() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
    for (int i = 0; i < depth; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
      System.err.print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  private void markAndTraverse(final Oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
    // End of path
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    if (obj == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
    // Visited object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    if (!markBits.mark(obj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
    // Root of work list for objects to be visited.  A simple
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
    // stack for saving new objects to be analyzed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    final Stack workList = new Stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
    // Next object to be visited.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    Oop next = obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
      // Node in the list currently being visited.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
      while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
        final Oop currObj = next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
        // For the progress meter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
        if (progressThunk != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
          visitedSize += currObj.getObjectSize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
          double curFrac = (double) visitedSize / (double) usedSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
          if (curFrac >
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
              lastNotificationFraction + MINIMUM_NOTIFICATION_FRACTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
            progressThunk.heapIterationFractionUpdate(curFrac);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
            lastNotificationFraction = curFrac;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
        if (DEBUG) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
          ++depth;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
          printHeader();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
          System.err.println("ReversePtrs.markAndTraverse(" +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
              currObj.getHandle() + ")");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
        // Iterate over the references in the object.  Do the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
        // reverse pointer analysis for each reference.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
        // Add the reference to the work-list so that its
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
        // references will be visited.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
        currObj.iterate(new DefaultOopVisitor() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
          public void doOop(OopField field, boolean isVMField) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
            // "field" refers to a reference in currObj
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
            Oop next = field.getValue(currObj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
            rp.put(new LivenessPathElement(currObj, field.getID()), next);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
            if ((next != null) && markBits.mark(next)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
              workList.push(next);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
        }, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
        if (DEBUG) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
          --depth;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
        // Get the next object to visit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
        next = (Oop) workList.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
    } catch (EmptyStackException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
      // Done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    } catch (NullPointerException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
      System.err.println("ReversePtrs: WARNING: " + e +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
        " during traversal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
    } catch (Exception e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
      System.err.println("ReversePtrs: WARNING: " + e +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
        " during traversal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
  class RootVisitor implements AddressVisitor {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
    RootVisitor(String baseRootDescription) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
      this.baseRootDescription = baseRootDescription;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
    public void visitAddress(Address addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
      Oop next = heap.newOop(addr.getOopHandleAt(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
      LivenessPathElement lp = new LivenessPathElement(null,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
                                        new NamedFieldIdentifier(baseRootDescription +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
                                                                 " @ " + addr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
      rp.put(lp, next);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
      markAndTraverse(next);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   286
    public void visitCompOopAddress(Address addr) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   287
      Oop next = heap.newOop(addr.getCompOopHandleAt(0));
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   288
      LivenessPathElement lp = new LivenessPathElement(null,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   289
                                        new NamedFieldIdentifier(baseRootDescription +
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   290
                                                                 " @ " + addr));
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   291
      rp.put(lp, next);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   292
      markAndTraverse(next);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   293
    }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   294
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
    private String baseRootDescription;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  // Traverse the roots on a given thread's stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  private void doStack(JavaThread thread, AddressVisitor oopVisitor) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
    for (StackFrameStream fst = new StackFrameStream(thread); !fst.isDone(); fst.next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
      fst.getCurrent().oopsDo(oopVisitor, fst.getRegisterMap());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
  // Traverse a JNIHandleBlock
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  private void doJNIHandleBlock(JNIHandleBlock handles, AddressVisitor oopVisitor) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
    handles.oopsDo(oopVisitor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
}