private void markAndTraverse(final Oop obj) {

    // End of path
    if (obj == null) {
      return;
    }

    // Visited object
    if (!markBits.mark(obj)) {
      return;
    }

    // Root of work list for objects to be visited.  A simple
    // stack for saving new objects to be analyzed.

    final Stack workList = new Stack();

    // Next object to be visited.
    Oop next = obj;

    try {
      // Node in the list currently being visited.

      while (true) {
        final Oop currObj = next;

        // For the progress meter
        if (progressThunk != null) {
          visitedSize += currObj.getObjectSize();
          double curFrac = (double) visitedSize / (double) usedSize;
          if (curFrac > lastNotificationFraction + MINIMUM_NOTIFICATION_FRACTION) {
            progressThunk.heapIterationFractionUpdate(curFrac);
            lastNotificationFraction = curFrac;
          }
        }

        if (DEBUG) {
          ++depth;
          printHeader();
          System.err.println("ReversePtrs.markAndTraverse(" + currObj.getHandle() + ")");
        }

        // Iterate over the references in the object.  Do the
        // reverse pointer analysis for each reference.
        // Add the reference to the work-list so that its
        // references will be visited.
        currObj.iterate(
            new DefaultOopVisitor() {
              public void doOop(OopField field, boolean isVMField) {
                // "field" refers to a reference in currObj
                Oop next = field.getValue(currObj);
                rp.put(new LivenessPathElement(currObj, field.getID()), next);
                if ((next != null) && markBits.mark(next)) {
                  workList.push(next);
                }
              }
            },
            false);

        if (DEBUG) {
          --depth;
        }

        // Get the next object to visit.
        next = (Oop) workList.pop();
      }
    } catch (EmptyStackException e) {
      // Done
    } catch (NullPointerException e) {
      System.err.println("ReversePtrs: WARNING: " + e + " during traversal");
    } catch (Exception e) {
      System.err.println("ReversePtrs: WARNING: " + e + " during traversal");
    }
  }