Ejemplo n.º 1
0
  public IResult execute(IProgressListener listener) throws Exception {
    int[] retainedSet;

    if (fieldNames == null)
      retainedSet = snapshot.getRetainedSet(objects.getIds(listener), listener);
    else retainedSet = snapshot.getRetainedSet(objects.getIds(listener), fieldNames, listener);

    if (listener.isCanceled()) throw new IProgressListener.OperationCanceledException();

    Histogram histogram = snapshot.getHistogram(retainedSet, listener);

    if (listener.isCanceled()) throw new IProgressListener.OperationCanceledException();

    histogram.setLabel(
        MessageUtil.format(Messages.RetainedSetQuery_RetainedBy, objects.getLabel()));
    return histogram;
  }
  @Override
  public int[] extractEntryIds(IObject list) throws SnapshotException {
    IProgressListener listener = new VoidProgressListener();
    // If there isn't a size, then use an upper limit in case there is a loop
    int size = super.hasSize() ? getSize(list) : 10000000;

    String taskMsg =
        MessageUtil.format(
            Messages.ExtractListValuesQuery_CollectingElements, size, list.getTechnicalName());
    listener.beginTask(taskMsg, size);

    ArrayInt result = new ArrayInt();
    int loopingLimit = size;

    IObject header = (IObject) list.resolveValue("header"); // LinkedList$Header //$NON-NLS-1$
    if (header == null)
      header = (IObject) list.resolveValue("voidLink"); // LinkedList$Link IBM VM //$NON-NLS-1$
    if (header == null)
      header = (IObject) list.resolveValue("first"); // LinkedList$Node Java 7 //$NON-NLS-1$
    if (header == null) {}

    if (header == null) {
      // Look for the only object field
      header = resolveNextFields(list);
    }
    if (header == null) return null;

    IObject previous = header;
    IObject current = header;

    if (current.getClazz().getName().equals("java.util.LinkedList$Entry")
        || //$NON-NLS-1$
        current.getClazz().getName().equals("java.util.LinkedList$Link")
        || //$NON-NLS-1$
        current
            .getClazz()
            .getName()
            .equals("java.util.concurrent.LinkedBlockingQueue$Node")) // $NON-NLS-1$
    {
      // Skip over header link for pre Java 7 implementations
      current = (IObject) header.resolveValue("next"); // $NON-NLS-1$;
      if (current == null) {
        // Try without using field names
        final ISnapshot snapshot = header.getSnapshot();
        for (int i : snapshot.getOutboundReferentIds(header.getObjectId())) {
          IObject o = snapshot.getObject(i);
          // Exclude the class
          if (i != header.getClazz().getObjectId()) {
            if (o.getClazz().equals(header.getClazz())) {
              // same type as header, so possible next field
              // don't care whether we get current or previous -
              // just circle the wrong way
              current = o;
              break;
            }
          }
        }
      }
    } else {
      header = null;
    }

    while (current != null && current != header && loopingLimit-- > 0) {
      // Find the element
      IObject ref = (IObject) current.resolveValue("element"); // $NON-NLS-1$
      if (ref == null) ref = (IObject) current.resolveValue("data"); // IBM VM //$NON-NLS-1$
      if (ref == null) ref = (IObject) current.resolveValue("item"); // Java 7 //$NON-NLS-1$
      if (current.equals(ref)) {
        // java.util.concurrent.LinkedTransferQueue has a spurious link
        ref = null;
      }

      // Find the next link
      IObject next = (IObject) current.resolveValue("next"); // $NON-NLS-1$

      if (next == null) {
        // Try without using field names
        final ISnapshot snapshot = current.getSnapshot();
        for (int i : snapshot.getOutboundReferentIds(current.getObjectId())) {
          IObject o = snapshot.getObject(i);
          // Exclude the previous field and the class
          if (i != previous.getObjectId() && i != current.getClazz().getObjectId()) {
            if (o.getClazz().equals(current.getClazz())) {
              // same type as current, so possible next field
              if (next != null) {
                // Uncertain, so give up
                next = null;
                break;
              }
              next = o;
            } else {
              // possible element
              if (ref == null) ref = o;
            }
          }
        }
      }

      if (ref != null) result.add(ref.getObjectId());
      previous = current;
      current = next;
      listener.worked(1);
      // If the user cancels then just return what we have got so far
      if (listener.isCanceled()) break;
    }

    listener.done();

    return result.toArray();
  }