### Eclipse Workspace Patch 1.0 #P org.eclipse.mat.api Index: src/org/eclipse/mat/inspections/ReachableSetQuery.java =================================================================== --- src/org/eclipse/mat/inspections/ReachableSetQuery.java (revision 0) +++ src/org/eclipse/mat/inspections/ReachableSetQuery.java (revision 0) @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2010 SAP AG. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * SAP AG - initial API and implementation + *******************************************************************************/ +package org.eclipse.mat.inspections; + +import org.eclipse.mat.query.IQuery; +import org.eclipse.mat.query.IResult; +import org.eclipse.mat.query.annotations.Argument; +import org.eclipse.mat.query.annotations.CommandName; +import org.eclipse.mat.snapshot.Histogram; +import org.eclipse.mat.snapshot.ISnapshot; +import org.eclipse.mat.snapshot.query.IHeapObjectArgument; +import org.eclipse.mat.util.IProgressListener; +import org.eclipse.mat.util.MessageUtil; + +@CommandName("show_reachable_set") +public class ReachableSetQuery implements IQuery +{ + @Argument + public ISnapshot snapshot; + + @Argument(flag = "none") + public IHeapObjectArgument objects; + + @Argument(isMandatory = false, flag = "f") + public String[] fieldNames; + + public IResult execute(IProgressListener listener) throws Exception + { + int[] reachableSet; + + reachableSet = snapshot.getReachableSet(objects.getIds(listener), listener); + + if (listener.isCanceled()) throw new IProgressListener.OperationCanceledException(); + + Histogram histogram = snapshot.getHistogram(reachableSet, listener); + + if (listener.isCanceled()) throw new IProgressListener.OperationCanceledException(); + + histogram.setLabel(MessageUtil.format("Reachable Set", objects.getLabel())); + return histogram; + } + +} Index: src/org/eclipse/mat/snapshot/ISnapshot.java =================================================================== --- src/org/eclipse/mat/snapshot/ISnapshot.java (revision 654) +++ src/org/eclipse/mat/snapshot/ISnapshot.java (working copy) @@ -324,6 +324,8 @@ public int[] getRetainedSet(int[] objectIds, ExcludedReferencesDescriptor[] excludedReferences, IProgressListener progressMonitor) throws SnapshotException; + + public int[] getReachableSet(int[] objectIds, IProgressListener progressListener) throws SnapshotException; /** * Calculate the minimum retained set of objects for the given objects Index: plugin.xml =================================================================== --- plugin.xml (revision 654) +++ plugin.xml (working copy) @@ -20,6 +20,7 @@ + #P org.eclipse.mat.parser Index: src/org/eclipse/mat/parser/internal/SnapshotImpl.java =================================================================== --- src/org/eclipse/mat/parser/internal/SnapshotImpl.java (revision 637) +++ src/org/eclipse/mat/parser/internal/SnapshotImpl.java (working copy) @@ -705,7 +705,7 @@ return retained.toArray(); } - + public int[] getRetainedSet(int[] objectIds, IProgressListener progressMonitor) throws SnapshotException { int availableProcessors = Runtime.getRuntime().availableProcessors(); @@ -802,6 +802,72 @@ } return retainedSet.toArray(); } + + public int[] getReachableSet(int[] objectIds, IProgressListener progressListener) throws SnapshotException + { + /* for empty initial set - return immediately an empty reachable set */ + if (objectIds.length == 0) { return new int[0]; } + + int numberOfObjects = snapshotInfo.getNumberOfObjects(); + + if (progressListener == null) + progressListener = new VoidProgressListener(); + + /* a 'bit field' to mark all reached objects */ + boolean[] reachable = new boolean[numberOfObjects]; + + /* + * The dfs() will start from the GC roots, follow the outbound + * references, and mark all unmarked objects. The reachable set will + * contain the marked objects + */ + ObjectMarker marker = new ObjectMarker(roots.getAllKeys(), reachable, indexManager.outbound(), progressListener); + try + { + int availableProcessors = Runtime.getRuntime().availableProcessors(); + if (availableProcessors > 1) + { + marker.markMultiThreaded(availableProcessors); + /* + * build the result in an IntArray - the exact number of marked is not + * known + */ + ArrayIntBig retained = new ArrayIntBig(); + + /* Put each unmarked object into the retained set */ + for (int i = 0; i < numberOfObjects; i++) + { + if (reachable[i]) + { + retained.add(i); + } + } + return retained.toArray(); + } + else + { + int numObjectsReached = marker.markSingleThreaded(); + int[] reachableSet = new int[numObjectsReached]; + int j = 0; + for (int i = 0; i < reachable.length; i++) + { + if (reachable[i]) + reachableSet[j++] = i; + } + return reachableSet; + } + } + catch (OperationCanceledException e) + { + // $JL-EXC$ + return null; + } + catch (InterruptedException e) + { + // $JL-EXC$ + return null; + } + } public long getMinRetainedSize(int[] objectIds, IProgressListener progressMonitor) throws UnsupportedOperationException, SnapshotException