< prev index next >

application/org.openjdk.jmc.flightrecorder.ui/src/main/java/org/openjdk/jmc/flightrecorder/ui/pages/ClassLoadingPage.java

Print this page

        

@@ -30,14 +30,20 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
  * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 package org.openjdk.jmc.flightrecorder.ui.pages;
 
+
+import static org.openjdk.jmc.common.item.ItemQueryBuilder.fromWhere;
+
 import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.resource.ImageDescriptor;

@@ -48,14 +54,15 @@
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.ui.forms.widgets.Form;
 import org.eclipse.ui.forms.widgets.FormToolkit;
-
+import org.openjdk.jmc.common.IMCClassLoader;
 import org.openjdk.jmc.common.IState;
 import org.openjdk.jmc.common.IWritableState;
 import org.openjdk.jmc.common.item.Aggregators;
+import org.openjdk.jmc.common.item.IAggregator;
 import org.openjdk.jmc.common.item.IAttribute;
 import org.openjdk.jmc.common.item.IItemCollection;
 import org.openjdk.jmc.common.item.IItemFilter;
 import org.openjdk.jmc.common.item.ItemFilters;
 import org.openjdk.jmc.common.item.RangeMatchPolicy;

@@ -129,10 +136,12 @@
         private static final IItemFilter TABLE_FILTER = ItemFilters.or(JdkQueries.CLASS_LOAD.getFilter(),
                         JdkQueries.CLASS_UNLOAD.getFilter());
         private static final ItemHistogramBuilder CLASSLOADER_HISTOGRAM = new ItemHistogramBuilder();
         private static final ItemListBuilder CLASS_LOADING_LIST = new ItemListBuilder();
         private static final ItemListBuilder CLASS_UNLOADING_LIST = new ItemListBuilder();
+        private static final ItemListBuilder CLASS_DEFINE_LIST = new ItemListBuilder();
+        private static final ItemListBuilder CLASS_LOADER_STATISTICS_LIST = new ItemListBuilder();
         private static final Map<String, Boolean> LEGEND_ITEMS = new LinkedHashMap<>();
         private static final String LOADED_COUNT = "loadedCount"; //$NON-NLS-1$
         private static final String UNLOADED_COUNT = "unloadedCount"; //$NON-NLS-1$
         private static final String CLASS_LOAD = "classLoad"; //$NON-NLS-1$
         private static final String CLASS_UNLOAD = "classUnload"; //$NON-NLS-1$

@@ -152,15 +161,31 @@
                 CLASS_LOADING_LIST.addColumn(JdkAttributes.CLASS_INITIATING_CLASSLOADER);
                 CLASS_LOADING_LIST.addColumn(JfrAttributes.START_TIME);
                 CLASS_LOADING_LIST.addColumn(JfrAttributes.DURATION);
                 CLASS_LOADING_LIST.addColumn(JfrAttributes.END_TIME);
                 CLASS_LOADING_LIST.addColumn(JfrAttributes.EVENT_THREAD);
+                
                 CLASS_UNLOADING_LIST.addColumn(JfrAttributes.EVENT_TIMESTAMP);
                 CLASS_UNLOADING_LIST.addColumn(JfrAttributes.EVENT_THREAD);
                 CLASS_UNLOADING_LIST.addColumn(JdkAttributes.CLASS_UNLOADED);
                 CLASS_UNLOADING_LIST.addColumn(JdkAttributes.CLASS_DEFINING_CLASSLOADER);
 
+                CLASS_DEFINE_LIST.addColumn(JfrAttributes.START_TIME);
+                CLASS_DEFINE_LIST.addColumn(JdkAttributes.CLASS_DEFINING_CLASSLOADER);
+                CLASS_DEFINE_LIST.addColumn(JdkAttributes.CLASS_DEFINED);
+                CLASS_DEFINE_LIST.addColumn(JfrAttributes.EVENT_THREAD);
+                
+                CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.ANONYMOUS_BLOCK_SIZE);
+                CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.ANONYMOUS_CHUNK_SIZE);
+                CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.ANONYMOUS_CLASS_COUNT);
+                CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.BLOCK_SIZE);
+                CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.CHUNK_SIZE);
+                CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.CLASS_COUNT);
+                CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.CLASS_LOADER_DATA);
+                CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.PARENT_CLASSLOADER);
+                CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.CLASSLOADER);
+                CLASS_LOADER_STATISTICS_LIST.addColumn(JfrAttributes.START_TIME);
                 // FIXME: Need to make a label provider for this
                 // FIXME: Want to have this in the same order
 
                 LEGEND_ITEMS.put(JdkAttributes.CLASSLOADER_LOADED_COUNT.getIdentifier(), Boolean.TRUE);
                 LEGEND_ITEMS.put(JdkAttributes.CLASSLOADER_UNLOADED_COUNT.getIdentifier(), Boolean.FALSE);

@@ -171,12 +196,16 @@
         private class ClassLoadingUi implements IPageUI {
 
                 private final ChartCanvas classLoadingChart;
                 private final ItemList classLoadingTable;
                 private final ItemList classUnloadingTable;
+                private final ItemList classDefineTable;
+                private final ItemList classLoaderStatisticsTable;
                 private FilterComponent classLoadingFilter;
                 private FilterComponent classUnloadingFilter;
+                private FilterComponent classDefineFilter;
+                private FilterComponent classLoaderStatisticsFilter;
                 private final SashForm sash;
                 private final IPageContainer pageContainer;
                 private IItemCollection selectionItems;
                 private ItemHistogram classloaderHistogram;
                 private FilterComponent classloaderHistogramFilter;

@@ -190,10 +219,11 @@
                                 .of(JdkAttributes.CLASSLOADER_LOADED_COUNT, JdkAttributes.CLASSLOADER_UNLOADED_COUNT)
                                 .map(a -> DataPageToolkit.createAttributeCheckAction(a, b -> updateChart()));
                 private final List<IAction> allChartSeriesActions = Stream
                                 .concat(Stream.of(classLoadAction, classUnloadAction), statsActions).collect(Collectors.toList());
                 private CTabFolder tabFolder;
+                private CTabFolder classloaderFolder;
                 private XYChart chart;
                 private IRange<IQuantity> timeRange;
                 private FlavorSelector flavorSelector;
 
                 ClassLoadingUi(Composite parent, FormToolkit toolkit, IPageContainer pageContainer, IState state) {

@@ -218,11 +248,13 @@
                         DataPageToolkit.setChart(classLoadingChart, chart, pageContainer::showSelection, this::onChartSelection);
                         SelectionStoreActionToolkit.addSelectionStoreRangeActions(pageContainer.getSelectionStore(), chart,
                                         JfrAttributes.LIFETIME, Messages.ClassLoadingPage_CLASS_LOADING_TIMELINE_SELECTION,
                                         classLoadingChart.getContextMenu());
 
-                        classloaderHistogram = CLASSLOADER_HISTOGRAM.buildWithoutBorder(sash,
+                        classloaderFolder = new CTabFolder(sash, SWT.NONE);
+
+                        classloaderHistogram = CLASSLOADER_HISTOGRAM.buildWithoutBorder(classloaderFolder,
                                         JdkAttributes.CLASS_DEFINING_CLASSLOADER, TableSettings.forState(state.getChild(HISTOGRAM)));
                         classloaderHistogramFilter = FilterComponent.createFilterComponent(classloaderHistogram, null,
                                         getDataSource().getItems().apply(JdkFilters.CLASS_LOAD_OR_UNLOAD),
                                         pageContainer.getSelectionStore()::getSelections, this::onHistogramFilterChange);
                         classloaderHistogram.getManager().getViewer().addSelectionChangedListener(

@@ -234,13 +266,42 @@
                                         classloaderHistogram, Messages.ClassLoadingPage_CLASS_LOADING_HISTOGRAM_SELECTION,
                                         classLoaderHistogramMm);
                         classLoaderHistogramMm.add(classloaderHistogramFilter.getShowFilterAction());
                         classLoaderHistogramMm.add(classloaderHistogramFilter.getShowSearchAction());
                         classloaderHistogramFilter.loadState(state.getChild(HISTOGRAM_FILTER));
+                        DataPageToolkit.addTabItem(classloaderFolder, classloaderHistogramFilter.getComponent(),
+                                        Messages.ClassLoadingPage_CLASS_LOADER_TAB);
 
                         ItemHistogramWithInput.chain(classloaderHistogram, this::updateTables);
 
+                        classLoaderStatisticsTable = CLASS_LOADER_STATISTICS_LIST.buildWithoutBorder(classloaderFolder,
+                                        TableSettings.forState(state.getChild(CLASS_LOADER_STATISTICS_TABLE)));
+                        classLoaderStatisticsTable.getManager().getViewer().addSelectionChangedListener(e -> {
+                                // The standard aggregators will skip the null classloader, so we need to do this manually.
+                                IItemCollection selection = ItemCollectionToolkit.build(classLoaderStatisticsTable.getSelection().get());
+                                Stream<IMCClassLoader> stream = ItemCollectionToolkit.values(selection, JdkAttributes.CLASSLOADER).get().distinct();
+                                Set<IMCClassLoader> selected = stream.collect(Collectors.toSet());
+                                IItemFilter selectionFilter =  ItemFilters.and(ItemFilters.or(JdkFilters.CLASS_LOAD_OR_UNLOAD,
+                                JdkFilters.CLASS_DEFINE), ItemFilters.memberOf(JdkAttributes.CLASS_DEFINING_CLASSLOADER, selected));
+                                IItemCollection filteredItems = getDataSource().getItems().apply(selectionFilter);
+                                pageContainer.showSelection(filteredItems);
+                                updateTables(filteredItems);
+                        });
+                        classLoaderStatisticsFilter = FilterComponent.createFilterComponent(classLoaderStatisticsTable, null,
+                                        getDataSource().getItems().apply(JdkFilters.CLASS_LOADER_STATISTICS),
+                                        pageContainer.getSelectionStore()::getSelections, this::onClassLoaderStatisticsFilterChange);
+                        MCContextMenuManager classLoaderStatisticsTableMm = MCContextMenuManager
+                                        .create(classLoaderStatisticsTable.getManager().getViewer().getControl());
+                        ColumnMenusFactory.addDefaultMenus(classLoaderStatisticsTable.getManager(), classLoaderStatisticsTableMm);
+                        SelectionStoreActionToolkit.addSelectionStoreActions(pageContainer.getSelectionStore(), classLoaderStatisticsTable,
+                                        Messages.ClassLoadingPage_CLASS_LOADER_STATISTICS_LIST_SELECTION, classLoaderStatisticsTableMm);
+                        classLoaderStatisticsTableMm.add(classLoaderStatisticsFilter.getShowFilterAction());
+                        classLoaderStatisticsTableMm.add(classLoaderStatisticsFilter.getShowSearchAction());
+                        classLoaderStatisticsFilter.loadState(state.getChild(CLASS_LOADER_STATISTICS_FILTER));
+                        DataPageToolkit.addTabItem(classloaderFolder, classLoaderStatisticsFilter.getComponent(),
+                                        Messages.ClassLoadingPage_CLASS_LOADER_STATISTICS_TAB_TITLE);
+
                         tabFolder = new CTabFolder(sash, SWT.NONE);
 
                         classLoadingTable = CLASS_LOADING_LIST.buildWithoutBorder(tabFolder,
                                         TableSettings.forState(state.getChild(CLASS_LOADING_TABLE)));
                         classLoadingTable.getManager().getViewer().addSelectionChangedListener(e -> pageContainer

@@ -257,10 +318,28 @@
                         classLoadingTableMm.add(classLoadingFilter.getShowSearchAction());
                         classLoadingFilter.loadState(state.getChild(CLASS_LOADING_FILTER));
                         DataPageToolkit.addTabItem(tabFolder, classLoadingFilter.getComponent(),
                                         Messages.ClassLoadingPage_CLASS_LOADING_TAB_TITLE);
 
+                        classDefineTable = CLASS_DEFINE_LIST.buildWithoutBorder(tabFolder,
+                                        TableSettings.forState(state.getChild(CLASS_DEFINE_TABLE)));
+                        classDefineTable.getManager().getViewer().addSelectionChangedListener(e -> pageContainer
+                                        .showSelection(ItemCollectionToolkit.build(classDefineTable.getSelection().get())));
+                        classDefineFilter = FilterComponent.createFilterComponent(classDefineTable, null,
+                                        getDataSource().getItems().apply(JdkFilters.CLASS_DEFINE),
+                                        pageContainer.getSelectionStore()::getSelections, this::onClassDefineFilterChange);
+                        MCContextMenuManager classDefineTableMm = MCContextMenuManager
+                                        .create(classDefineTable.getManager().getViewer().getControl());
+                        ColumnMenusFactory.addDefaultMenus(classDefineTable.getManager(), classDefineTableMm);
+                        SelectionStoreActionToolkit.addSelectionStoreActions(pageContainer.getSelectionStore(), classDefineTable,
+                                        Messages.ClassLoadingPage_CLASS_DEFINE_LIST_SELECTION, classDefineTableMm);
+                        classDefineTableMm.add(classDefineFilter.getShowFilterAction());
+                        classDefineTableMm.add(classDefineFilter.getShowSearchAction());
+                        classDefineFilter.loadState(state.getChild(CLASS_DEFINE_FILTER));
+                        DataPageToolkit.addTabItem(tabFolder, classDefineFilter.getComponent(),
+                                        Messages.ClassLoadingPage_CLASS_DEFINE_TAB_TITLE);
+
                         classUnloadingTable = CLASS_UNLOADING_LIST.buildWithoutBorder(tabFolder,
                                         TableSettings.forState(state.getChild(CLASS_UNLOADING_TABLE)));
                         classUnloadingTable.getManager().getViewer().addSelectionChangedListener(e -> pageContainer
                                         .showSelection(ItemCollectionToolkit.build(classUnloadingTable.getSelection().get())));
                         classUnloadingFilter = FilterComponent.createFilterComponent(classUnloadingTable, null,

@@ -276,34 +355,45 @@
                         classUnloadingFilter.loadState(state.getChild(CLASS_UNLOADING_FILTER));
                         DataPageToolkit.addTabItem(tabFolder, classUnloadingFilter.getComponent(),
                                         Messages.ClassLoadingPage_CLASS_UNLOADING_TAB_TITLE);
 
                         tabFolder.setSelection(tabFolderIndex);
+                        classloaderFolder.setSelection(tabFolderIndex);
 
                         PersistableSashForm.loadState(sash, state.getChild(SASH));
                         flavorSelector = FlavorSelector.itemsWithTimerange(form, TABLE_FILTER, getDataSource().getItems(),
                                         pageContainer, this::onInputSelected, this::onShow, flavorSelectorState);
                         addResultActions(form);
 
                         onHistogramFilterChange(histogramFilter);
                         onClassLoadFilterChange(classLoadTableFilter);
                         onClassUnloadFilterChange(classUnloadTableFilter);
+                        onClassDefineFilterChange(classDefineTableFilter);
+                        onClassLoaderStatisticsFilterChange(classLoaderStatisticsTableFilter);
 
                         classloaderHistogram.getManager().setSelectionState(histogramSelection);
                         classLoadingTable.getManager().setSelectionState(classLoadingTableSelection);
                         classUnloadingTable.getManager().setSelectionState(classUnloadingTableSelection);
+                        classDefineTable.getManager().setSelectionState(classDefineTableSelection);
+                        classLoaderStatisticsTable.getManager().setSelectionState(classLoaderStatisticsTableSelection);
                 }
 
                 private void onHistogramFilterChange(IItemFilter filter) {
                         classloaderHistogramFilter.filterChangeHelper(filter, classloaderHistogram,
-                                        getDataSource().getItems().apply(JdkFilters.CLASS_LOAD_OR_UNLOAD));
+                                        getDataSource().getItems().apply(ItemFilters.or(JdkFilters.CLASS_LOAD_OR_UNLOAD, JdkFilters.CLASS_DEFINE)));
                         if (classLoadingFilter != null) {
                                 classLoadingFilter.notifyListener();
                         }
                         if (classUnloadingFilter != null) {
                                 classUnloadingFilter.notifyListener();
                         }
+                        if (classDefineFilter != null) {
+                                classDefineFilter.notifyListener();
+                        }
+                        if (classLoaderStatisticsFilter != null) {
+                                classLoaderStatisticsFilter.notifyListener();
+                        }
                         histogramFilter = filter;
                 }
 
                 private void onClassLoadFilterChange(IItemFilter filter) {
                         classLoadingFilter.filterChangeHelper(filter, classLoadingTable,

@@ -315,28 +405,46 @@
                         classUnloadingFilter.filterChangeHelper(filter, classUnloadingTable,
                                         getDataSource().getItems().apply(JdkFilters.CLASS_UNLOAD));
                         classUnloadTableFilter = filter;
                 }
 
+                private void onClassDefineFilterChange(IItemFilter filter) {
+                        classDefineFilter.filterChangeHelper(filter, classDefineTable,
+                                        getDataSource().getItems().apply(JdkFilters.CLASS_DEFINE));
+                        classDefineTableFilter = filter;
+                }
+                
+                private void onClassLoaderStatisticsFilterChange(IItemFilter filter) {
+                        classLoaderStatisticsFilter.filterChangeHelper(filter, classLoaderStatisticsTable,
+                                        getDataSource().getItems().apply(JdkFilters.CLASS_LOADER_STATISTICS));
+                        classLoaderStatisticsTableFilter = filter;
+                }
+        
                 @Override
                 public void saveTo(IWritableState state) {
                         PersistableSashForm.saveState(sash, state.createChild(SASH));
                         classloaderHistogram.getManager().getSettings().saveState(state.createChild(HISTOGRAM));
                         classLoadingTable.getManager().getSettings().saveState(state.createChild(CLASS_LOADING_TABLE));
                         classUnloadingTable.getManager().getSettings().saveState(state.createChild(CLASS_UNLOADING_TABLE));
+                        classDefineTable.getManager().getSettings().saveState(state.createChild(CLASS_DEFINE_TABLE));
+                        classLoaderStatisticsTable.getManager().getSettings().saveState(state.createChild(CLASS_LOADER_STATISTICS_TABLE));
                         classloaderHistogramFilter.saveState(state.createChild(HISTOGRAM_FILTER));
                         classLoadingFilter.saveState(state.createChild(CLASS_LOADING_FILTER));
                         classUnloadingFilter.saveState(state.createChild(CLASS_UNLOADING_FILTER));
+                        classDefineFilter.saveState(state.createChild(CLASS_DEFINE_FILTER));
+                        classLoaderStatisticsFilter.saveState(state.createChild(CLASS_LOADER_STATISTICS_FILTER));
                         ActionToolkit.saveCheckState(state.createChild(CHART), allChartSeriesActions.stream());
 
                         saveToLocal();
                 }
 
                 private void saveToLocal() {
                         histogramSelection = classloaderHistogram.getManager().getSelectionState();
                         classLoadingTableSelection = classLoadingTable.getManager().getSelectionState();
                         classUnloadingTableSelection = classUnloadingTable.getManager().getSelectionState();
+                        classDefineTableSelection = classDefineTable.getManager().getSelectionState();
+                        classLoaderStatisticsTableSelection = classLoaderStatisticsTable.getManager().getSelectionState();
                         tabFolderIndex = tabFolder.getSelectionIndex();
                         flavorSelectorState = flavorSelector.getFlavorSelectorState();
                 }
 
                 private void onShow(Boolean show) {

@@ -393,13 +501,15 @@
                                 classloaderHistogram.show(items.apply(JdkFilters.CLASS_LOAD_OR_UNLOAD));
                         }
                 }
 
                 private void updateTables(IItemCollection selectedItems) {
-                        if (classLoadingTable != null && classUnloadingTable != null) {
+                        if (classLoadingTable != null && classUnloadingTable != null && classDefineTable != null
+                                        && classLoaderStatisticsTable != null) {
                                 classLoadingTable.show(selectedItems.apply(JdkQueries.CLASS_LOAD.getFilter()));
                                 classUnloadingTable.show(selectedItems.apply(JdkQueries.CLASS_UNLOAD.getFilter()));
+                                classDefineTable.show(selectedItems.apply(JdkQueries.CLASS_DEFINE.getFilter()));
                         }
                 }
 
                 private void onChartSelection(IRange<IQuantity> range) {
                         // FIXME: Make this depend on the legend as well? And maybe on which chart row has been selected?

@@ -415,25 +525,33 @@
         private static final String SASH = "sash"; //$NON-NLS-1$
         private static final String HISTOGRAM = "histogram"; //$NON-NLS-1$
         private static final String HISTOGRAM_FILTER = "histogramFilter"; //$NON-NLS-1$
         private static final String CLASS_LOADING_TABLE = "classLoadingTable"; //$NON-NLS-1$
         private static final String CLASS_UNLOADING_TABLE = "classUnloadingTable"; //$NON-NLS-1$
+        private static final String CLASS_DEFINE_TABLE = "classDefineTable"; //$NON-NLS-1$
+        private static final String CLASS_LOADER_STATISTICS_TABLE = "classLoaderStatisticsTable"; //$NON-NLS-1$
         private static final String CLASS_LOADING_FILTER = "classLoadingFilter"; //$NON-NLS-1$
         private static final String CLASS_UNLOADING_FILTER = "classUnloadingFilter"; //$NON-NLS-1$
+        private static final String CLASS_DEFINE_FILTER = "classDefineFilter"; //$NON-NLS-1$
+        private static final String CLASS_LOADER_STATISTICS_FILTER = "classLoaderStatisticsFilter"; //$NON-NLS-1$
         private static final String CHART = "chart"; //$NON-NLS-1$
 
         @Override
         public IPageUI display(Composite parent, FormToolkit toolkit, IPageContainer pageContainer, IState state) {
                 return new ClassLoadingUi(parent, toolkit, pageContainer, state);
         }
 
         private SelectionState histogramSelection;
         private SelectionState classLoadingTableSelection;
         private SelectionState classUnloadingTableSelection;
+        private SelectionState classDefineTableSelection;
+        private SelectionState classLoaderStatisticsTableSelection;
         private IItemFilter histogramFilter;
         private IItemFilter classLoadTableFilter;
         private IItemFilter classUnloadTableFilter;
+        private IItemFilter classDefineTableFilter;
+        private IItemFilter classLoaderStatisticsTableFilter;
         private int tabFolderIndex = 0;
         private IRange<IQuantity> timelineRange;
         private FlavorSelectorState flavorSelectorState;
 
         public ClassLoadingPage(IPageDefinition dpd, StreamModel items, IPageContainer editor) {
< prev index next >