mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
debugger overhead proto
This commit is contained in:
@@ -35,6 +35,7 @@ import com.intellij.debugger.ui.impl.ThreadsPanel;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.MessageDescriptor;
|
||||
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl;
|
||||
import com.intellij.debugger.ui.overhead.OverheadView;
|
||||
import com.intellij.debugger.ui.tree.NodeDescriptor;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.ui.ExecutionConsole;
|
||||
@@ -318,6 +319,7 @@ public class JavaDebugProcess extends XDebugProcess {
|
||||
public void registerAdditionalContent(@NotNull RunnerLayoutUi ui) {
|
||||
registerThreadsPanel(ui);
|
||||
registerMemoryViewPanel(ui);
|
||||
registerOverheadMonitor(ui);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -360,7 +362,8 @@ public class JavaDebugProcess extends XDebugProcess {
|
||||
}
|
||||
|
||||
private void registerMemoryViewPanel(@NotNull RunnerLayoutUi ui) {
|
||||
if (!Registry.get("debugger.enable.memory.view").asBoolean()) return;
|
||||
if (!Registry.is("debugger.enable.memory.view")) return;
|
||||
|
||||
final XDebugSession session = getSession();
|
||||
final DebugProcessImpl process = myJavaSession.getProcess();
|
||||
final InstancesTracker tracker = InstancesTracker.getInstance(myJavaSession.getProject());
|
||||
@@ -395,6 +398,35 @@ public class JavaDebugProcess extends XDebugProcess {
|
||||
}
|
||||
}, memoryViewContent);
|
||||
}
|
||||
|
||||
private void registerOverheadMonitor(@NotNull RunnerLayoutUi ui) {
|
||||
if (!Registry.is("debugger.enable.overhead.monitor")) return;
|
||||
|
||||
OverheadView monitor = new OverheadView(myJavaSession.getProcess());
|
||||
Content overheadContent = ui.createContent("OverheadMonitor", monitor, "Overhead", AllIcons.Debugger.Db_obsolete, null);
|
||||
|
||||
overheadContent.setCloseable(false);
|
||||
overheadContent.setShouldDisposeContent(true);
|
||||
|
||||
//session.addSessionListener(new XDebugSessionListener() {
|
||||
// @Override
|
||||
// public void sessionStopped() {
|
||||
// session.removeSessionListener(this);
|
||||
// data.getTrackedStacks().clear();
|
||||
// }
|
||||
//});
|
||||
|
||||
ui.addContent(overheadContent, 0, PlaceInGrid.right, true);
|
||||
//final DebuggerManagerThreadImpl managerThread = process.getManagerThread();
|
||||
//ui.addListener(new ContentManagerAdapter() {
|
||||
// @Override
|
||||
// public void selectionChanged(ContentManagerEvent event) {
|
||||
// if (event != null && event.getContent() == overheadContent) {
|
||||
// classesFilteredView.setActive(overheadContent.isSelected(), managerThread);
|
||||
// }
|
||||
// }
|
||||
//}, overheadContent);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.openapi.util.Key;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author egor
|
||||
*/
|
||||
public class OverheadTimings {
|
||||
public static final Key<OverheadTimings> KEY = Key.create("OVERHEAD_TIMINGS");
|
||||
|
||||
private final Map<Object, Long> myMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static float get(DebugProcessImpl process, Object producer) {
|
||||
return getTimings(process).myMap.get(producer);
|
||||
}
|
||||
|
||||
public static void add(DebugProcessImpl process, Object producer, long overhead) {
|
||||
getTimings(process).myMap.merge(producer, overhead, (old, value) -> old + value);
|
||||
}
|
||||
|
||||
private static OverheadTimings getTimings(DebugProcessImpl process) {
|
||||
OverheadTimings data = process.getUserData(KEY);
|
||||
if (data == null) {
|
||||
data = new OverheadTimings();
|
||||
process.putUserData(KEY, data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor;
|
||||
import com.intellij.debugger.requests.Requestor;
|
||||
import com.intellij.debugger.settings.DebuggerSettings;
|
||||
import com.intellij.debugger.ui.OverheadTimings;
|
||||
import com.intellij.debugger.ui.overhead.OverheadTimings;
|
||||
import com.intellij.debugger.ui.impl.watch.CompilingEvaluatorImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.overhead;
|
||||
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.util.EventDispatcher;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.EventListener;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author egor
|
||||
*/
|
||||
public class OverheadTimings {
|
||||
public static final Key<OverheadTimings> KEY = Key.create("OVERHEAD_TIMINGS");
|
||||
|
||||
private final EventDispatcher<OverheadTimingsListener> myEventDispatcher = EventDispatcher.create(OverheadTimingsListener.class);
|
||||
private final Map<Object, Timings> myMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static long getTime(DebugProcessImpl process, Object producer) {
|
||||
Timings timings = getTimings(process).myMap.get(producer);
|
||||
return timings != null ? timings.myTime : 0;
|
||||
}
|
||||
|
||||
public static long getHits(DebugProcessImpl process, Object producer) {
|
||||
Timings timings = getTimings(process).myMap.get(producer);
|
||||
return timings != null ? timings.myHits : 0;
|
||||
}
|
||||
|
||||
public static Set<Object> getProducers(DebugProcessImpl process) {
|
||||
return getTimings(process).myMap.keySet();
|
||||
}
|
||||
|
||||
public static void add(DebugProcessImpl process, Object producer, long overhead) {
|
||||
OverheadTimings timings = getTimings(process);
|
||||
timings.myMap.merge(producer, new Timings(1, overhead), (old, value) -> new Timings(old.myHits + 1, old.myTime + overhead));
|
||||
timings.myEventDispatcher.getMulticaster().timingAdded(producer);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static OverheadTimings getTimings(DebugProcessImpl process) {
|
||||
OverheadTimings data = process.getUserData(KEY);
|
||||
if (data == null) {
|
||||
data = new OverheadTimings();
|
||||
process.putUserData(KEY, data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private static class Timings {
|
||||
final long myHits;
|
||||
final long myTime;
|
||||
|
||||
public Timings(long hits, long time) {
|
||||
myHits = hits;
|
||||
myTime = time;
|
||||
}
|
||||
}
|
||||
|
||||
static void addListener(OverheadTimingsListener listener, DebugProcessImpl process) {
|
||||
getTimings(process).myEventDispatcher.addListener(listener);
|
||||
}
|
||||
|
||||
public interface OverheadTimingsListener extends EventListener {
|
||||
void timingAdded(Object producer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.overhead;
|
||||
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.ui.breakpoints.Breakpoint;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CustomShortcutSet;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.TableUtil;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.util.ui.ColumnInfo;
|
||||
import com.intellij.util.ui.ListTableModel;
|
||||
import com.intellij.util.ui.components.BorderLayoutPanel;
|
||||
import one.util.streamex.IntStreamEx;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.Comparator;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author egor
|
||||
*/
|
||||
public class OverheadView extends BorderLayoutPanel {
|
||||
@NotNull private final DebugProcessImpl myProcess;
|
||||
|
||||
static final EnabledColumnInfo ENABLED_COLUMN = new EnabledColumnInfo();
|
||||
static final NameColumnInfo NAME_COLUMN = new NameColumnInfo();
|
||||
|
||||
final JBTable myTable;
|
||||
final ListTableModel<BreakpointOverheadItem> myModel;
|
||||
|
||||
public OverheadView(@NotNull DebugProcessImpl process) {
|
||||
myProcess = process;
|
||||
|
||||
myModel = new ListTableModel<>(new ColumnInfo[]{
|
||||
ENABLED_COLUMN,
|
||||
NAME_COLUMN,
|
||||
new TimingColumnInfo("hits", s -> OverheadTimings.getHits(myProcess, s.myBreakpoint)),
|
||||
new TimingColumnInfo("time", s -> OverheadTimings.getTime(myProcess, s.myBreakpoint))},
|
||||
StreamEx.of(OverheadTimings.getProducers(process)).select(Breakpoint.class).map(BreakpointOverheadItem::new).toList(),
|
||||
3, SortOrder.DESCENDING);
|
||||
myModel.setSortable(true);
|
||||
myTable = new JBTable(myModel);
|
||||
addToCenter(ScrollPaneFactory.createScrollPane(myTable));
|
||||
TableUtil.setupCheckboxColumn(myTable.getColumnModel().getColumn(0));
|
||||
OverheadTimings.addListener(o -> {
|
||||
int idx = 0;
|
||||
for (BreakpointOverheadItem item : myModel.getItems()) {
|
||||
if (item.myBreakpoint == o) {
|
||||
myModel.fireTableRowsUpdated(idx, idx);
|
||||
return;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
myModel
|
||||
.setItems(StreamEx.of(OverheadTimings.getProducers(process)).select(Breakpoint.class).map(BreakpointOverheadItem::new).toList());
|
||||
myModel.fireTableDataChanged();
|
||||
}, process);
|
||||
|
||||
new DumbAwareAction("Toggle") {
|
||||
@Override
|
||||
public void update(@NotNull AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(myTable.getSelectedRowCount() == 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull final AnActionEvent e) {
|
||||
getSelected().forEach(c -> c.setEnabled(!c.isEnabled()));
|
||||
myTable.repaint();
|
||||
}
|
||||
}.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0)), myTable);
|
||||
}
|
||||
|
||||
private StreamEx<OverheadItem> getSelected() {
|
||||
return IntStreamEx.of(myTable.getSelectedRows()).map(myTable::convertRowIndexToModel).mapToObj(myModel::getItem);
|
||||
}
|
||||
|
||||
private static class EnabledColumnInfo extends ColumnInfo<OverheadItem, Boolean> {
|
||||
public EnabledColumnInfo() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass() {
|
||||
return Boolean.class;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Boolean valueOf(OverheadItem item) {
|
||||
return item.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(OverheadItem item) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(OverheadItem item, Boolean value) {
|
||||
item.setEnabled(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NameColumnInfo extends ColumnInfo<BreakpointOverheadItem, String> {
|
||||
public NameColumnInfo() {
|
||||
super("name");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String valueOf(BreakpointOverheadItem aspects) {
|
||||
return aspects.getName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Comparator<BreakpointOverheadItem> getComparator() {
|
||||
return Comparator.comparing(i -> valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
private static class TimingColumnInfo extends ColumnInfo<BreakpointOverheadItem, Long> {
|
||||
private final Function<BreakpointOverheadItem, Long> myGetter;
|
||||
|
||||
public TimingColumnInfo(@NotNull String name, Function<BreakpointOverheadItem, Long> getter) {
|
||||
super(name);
|
||||
myGetter = getter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass() {
|
||||
return Long.class;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Long valueOf(BreakpointOverheadItem aspects) {
|
||||
return myGetter.apply(aspects);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Comparator<BreakpointOverheadItem> getComparator() {
|
||||
return Comparator.comparingLong(i -> valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
interface OverheadItem {
|
||||
boolean isEnabled();
|
||||
|
||||
void setEnabled(boolean enabled);
|
||||
|
||||
String getName();
|
||||
}
|
||||
|
||||
static class BreakpointOverheadItem implements OverheadItem {
|
||||
private final Breakpoint myBreakpoint;
|
||||
|
||||
public BreakpointOverheadItem(Breakpoint breakpoint) {
|
||||
myBreakpoint = breakpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return myBreakpoint.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return myBreakpoint.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
myBreakpoint.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -289,6 +289,7 @@ debugger.capture.points.annotations=false
|
||||
debugger.resume.yourkit.threads=false
|
||||
debugger.keep.step.requests=false
|
||||
debugger.enable.memory.view=true
|
||||
debugger.enable.overhead.monitor=false
|
||||
debugger.tree.states.depth=100
|
||||
|
||||
analyze.exceptions.on.the.fly=false
|
||||
|
||||
Reference in New Issue
Block a user