Bug 550022 - [GTK] Long delay in deleting all items from a virtual table
Summary: [GTK] Long delay in deleting all items from a virtual table
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.13   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Platform-SWT-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance, triaged
: 559129 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-08-13 12:03 EDT by Lars Vogel CLA
Modified: 2020-02-17 04:07 EST (History)
4 users (show)

See Also:


Attachments
Yourkit trace (113.83 KB, image/png)
2019-09-05 06:14 EDT, Lars Vogel CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Lars Vogel CLA 2019-08-13 12:03:34 EDT
I see the following UI freeze in my error log.


Stack Trace
	at org.eclipse.swt.internal.gtk.GTK._gtk_list_store_clear(Native Method)
	at org.eclipse.swt.internal.gtk.GTK.gtk_list_store_clear(GTK.java:3891)
	at org.eclipse.swt.widgets.Table.removeAll(Table.java:2828)
	at org.eclipse.swt.widgets.Table.remove(Table.java:2702)
	at org.eclipse.swt.widgets.Table.setItemCount(Table.java:3680)
	at org.eclipse.jface.viewers.TableViewer.doSetItemCount(TableViewer.java:231)
	at org.eclipse.jface.viewers.AbstractTableViewer.internalVirtualRefreshAll(AbstractTableViewer.java:646)
	at org.eclipse.jface.viewers.AbstractTableViewer.internalRefresh(AbstractTableViewer.java:620)
	at org.eclipse.jface.viewers.AbstractTableViewer.internalRefresh(AbstractTableViewer.java:610)
	at org.eclipse.jface.viewers.AbstractTableViewer.lambda$0(AbstractTableViewer.java:572)
	at org.eclipse.jface.viewers.AbstractTableViewer$$Lambda$1513/0x0000000101515c40.run(Unknown Source)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1393)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1354)
	at org.eclipse.jface.viewers.AbstractTableViewer.inputChanged(AbstractTableViewer.java:572)
	at org.eclipse.jface.viewers.ContentViewer.setInput(ContentViewer.java:282)
	at org.eclipse.jface.viewers.StructuredViewer.setInput(StructuredViewer.java:1631)
	at org.eclipse.egit.ui.internal.history.GitHistoryPage.clearViewers(GitHistoryPage.java:1732)
	at org.eclipse.egit.ui.internal.history.GitHistoryPage.initAndStartRevWalk(GitHistoryPage.java:2390)
	at org.eclipse.egit.ui.internal.history.GitHistoryPage.inputSet(GitHistoryPage.java:2000)
	at org.eclipse.team.ui.history.HistoryPage.setInput(HistoryPage.java:54)
	at org.eclipse.egit.ui.internal.history.GitHistoryPage.setInput(GitHistoryPage.java:1863)
	at org.eclipse.team.internal.ui.history.GenericHistoryView.getPageRec(GenericHistoryView.java:652)
	at org.eclipse.ui.part.PageBookView.partActivated(PageBookView.java:694)
	at org.eclipse.team.internal.ui.history.GenericHistoryView.showHistoryPageFor(GenericHistoryView.java:628)
	at org.eclipse.team.internal.ui.history.GenericHistoryView.showHistory(GenericHistoryView.java:899)
	at org.eclipse.team.internal.ui.history.GenericHistoryView.editorActivated(GenericHistoryView.java:835)
	at org.eclipse.team.internal.ui.history.GenericHistoryView.partActivated(GenericHistoryView.java:382)
	at org.eclipse.ui.part.PageBookView$1.partActivated(PageBookView.java:1006)
	at org.eclipse.ui.internal.WorkbenchPage$4.run(WorkbenchPage.java:4906)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
	at org.eclipse.ui.internal.WorkbenchPage.firePartActivated(WorkbenchPage.java:4903)
	at org.eclipse.ui.internal.WorkbenchPage.access$3(WorkbenchPage.java:4879)
	at org.eclipse.ui.internal.WorkbenchPage$E4PartListener.partActivated(WorkbenchPage.java:214)
	at org.eclipse.e4.ui.internal.workbench.PartServiceImpl$3.run(PartServiceImpl.java:253)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
	at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.firePartActivated(PartServiceImpl.java:250)
	at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:774)
	at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.activate(PartServiceImpl.java:683)
	at org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer.activate(AbstractPartRenderer.java:97)
	at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer.lambda$3(StackRenderer.java:1061)
	at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer$$Lambda$263/0x0000000100698c40.accept(Unknown Source)
	at org.eclipse.swt.events.SelectionListener$1.widgetSelected(SelectionListener.java:84)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:252)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5618)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1405)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1431)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1414)
	at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1203)
	at org.eclipse.swt.custom.CTabFolder.setSelection(CTabFolder.java:3193)
	at org.eclipse.swt.custom.CTabFolder.onMouse(CTabFolder.java:1876)
	at org.eclipse.swt.custom.CTabFolder.lambda$0(CTabFolder.java:330)
	at org.eclipse.swt.custom.CTabFolder$$Lambda$255/0x000000010064a440.handleEvent(Unknown Source)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5618)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1405)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4882)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4406)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1160)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1049)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155)
	at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:635)
	at org.eclipse.ui.internal.Workbench$$Lambda$118/0x000000010036d840.run(Unknown Source)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:559)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:150)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255)
	at java.base@11.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base@11.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base@11.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base@11.0.2/java.lang.reflect.Method.invoke(Method.java:566)
	at app//org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:660)
	at app//org.eclipse.equinox.launcher.Main.basicRun(Main.java:597)
	at app//org.eclipse.equinox.launcher.Main.run(Main.java:1468)
	at app//org.eclipse.equinox.launcher.Main.main(Main.java:1441)
Comment 1 Thomas Wolf CLA 2019-08-13 14:39:42 EDT
This is while clearing the commit table. Nothing we can do in EGit. Move the bug to SWT/GTK.
Comment 2 Eric Williams CLA 2019-08-13 14:46:18 EDT
Is this a consistently reproducible bug, or just a one-off?
Comment 3 Lars Vogel CLA 2019-08-13 14:55:31 EDT
(In reply to Eric Williams from comment #2)
> Is this a consistently reproducible bug, or just a one-off?

Happens all the time in my "all eclipse top-level projects in one ws" workspace.
Comment 4 Eric Williams CLA 2019-08-13 15:07:01 EDT
Okay, we'll investigate. Thanks for the bug report.
Comment 5 Lars Vogel CLA 2019-08-13 15:37:25 EDT
(In reply to Eric Williams from comment #4)
> Okay, we'll investigate. Thanks for the bug report.

Thanks, Eric.
Comment 6 Eric Williams CLA 2019-08-13 15:44:06 EDT
What exactly are the steps to reproduce this?
Comment 7 Lars Vogel CLA 2019-08-13 15:50:29 EDT
(In reply to Eric Williams from comment #6)
> What exactly are the steps to reproduce this?

Create ws with all projects from SWT, platform.ui, platform.text, JDT, PDE platform.ua.
Enable freeze monitor and use Eclipse to jump between classes which are located in different repos
Have the History view open during this operation.
Comment 8 Thomas Wolf CLA 2019-08-13 15:59:16 EDT
@Eric: probably Lars has a longish history visible in the Git History view. Then he switches from one repo to another. Before loading the new history, EGit clears the table by setting the table input to an empty array.

The commit graph table has SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL. Column 1 is owner draw.

All we do in EGit is table.setInput(new SWTCommit[0]); and then the code goes through internalVirtualRefreshAll(), doSetItemCount(0), Table.setItemCount(0), and eventually removeAll().

@Lars: how long is the UI freeze? Which SWT version?

Note that SWT versions < 4919 (Eclipse 4.10) run into an exponential algorithm in gtk_list_store_clear for tables with SWT.VIRTUAL | SWT.MULTI.
Comment 9 Lars Vogel CLA 2019-08-13 16:04:49 EDT
(In reply to Thomas Wolf from comment #8)
> @Lars: how long is the UI freeze? 

Between 500 and 900 ms.

> Which SWT version?

Yesterdays build.
Comment 10 Eclipse Genie CLA 2019-08-13 16:25:44 EDT
New Gerrit change created: https://git.eclipse.org/r/147650
Comment 11 Lars Vogel CLA 2019-08-13 16:32:40 EDT
I'm not sure if the attached Snippet reproduces the exact same thing but I hope it helps.

Expand the tree, wait until elements are created.
Collapse it again:

Field OPTION2 = true -> use setInput
setInput took: 5468 ms

Field OPTION1 = false -> use deleteAll
removeAll took: 6180 ms
Comment 12 Eric Williams CLA 2019-08-14 09:08:38 EDT
(In reply to Lars Vogel from comment #11)
> I'm not sure if the attached Snippet reproduces the exact same thing but I
> hope it helps.
> 
> Expand the tree, wait until elements are created.
> Collapse it again:
> 
> Field OPTION2 = true -> use setInput
> setInput took: 5468 ms
> 
> Field OPTION1 = false -> use deleteAll
> removeAll took: 6180 ms

I'll take a look later today. FWIW I can't reproduce the slowdown using EGit.
Comment 13 Eric Williams CLA 2019-08-16 12:13:47 EDT
I'm not going to get to this in time for 4.13, I'll work on it for 4.14.
Comment 14 Lars Vogel CLA 2019-09-05 06:14:16 EDT
Created attachment 279778 [details]
Yourkit trace

Adding a Yourkit trace in caes that helps.
Comment 15 Eric Williams CLA 2019-09-18 12:05:22 EDT
I'm still having trouble reproducing this, even with the threshold set to 200ms. I am speaking about EGit, using the snippet I can reproduce the issue reliably.
Comment 16 Lars Vogel CLA 2019-09-18 12:07:08 EDT
(In reply to Eric Williams from comment #15)
> I'm still having trouble reproducing this, even with the threshold set to
> 200ms. I am speaking about EGit, using the snippet I can reproduce the issue
> reliably.

I suggest to use the snippet for analysis, I created it to make it easier for your to reproduce.
Comment 17 Eric Williams CLA 2019-09-23 10:50:43 EDT
Using the snippet, removeAll is actually the same (and sometimes faster) than setInput.

I'll continue to investigate, gtk_list_store_clear() runs in linear time, so larger Tables will suffer a performance decrease. The question becomes whether or not we can mitigate it or not.
Comment 18 Eric Williams CLA 2019-11-12 11:52:05 EST
Moving into 4.15 as I didn't get a chance to look at this one.
Comment 19 Thomas Wolf CLA 2020-01-27 07:10:21 EST
*** Bug 559129 has been marked as a duplicate of this bug. ***
Comment 20 Lakshmi P Shanmugam CLA 2020-02-17 04:07:43 EST
Resetting target, please re-target as required.