Fwd: IDE responsiveness

6 views
Skip to first unread message

iulian dragos

unread,
Sep 9, 2010, 5:34:49 AM9/9/10
to scala-ide-dev


---------- Forwarded message ----------
From: iulian dragos <iulian...@epfl.ch>
Date: Thu, Sep 9, 2010 at 11:32 AM
Subject: IDE responsiveness
To: Martin Odersky <martin....@epfl.ch>, Eugene Vigdorchik <eugene.v...@gmail.com>, Plociniczak Hubert <hubert.pl...@epfl.ch>, Miles Sabin <mi...@milessabin.com>, scala-...@googlegroups.com


Hello,

I've been trying to use Eclipse as my main IDE for Scala development. There are good things and bad things, but I think that very small changes could improve (my) experience dramatically. First, code navigation and inspection is very good. Even for a project of abuot 80k LOC, it finds definitions almost all the time.

The downside is editing. There are many large files (~1500 LOC is the norm), and typing is simply too frustrating. If I stop for a second, I need to wait 4-5 seconds while the UI is completely frozen. I tried to dump threads, and most of the times the main thread is blocked waiting for a lock in SynchronizableDocument.get. There's another blocked thread, Java Reconciler, which is blocked waiting for a SyncVar (which is the presentation compiler result). This makes is basically impossible to use: by the time the UI becomes responsive again, and it prints all the characters I typed in the meantime, another compilation run is started (I guess) so I have to stop again. And so on.

Could we change the timeout, so that I can have longer breaks when typing, before the compiler kicks in? Maybe something related to the size of the current file. I think 3 seconds would be much better. I understand that this timeout may be dictated by the JDT, so in that case we're out of luck. At any rate, it would be good to be able to cancel whatever the IDE is doing, but it looks like the main tread is the one that's blocked.

Any thoughts?

iulian





--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais



--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais

Miles Sabin

unread,
Sep 9, 2010, 5:59:48 AM9/9/10
to iulian dragos, Martin Odersky, Eugene Vigdorchik, Plociniczak Hubert, scala-...@googlegroups.com
On Thu, Sep 9, 2010 at 10:32 AM, iulian dragos <iulian...@epfl.ch> wrote:
> The downside is editing. There are many large files (~1500 LOC is the norm),
> and typing is simply too frustrating. If I stop for a second, I need to wait
> 4-5 seconds while the UI is completely frozen. I tried to dump threads, and
> most of the times the main thread is blocked waiting for a lock
> in SynchronizableDocument.get. There's another blocked thread, Java
> Reconciler, which is blocked waiting for a SyncVar (which is the
> presentation compiler result).

Some context would help ... next time you see this, could you send me
the thread dump for the UI thread when it's blocked in
SynchronizableDocument.get.

Cheers,


Miles

--
Miles Sabin
tel: +44 7813 944 528
gtalk: mi...@milessabin.com
skype: milessabin
http://www.chuusai.com/
http://twitter.com/milessabin

martin odersky

unread,
Sep 9, 2010, 6:49:18 AM9/9/10
to Miles Sabin, iulian dragos, Eugene Vigdorchik, Plociniczak Hubert, scala-...@googlegroups.com
I don't know about SynchronizableDocument. But for the SyncVar block with the presentation compiler, it indicates that it's used the wrong way. You should never use a blocking get, only use a get with a low timeout (say 50ms). Then if you have further input, simply cancel the request.
This interaction pattern is outlined in the doc comment of nsc.interactive.Response.

Cheers

 -- Martin

Miles Sabin

unread,
Sep 9, 2010, 7:05:18 AM9/9/10
to martin odersky, iulian dragos, Eugene Vigdorchik, Plociniczak Hubert, scala-...@googlegroups.com
On Thu, Sep 9, 2010 at 11:49 AM, martin odersky <martin....@epfl.ch> wrote:
> I don't know about SynchronizableDocument. But for the SyncVar block with
> the presentation compiler, it indicates that it's used the wrong way. You
> should never use a blocking get, only use a get with a low timeout (say
> 50ms). Then if you have further input, simply cancel the request.
> This interaction pattern is outlined in the doc comment of
> nsc.interactive.Response.

That might be so, nevertheless the interaction between the reconciler
thread and the UI thread that Iulian is reporting shouldn't be
happening, and it would help a lot to know exactly where it is.

iulian dragos

unread,
Sep 9, 2010, 8:01:17 AM9/9/10
to scala-...@googlegroups.com, martin odersky, Eugene Vigdorchik, Plociniczak Hubert
I still have the thread dump. Notice that 3 threads have interesting stacks: Scala Presentation, Java Reconciler and the main thread. The main thread does not seem to have any stack entry that comes from the SDT, though. Here's the full thread dump. Miles, should I file a bug report? This is not the only stack configuration I noticed, but invariably the main thread is blocked (I assume the main thread is the UI?).

Full thread dump Java HotSpot(TM) Client VM (16.3-b01-279 mixed mode):

"Worker-6" prio=5 tid=00000000136afc00 nid=0xb163e000 in Object.wait() [00000000b163d000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:185)
- locked <00000000182f0530> (a org.eclipse.core.internal.jobs.WorkerPool)
at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:217)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:51)

"Scala Presentation Compiler" prio=6 tid=00000000136c1400 nid=0xb1338000 runnable [00000000b1327000]
   java.lang.Thread.State: RUNNABLE
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:391)
at java.lang.StringBuilder.append(StringBuilder.java:119)
at scala.collection.mutable.StringBuilder.append(StringBuilder.scala:178)
at scala.reflect.generic.Symbols$AbsSymbol.fullName(Symbols.scala:39)
at scala.reflect.generic.Symbols$AbsSymbol.fullName(Symbols.scala:47)
at scala.tools.eclipse.ScalaPresentationCompiler$EclipseTyperRun.addImport$1(ScalaPresentationCompiler.scala:122)
at scala.tools.eclipse.ScalaPresentationCompiler$EclipseTyperRun$$anonfun$compileSourceFor$1.apply(ScalaPresentationCompiler.scala:128)
at scala.tools.eclipse.ScalaPresentationCompiler$EclipseTyperRun$$anonfun$compileSourceFor$1.apply(ScalaPresentationCompiler.scala:128)
at scala.collection.LinearSeqOptimized$class.exists(LinearSeqOptimized.scala:81)
at scala.collection.immutable.List.exists(List.scala:45)
at scala.tools.eclipse.ScalaPresentationCompiler$EclipseTyperRun.compileSourceFor(ScalaPresentationCompiler.scala:128)
at scala.tools.nsc.typechecker.Typers$Typer.typedIdent$1(Typers.scala:3561)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3996)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typedArg(Typers.scala:2141)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedArgs$3.apply(Typers.scala:2151)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedArgs$3.apply(Typers.scala:2150)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206)
at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:61)
at scala.collection.immutable.List.foreach(List.scala:45)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:206)
at scala.collection.immutable.List.map(List.scala:45)
at scala.tools.nsc.typechecker.Typers$Typer.typedArgs(Typers.scala:2150)
at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:2350)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$tryTypedApply$1$1.apply(Typers.scala:3239)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$tryTypedApply$1$1.apply(Typers.scala:3239)
at scala.tools.nsc.typechecker.Typers$Typer.silent(Typers.scala:699)
at scala.tools.nsc.typechecker.Typers$Typer.tryTypedApply$1(Typers.scala:3239)
at scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:3298)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3924)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typedQualifier(Typers.scala:4145)
at scala.tools.nsc.typechecker.Typers$Typer.typedQualifier(Typers.scala:4151)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3964)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4139)
at scala.tools.nsc.typechecker.Typers$Typer.computeType(Typers.scala:4215)
at scala.tools.nsc.typechecker.Namers$Namer.typeSig(Namers.scala:1174)
at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$typeCompleter$1.apply(Namers.scala:517)
at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$typeCompleter$1.apply(Namers.scala:515)
at scala.tools.nsc.typechecker.Namers$$anon$1.complete(Namers.scala:1338)
at scala.tools.nsc.typechecker.Namers$$anon$1.complete(Namers.scala:1336)
at scala.tools.nsc.symtab.Symbols$Symbol.info(Symbols.scala:743)
at scala.tools.nsc.symtab.Symbols$Symbol.initialize(Symbols.scala:855)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3720)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typedStat$1(Typers.scala:2067)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.collection.immutable.List.loop$1(List.scala:115)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer.typedBlock(Typers.scala:1889)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3769)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typedArg(Typers.scala:2141)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedArgs$3.apply(Typers.scala:2151)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$typedArgs$3.apply(Typers.scala:2150)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206)
at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:61)
at scala.collection.immutable.List.foreach(List.scala:45)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:206)
at scala.collection.immutable.List.map(List.scala:45)
at scala.tools.nsc.typechecker.Typers$Typer.typedArgs(Typers.scala:2150)
at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:2350)
at scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:3300)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3924)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4139)
at scala.tools.nsc.typechecker.Typers$Typer.computeType(Typers.scala:4215)
at scala.tools.nsc.typechecker.Namers$Namer.typeSig(Namers.scala:1174)
at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$typeCompleter$1.apply(Namers.scala:517)
at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$typeCompleter$1.apply(Namers.scala:515)
at scala.tools.nsc.typechecker.Namers$$anon$1.complete(Namers.scala:1338)
at scala.tools.nsc.typechecker.Namers$$anon$1.complete(Namers.scala:1336)
at scala.tools.nsc.symtab.Symbols$Symbol.info(Symbols.scala:743)
at scala.tools.nsc.symtab.Symbols$Symbol.initialize(Symbols.scala:855)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3720)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typedStat$1(Typers.scala:2067)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.collection.immutable.List.loop$1(List.scala:115)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer.typedBlock(Typers.scala:1889)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3769)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.transformedOrTyped(Typers.scala:4222)
at scala.tools.nsc.typechecker.Typers$Typer.typedDefDef(Typers.scala:1747)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3742)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3762)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typedStat$1(Typers.scala:2067)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.collection.immutable.List.loop$1(List.scala:115)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer.typedTemplate(Typers.scala:1507)
at scala.tools.nsc.typechecker.Typers$Typer.typedClassDef(Typers.scala:1283)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3733)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typedStat$1(Typers.scala:2067)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.collection.immutable.List.loop$1(List.scala:115)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer.typedBlock(Typers.scala:1889)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3769)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4139)
at scala.tools.nsc.typechecker.Typers$Typer.computeType(Typers.scala:4215)
at scala.tools.nsc.typechecker.Namers$Namer.methodSig(Namers.scala:926)
at scala.tools.nsc.typechecker.Namers$Namer.typeSig(Namers.scala:1163)
at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$typeCompleter$1.apply(Namers.scala:517)
at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$typeCompleter$1.apply(Namers.scala:515)
at scala.tools.nsc.typechecker.Namers$$anon$1.complete(Namers.scala:1338)
at scala.tools.nsc.typechecker.Namers$$anon$1.complete(Namers.scala:1336)
at scala.tools.nsc.symtab.Symbols$Symbol.info(Symbols.scala:743)
at scala.tools.nsc.symtab.Symbols$Symbol.initialize(Symbols.scala:855)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3720)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typedStat$1(Typers.scala:2067)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.collection.immutable.List.loop$1(List.scala:115)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.collection.immutable.List.loop$1(List.scala:119)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer.typedTemplate(Typers.scala:1507)
at scala.tools.nsc.typechecker.Typers$Typer.typedClassDef(Typers.scala:1283)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3733)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3762)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typedStat$1(Typers.scala:2067)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.collection.immutable.List.loop$1(List.scala:115)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3729)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typedStat$1(Typers.scala:2067)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$20.apply(Typers.scala:2135)
at scala.collection.immutable.List.loop$1(List.scala:115)
at scala.collection.immutable.List.mapConserve(List.scala:132)
at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:2135)
at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:3729)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4078)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4126)
at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.apply(Analyzer.scala:85)
at scala.tools.nsc.Global$GlobalPhase$$anonfun$applyPhase$1.apply(Global.scala:276)
at scala.tools.nsc.Global$GlobalPhase$$anonfun$applyPhase$1.apply(Global.scala:276)
at scala.tools.nsc.reporters.Reporter.withSource(Reporter.scala:48)
at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:276)
at scala.tools.nsc.interactive.Global$TyperRun$$anonfun$applyPhase$1$$anonfun$apply$mcV$sp$1.apply(Global.scala:530)
at scala.tools.nsc.interactive.Global$TyperRun$$anonfun$applyPhase$1$$anonfun$apply$mcV$sp$1.apply(Global.scala:530)
at scala.tools.nsc.symtab.SymbolTable.atPhase(SymbolTable.scala:103)
at scala.tools.nsc.interactive.Global$TyperRun$$anonfun$applyPhase$1.apply(Global.scala:530)
at scala.tools.nsc.interactive.Global$TyperRun$$anonfun$applyPhase$1.apply(Global.scala:530)
at scala.tools.nsc.reporters.Reporter.withSource(Reporter.scala:48)
at scala.tools.nsc.interactive.Global$TyperRun.applyPhase(Global.scala:529)
at scala.tools.nsc.interactive.Global$TyperRun.typeCheck(Global.scala:483)
at scala.tools.nsc.interactive.Global$TyperRun.typedTree(Global.scala:520)
at scala.tools.nsc.interactive.Global.typedTree(Global.scala:321)
at scala.tools.nsc.interactive.Global$$anonfun$getTypedTree$1.apply(Global.scala:331)
at scala.tools.nsc.interactive.Global$$anonfun$getTypedTree$1.apply(Global.scala:331)
at scala.tools.nsc.interactive.Global.respond(Global.scala:276)
at scala.tools.nsc.interactive.Global.getTypedTree(Global.scala:331)
at scala.tools.nsc.interactive.CompilerControl$$anon$3.apply$mcV$sp(CompilerControl.scala:95)
at scala.tools.nsc.interactive.Global.pollForWork(Global.scala:132)
at scala.tools.nsc.interactive.Global$$anon$2.run(Global.scala:192)

"Worker-5" prio=5 tid=0000000013b2d400 nid=0xb1c4a000 in Object.wait() [00000000b1c49000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:185)
- locked <00000000182f0530> (a org.eclipse.core.internal.jobs.WorkerPool)
at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:217)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:51)

"Worker-4" prio=5 tid=0000000013235400 nid=0xb153c000 in Object.wait() [00000000b153b000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:185)
- locked <00000000182f0530> (a org.eclipse.core.internal.jobs.WorkerPool)
at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:217)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:51)

"Worker-3" prio=5 tid=00000000138c1000 nid=0xb1b48000 in Object.wait() [00000000b1b47000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:185)
- locked <00000000182f0530> (a org.eclipse.core.internal.jobs.WorkerPool)
at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:217)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:51)

"org.eclipse.jdt.internal.ui.text.JavaReconciler" daemon prio=1 tid=00000000131b5800 nid=0xb1a46000 in Object.wait() [00000000b1a45000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at scala.concurrent.SyncVar.get(SyncVar.scala:25)
- locked <000000002bfbfd50> (a scala.concurrent.SyncVar)
at scala.tools.eclipse.ScalaPresentationCompiler$CachedCompilerResult$$anon$3.<init>(ScalaPresentationCompiler.scala:76)
at scala.tools.eclipse.ScalaPresentationCompiler$CachedCompilerResult.create(ScalaPresentationCompiler.scala:70)
at scala.tools.eclipse.ScalaPresentationCompiler$CachedCompilerResult.create(ScalaPresentationCompiler.scala:67)
at scala.tools.eclipse.util.Cached$class.apply(Cached.scala:44)
at scala.tools.eclipse.ScalaPresentationCompiler$CachedCompilerResult.apply(ScalaPresentationCompiler.scala:67)
at scala.tools.eclipse.ScalaPresentationCompiler.withCompilerResult(ScalaPresentationCompiler.scala:90)
at scala.tools.eclipse.ScalaProject$$anonfun$withCompilerResult$1.apply(ScalaProject.scala:368)
at scala.tools.eclipse.ScalaProject$$anonfun$withCompilerResult$1.apply(ScalaProject.scala:367)
at scala.tools.eclipse.util.Cached$$anonfun$apply$1.apply$mcV$sp(Cached.scala:22)
at scala.tools.eclipse.util.Cached$$anonfun$apply$1.apply(Cached.scala:21)
at scala.tools.eclipse.util.Cached$$anonfun$apply$1.apply(Cached.scala:21)
at scala.tools.eclipse.util.Cached$class.locked(Cached.scala:83)
at scala.tools.eclipse.util.Cached$class.apply(Cached.scala:20)
at scala.tools.eclipse.ScalaProject$$anon$1.apply(ScalaProject.scala:39)
at scala.tools.eclipse.ScalaProject.withPresentationCompiler(ScalaProject.scala:363)
at scala.tools.eclipse.ScalaProject.withCompilerResult(ScalaProject.scala:367)
at scala.tools.eclipse.javaelements.ScalaCompilationUnit$$anonfun$withCompilerResult$1.apply(ScalaCompilationUnit.scala:49)
at scala.tools.eclipse.javaelements.ScalaCompilationUnit$class.withDocument(ScalaCompilationUnit.scala:41)
- locked <000000001a209448> (a java.lang.Object)
at scala.tools.eclipse.javaelements.ScalaSourceFile.withDocument(ScalaSourceFile.scala:40)
at scala.tools.eclipse.javaelements.ScalaCompilationUnit$class.withCompilerResult(ScalaCompilationUnit.scala:49)
at scala.tools.eclipse.javaelements.ScalaSourceFile.withCompilerResult(ScalaSourceFile.scala:40)
at scala.tools.eclipse.javaelements.ScalaCompilationUnit$class.buildStructure(ScalaCompilationUnit.scala:91)
at scala.tools.eclipse.javaelements.ScalaSourceFile.buildStructure(ScalaSourceFile.scala:40)
at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:258)
at org.eclipse.jdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:515)
at scala.tools.eclipse.javaelements.ScalaSourceFile.makeConsistent(ScalaSourceFile.scala:65)
at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.makeConsistent(ReconcileWorkingCopyOperation.java:170)
at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.executeOperation(ReconcileWorkingCopyOperation.java:89)
at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:728)
at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:788)
at org.eclipse.jdt.internal.core.CompilationUnit.reconcile(CompilationUnit.java:1244)
at scala.tools.eclipse.javaelements.ScalaSourceFile.reconcile(ScalaSourceFile.scala:55)
at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:126)
at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.access$0(JavaReconcilingStrategy.java:108)
at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy$1.run(JavaReconcilingStrategy.java:89)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:87)
at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:151)
at org.eclipse.jdt.internal.ui.text.CompositeReconcilingStrategy.reconcile(CompositeReconcilingStrategy.java:86)
at org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.reconcile(JavaCompositeReconcilingStrategy.java:102)
at org.eclipse.jface.text.reconciler.MonoReconciler.process(MonoReconciler.java:77)
at org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.run(AbstractReconciler.java:206)

"[ThreadPool Manager] - Idle Thread" daemon prio=5 tid=0000000013ecc400 nid=0xb1944000 in Object.wait() [00000000b1943000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor.run(Executor.java:106)
- locked <000000001d2490f0> (a org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor)

"Java indexing" daemon prio=4 tid=0000000013245400 nid=0xb1740000 in Object.wait() [00000000b173f000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at org.eclipse.jdt.internal.core.search.processing.JobManager.run(JobManager.java:381)
- locked <000000001a9e2048> (a org.eclipse.jdt.internal.core.search.indexing.IndexManager)
at java.lang.Thread.run(Thread.java:637)

"[Timer] - Main Queue Handler" daemon prio=5 tid=000000001311c400 nid=0xb143a000 in Object.wait() [00000000b1439000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.eclipse.equinox.internal.util.impl.tpt.timer.TimerImpl.run(TimerImpl.java:141)
- locked <000000001831a4f8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:637)

"Framework Event Dispatcher" daemon prio=5 tid=0000000013103000 nid=0xb1236000 in Object.wait() [00000000b1235000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.getNextEvent(EventManager.java:397)
- locked <0000000018301670> (a org.eclipse.osgi.framework.eventmgr.EventManager$EventThread)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:333)

"Start Level Event Dispatcher" daemon prio=5 tid=0000000013927400 nid=0xb1134000 in Object.wait() [00000000b1133000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <00000000181e6048> (a org.eclipse.osgi.framework.eventmgr.EventManager$EventThread)
at java.lang.Object.wait(Object.java:485)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.getNextEvent(EventManager.java:397)
- locked <00000000181e6048> (a org.eclipse.osgi.framework.eventmgr.EventManager$EventThread)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:333)

"Bundle File Closer" daemon prio=5 tid=00000000130fa400 nid=0xb1032000 in Object.wait() [00000000b1031000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.getNextEvent(EventManager.java:397)
- locked <00000000180dc620> (a org.eclipse.osgi.framework.eventmgr.EventManager$EventThread)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:333)

"State Data Manager" daemon prio=5 tid=00000000130f9c00 nid=0xb0f30000 waiting on condition [00000000b0f2f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.eclipse.osgi.internal.baseadaptor.StateManager.run(StateManager.java:306)
at java.lang.Thread.run(Thread.java:637)

"Poller SunPKCS11-Darwin" daemon prio=1 tid=00000000130dc000 nid=0xb0e25000 waiting on condition [00000000b0e24000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at sun.security.pkcs11.SunPKCS11$TokenPoller.run(SunPKCS11.java:692)
at java.lang.Thread.run(Thread.java:637)

"Low Memory Detector" daemon prio=5 tid=00000000130bac00 nid=0xb0c21000 runnable [0000000000000000]
   java.lang.Thread.State: RUNNABLE

"CompilerThread0" daemon prio=9 tid=00000000130b9c00 nid=0xb0b17000 waiting on condition [0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=9 tid=00000000130b9000 nid=0xb0a15000 waiting on condition [0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Surrogate Locker Thread (CMS)" daemon prio=5 tid=00000000130b8000 nid=0xb0913000 waiting on condition [0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=8 tid=00000000130aa400 nid=0xb0811000 in Object.wait() [00000000b0810000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0000000018010020> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=10 tid=00000000130a9800 nid=0xb070f000 in Object.wait() [00000000b070e000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0000000018013020> (a java.lang.ref.Reference$Lock)

"main" prio=6 tid=0000000013000800 nid=0xa0ac2500 waiting for monitor entry [00000000bfff9000]
   java.lang.Thread.State: BLOCKED (on object monitor)
at org.eclipse.core.internal.filebuffers.SynchronizableDocument.get(SynchronizableDocument.java:139)
- waiting to lock <000000001a209448> (a java.lang.Object)
at org.eclipse.jface.text.projection.ProjectionTextStore.get(ProjectionTextStore.java:148)
at org.eclipse.jface.text.AbstractDocument.get(AbstractDocument.java:1005)
at org.eclipse.jface.text.DefaultDocumentAdapter.doGetLine(DefaultDocumentAdapter.java:150)
at org.eclipse.jface.text.DefaultDocumentAdapter.getLine(DefaultDocumentAdapter.java:173)
at org.eclipse.swt.custom.StyledTextRenderer.drawLine(StyledTextRenderer.java:356)
at org.eclipse.swt.custom.StyledText.handlePaint(StyledText.java:5965)
at org.eclipse.swt.custom.StyledText$7.handleEvent(StyledText.java:5547)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:3543)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1250)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1273)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1258)
at org.eclipse.swt.widgets.Control.drawWidget(Control.java:1079)
at org.eclipse.swt.widgets.Canvas.drawWidget(Canvas.java:158)
at org.eclipse.swt.widgets.Widget.drawRect(Widget.java:589)
at org.eclipse.swt.widgets.Canvas.drawRect(Canvas.java:153)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:4635)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
at org.eclipse.swt.widgets.Display.applicationNextEventMatchingMask(Display.java:4188)
at org.eclipse.swt.widgets.Display.applicationProc(Display.java:4386)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
at org.eclipse.swt.internal.cocoa.NSApplication.nextEventMatchingMask(NSApplication.java:75)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3094)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2405)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:368)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514)
at org.eclipse.equinox.launcher.Main.run(Main.java:1311)

iulian dragos

unread,
Sep 9, 2010, 8:05:38 AM9/9/10
to scala-...@googlegroups.com, martin odersky, Eugene Vigdorchik, Plociniczak Hubert
I think I found it: the main threads waits for the lock that the reconciler thread has acquired in in the call to ScalaSourceFile.withDocument, and in turn it waits after the Scala presentation compiler in a call to SyncVar. Maybe the two threads could use finer-grained locking?

iulian

Miles Sabin

unread,
Sep 9, 2010, 8:12:17 AM9/9/10
to scala-...@googlegroups.com, martin odersky, Eugene Vigdorchik, Plociniczak Hubert
On Thu, Sep 9, 2010 at 1:05 PM, iulian dragos <jagu...@gmail.com> wrote:
> I think I found it: the main threads waits for the lock that the reconciler
> thread has acquired in in the call to ScalaSourceFile.withDocument, and in
> turn it waits after the Scala presentation compiler in a call to SyncVar.
> Maybe the two threads could use finer-grained locking?

Yes, that sounds about right to me ... either that or tweaking the
lock order. The tricky part here is that we don't have control over
Eclipse's locking strategy, so shoehorning our own in isn't always
straightforward.

If you could create a ticket for this with the stack trace attached
that would be very helpful.

iulian dragos

unread,
Sep 9, 2010, 9:21:16 AM9/9/10
to scala-...@googlegroups.com


On Thu, Sep 9, 2010 at 2:12 PM, Miles Sabin <mi...@milessabin.com> wrote:
On Thu, Sep 9, 2010 at 1:05 PM, iulian dragos <jagu...@gmail.com> wrote:
> I think I found it: the main threads waits for the lock that the reconciler
> thread has acquired in in the call to ScalaSourceFile.withDocument, and in
> turn it waits after the Scala presentation compiler in a call to SyncVar.
> Maybe the two threads could use finer-grained locking?

Yes, that sounds about right to me ... either that or tweaking the
lock order. The tricky part here is that we don't have control over
Eclipse's locking strategy, so shoehorning our own in isn't always
straightforward.

If you could create a ticket for this with the stack trace attached
that would be very helpful.


 

Cheers,


Miles

--
Miles Sabin
tel: +44 7813 944 528
gtalk: mi...@milessabin.com
skype: milessabin
http://www.chuusai.com/



-- 
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais

martin odersky

unread,
Sep 10, 2010, 5:38:44 AM9/10/10
to iulian dragos, scala-...@googlegroups.com, Eugene Vigdorchik, Plociniczak Hubert
Let me see if I get this right:

UI thread calls reconciler thread, presumably after some (short) quiescence period, and blocks until it is finished.

Reconciler thread calls presentation compiler thread and waits until it is finished.

Presentation compiler takes a long time -> IDE hangs.

Right so far? If yes, I see only two ways out of it:

UI thread does not block until reconciler is finished (not sure Eclipse lets us do that).

Reconciler does not issue a blocking call to presentation compiler. That's probably where we CAN do something.

In essence, EVERY askXXX call to the presentation compiler should follow
the scheme in the doc comment of the Response class. If that's not possible,
(say because the reconciler thread does not know whether there's further use input) we need to work with a different scheme. Probably let teh presentation compiler produce the index incrmentally and just pass to the reconciler the current status when asked without typechecking anything.

Cheers

 -- Martin




On Thu, Sep 9, 2010 at 3:19 PM, iulian dragos <iulian...@epfl.ch> wrote:


On Thu, Sep 9, 2010 at 2:12 PM, Miles Sabin <mi...@milessabin.com> wrote:
On Thu, Sep 9, 2010 at 1:05 PM, iulian dragos <jagu...@gmail.com> wrote:
> I think I found it: the main threads waits for the lock that the reconciler
> thread has acquired in in the call to ScalaSourceFile.withDocument, and in
> turn it waits after the Scala presentation compiler in a call to SyncVar.
> Maybe the two threads could use finer-grained locking?

Yes, that sounds about right to me ... either that or tweaking the
lock order. The tricky part here is that we don't have control over
Eclipse's locking strategy, so shoehorning our own in isn't always
straightforward.

If you could create a ticket for this with the stack trace attached
that would be very helpful.

 

Cheers,


Miles

--
Miles Sabin
tel: +44 7813 944 528
gtalk: mi...@milessabin.com
skype: milessabin
http://www.chuusai.com/
http://twitter.com/milessabin

Miles Sabin

unread,
Sep 10, 2010, 5:53:43 AM9/10/10
to scala-...@googlegroups.com, iulian dragos, Eugene Vigdorchik, Plociniczak Hubert
On Fri, Sep 10, 2010 at 10:38 AM, martin odersky <martin....@epfl.ch> wrote:
> Let me see if I get this right:
>
> UI thread calls reconciler thread, presumably after some (short) quiescence
> period, and blocks until it is finished.
>
> Reconciler thread calls presentation compiler thread and waits until it is
> finished.
>
> Presentation compiler takes a long time -> IDE hangs.
>
> Right so far?

Not quite. In general the UI thread doesn't wait for the reconciler
thread. However, in Iulian's case there is an unintentionally shared
lock which is held by the SDT in the reconciler thread while the
presentation compiler is working ... and it's this lock which the UI
thread is blocking on.

The solution is to avoid having the SDT hold this lock ... I have a
fix for that which I'll commit shortly.

David Bernard

unread,
Sep 11, 2010, 12:41:49 PM9/11/10
to scala-...@googlegroups.com
A cause of UI and Reconciler interdependency is the Completion (... Quick Fix). Because JDT completion request update on the CompilationUnit. So simple navigation with arrow mouse ... generate useless
request to compiler and freeze.
By default JDT auto-completion/auto-suggestion is ON.

/davidB

martin odersky

unread,
Sep 14, 2010, 11:19:35 AM9/14/10
to iulian dragos, scala-...@googlegroups.com, Eugene Vigdorchik, Plociniczak Hubert
Iulian and I had a closer look at it. It is indeed a serious problem. Basically the reconciler will
force a re-typecheck of some loaded files and block the UI thread until it is finished. There's some caching going on, so I am not sure which files are affected. Only those files that have changed since last reconcile or all files? Miles can you shed some light on the matter?

But in any case, even a single long file puts too much strain on the system, as Iulian experienced.
I believe not locking the UI thread is _not_ the right solution here, because even with an unlocked UI thread the presentation compiler would still be unresponsive for arbitrary lengths of time (during which it compiles structure info). What we need to do instead is have a fast call into the presentation compiler instead of a blocking one.

Essentially the goal of the reconciler is to let the indexing system catch up if the user stops typing for a while. The pause might be sufficient to get the presentation compiler into quiescent state, in which case all is fine. But if it is not, the bad things Iulian experienced happen.

So we need to change strategy. Instead of imposing on the presentation compiler an answer and blocking until we get it we should let the presentation compiler get the answer at its own pace.

I believe what we should do is let the presentation compiler maintain structure info. That way,
it can opportunistically always return the last compiled structure info that it found. If the pause was long enough and the file short enough so that the presentation compiler is in quiescent state when asked
one gets the up to date info. Otherwise the info that was computed last. For a completely fresh file, there is no last info. In that case, the presentation compiler can do a cursory top-level indexing to satisfy the indexer. The primary goal should be in each case not to block!

So this means that the interface to the presentation compiler will have to change. Essentially, the
StructureTraverser cannot work off a typed tree anymore because that tree might not exist.
Instead the presentation compiler should return its own version of the structure. But we want to avoid any Eclipse specifics. So I propose the presentation compiler will produce an abstract structure info in terms of symbol table entries.Something like this should do:

class StructureElement(sym: Symbol, nested: Seq[StructureElement])

The structure traverser would then work off the Seq of top-level StructureElements.

How does that sound?If we agree to proceed this way, I am happy to add the necessary bits to the presentation compiler. Who can do the IDE end?

Cheers

 -- Martin

Miles Sabin

unread,
Sep 14, 2010, 1:05:47 PM9/14/10
to scala-...@googlegroups.com, iulian dragos, Eugene Vigdorchik, Plociniczak Hubert, martin....@epfl.ch
On Tue, Sep 14, 2010 at 4:19 PM, martin odersky <martin....@epfl.ch> wrote:
> Iulian and I had a closer look at it. It is indeed a serious problem.
> Basically the reconciler will force a re-typecheck of some loaded files and
> block the UI thread until it is finished. There's some caching going on, so I
> am not sure which files are affected. Only those files that have changed since
> last reconcile or all files? Miles can you shed some light on the matter?

Only the changed files.

> But in any case, even a single long file puts too much strain on the system,
> as Iulian experienced.
> I believe not locking the UI thread is _not_ the right solution here,
> because even with an unlocked UI thread the presentation compiler would
> still be unresponsive for arbitrary lengths of time (during which it
> compiles structure info). What we need to do instead is have a fast call
> into the presentation compiler instead of a blocking one.

Locking out the UI thread is the wrong thing to be doing, even if it's
not the complete solution to the responsiveness problem. I agree that
fast calls into the presentation compiler would be ideal.

> Essentially the goal of the reconciler is to let the indexing system catch
> up if the user stops typing for a while.

Not just the indexer. The reconciler synchronizes all Eclipse's models
with the current state of the source text. That includes the index,
but it also includes things like the structure navigators (ie. the
outline view and the package explorer) and it updates semantic
highlighting, override indicators, inline error reporting etc., etc.
... in summary, the reconciler drives pretty much all of Eclipse's
semantic feedback.

> The pause might be sufficient to get the presentation compiler into
> quiescent state, in which case all is fine. But if it is not, the bad
> things Iulian experienced happen.
>
> So we need to change strategy. Instead of imposing on the presentation
> compiler an answer and blocking until we get it we should let the
> presentation compiler get the answer at its own pace.
>
> I believe what we should do is let the presentation compiler maintain
> structure info. That way, it can opportunistically always return the last
> compiled structure info that it found. If the pause was long enough and the
> file short enough so that the presentation compiler is in quiescent state
> when asked one gets the up to date info. Otherwise the info that was computed
> last. For a completely fresh file, there is no last info. In that case, the
> presentation compiler can do a cursory top-level indexing to satisfy the
> indexer. The primary goal should be in each case not to block!

One thing to think about here is that essentially any keystroke will
invalidate both cached information and any in-progress typer run. It's
the typer runs which are the expensive item, so really what we need to
be able to do is immediately cancel the reconcilers typer run whenever
a new keystroke comes in.

I like the idea of having old information reported if fresh
information hasn't been computed within a configurable deadline. That
depends on us being able to keep cached ASTs and use them safely. I
think progess in that area would be extremely valuable ... see below
...

> So this means that the interface to the presentation compiler will have to
> change. Essentially, the StructureTraverser cannot work off a typed tree
> anymore because that tree might not exist.
> Instead the presentation compiler should return its own version of the
> structure. But we want to avoid any Eclipse specifics. So I propose the
> presentation compiler will produce an abstract structure info in terms of
> symbol table entries.Something like this should do:
>
> class StructureElement(sym: Symbol, nested: Seq[StructureElement])
>
> The structure traverser would then work off the Seq of top-level
> StructureElements.
>
> How does that sound?If we agree to proceed this way, I am happy to add the
> necessary bits to the presentation compiler. Who can do the IDE end?

I'm not sure. It sounds very drastic and I'm not convinced that the
gain will outweigh the cost of the upheaval (bear in mind that many
tools, eg. Mirko's refactoring stuff, depend on access to scalac ASTs
and would also need to be rewritten). I would much prefer it if we
could stick with the present ASTs, but have them fully forced in the
background and rely on the strategy of falling back to stale (but
again fully forced) information as mentioned earlier.

Whatever we do here, I'd like to see the interactive components of the
compiler split out to a separate module, so that they can be upgraded
independently from the main scala distribution.

David Bernard

unread,
Sep 14, 2010, 1:49:12 PM9/14/10
to scala-...@googlegroups.com, iulian dragos, Eugene Vigdorchik, Plociniczak Hubert, martin....@epfl.ch

In july, I image a similar/mixed solution, but I'd not find time to explore since (in the wip_branch) :
* buffering request to update AST, and execute update only after a (configurable) idle time since last request
  => to avoid compilation when typing, it's better to have error at end of typing than during typing (with freeze)
* request to access AST, retreive the last fully computed AST (if exists), but doesn't force update of it (at least can request an async update)
* buffered request to update AST, as they 'll aggregated into one real update should return the same Promise (in charge to collect post-job and avoid duplicate post-job)
* provide a button to end-user
 * to disable on-fly update of AST and C°
 * to force update (like a clean + build) but for current file

This stuff (from my overview) could be done/explore on eclipse side, and then include in scalac (itself or a additionnal "module").
The developement could help to specify the scalac api. What I want to avoid (as end-user) it's to have a eclipse plugin that works only with scalac-trunk.

About public AST api (like Scaladoc2 did) proposed by Martin I'm +1, but I'm +3 for Miles point of view, Scala-IDE need to be stabilized (usage and feature), not to regress again. (note that this should be the same AST api for scalac plugin,...). In the case of Scaladoc, only vscaladoc was break by the change, and as vscaladoc is only an alternative , not an additional feature (like plugins, or Mirko stuff, also used by ENSIME), there is no big loose for user.

I hope to be readable. 

/davidB

Miles Sabin

unread,
Sep 15, 2010, 5:45:18 PM9/15/10
to scala-...@googlegroups.com, Iulian Dragos
On Thu, Sep 9, 2010 at 2:21 PM, iulian dragos <jagu...@gmail.com> wrote:
>> Yes, that sounds about right to me ... either that or tweaking the
>> lock order. The tricky part here is that we don't have control over
>> Eclipse's locking strategy, so shoehorning our own in isn't always
>> straightforward.
>>
>> If you could create a ticket for this with the stack trace attached
>> that would be very helpful.
>
> Done!
>
> http://www.assembla.com/spaces/scala-ide/tickets/1000160-ui-blocks-every-keystrokes-on-larger-files-(main-thread-waits-for-presentation-compiler)

OK, I've put together a patch which takes the strategy I sketched in
the ticket linked to above. The result is the update site here,

http://download.scala-ide.org/nightly-update-wip-responsiveness-2.8.0.final/

(this is relative to Eclipse Galileo, and Scala 2.8.0.final).

For comparison I tried editing scala/tools/nsc/typechecker/Typer.scala
(at the beginning, in the middle and at the end) with the master
2.8.0.final build. This is a large and complex source file (> 4000
lines) and, as Iulian described, the lockout when the reconciler kicks
in is quite noticeable (only about .5 sec on my machine with this
file, but long enough to be annoying).

With the patch applied I would say the experience is noticeably
better: editing this file is still a little sluggish (again, on my
machine, YMMV) but I would say just about acceptable.

I would be very interested to get feedback on the patched build from
anyone who has been suffering from these pauses.

Mirko Stocker

unread,
Sep 16, 2010, 4:19:35 AM9/16/10
to scala-...@googlegroups.com
Hi Martin, Miles

On Tuesday 14 September 2010 19:05:47 Miles Sabin wrote:
> I'm not sure. It sounds very drastic and I'm not convinced that the
> gain will outweigh the cost of the upheaval (bear in mind that many
> tools, eg. Mirko's refactoring stuff, depend on access to scalac ASTs
> and would also need to be rewritten). I would much prefer it if we
> could stick with the present ASTs, but have them fully forced in the
> background and rely on the strategy of falling back to stale (but
> again fully forced) information as mentioned earlier.

I'm not sure I completely understand the proposed changes yet. Is the idea to
just emit those StructureElements while the presentation compiler is still
running and to provide the full scalac AST once he's done? In that case, the
refactorings shouldn't care much because they would want to have a completely
type checked AST anyway and just wait for the result to be available.

Cheers

Mirko


PS: I was at the Herbstcampus in N�rnberg this week and talked to several
people who looked into Scala and want to use it, and the main problem they
have is the unstable IDE support. One guy even re-started a Scala project in
Java :-(

iulian dragos

unread,
Sep 16, 2010, 6:04:55 AM9/16/10
to Miles Sabin, scala-...@googlegroups.com
On Wed, Sep 15, 2010 at 11:45 PM, Miles Sabin <mi...@milessabin.com> wrote:
On Thu, Sep 9, 2010 at 2:21 PM, iulian dragos <jagu...@gmail.com> wrote:
>> Yes, that sounds about right to me ... either that or tweaking the
>> lock order. The tricky part here is that we don't have control over
>> Eclipse's locking strategy, so shoehorning our own in isn't always
>> straightforward.
>>
>> If you could create a ticket for this with the stack trace attached
>> that would be very helpful.
>
> Done!
>
> http://www.assembla.com/spaces/scala-ide/tickets/1000160-ui-blocks-every-keystrokes-on-larger-files-(main-thread-waits-for-presentation-compiler)

OK, I've put together a patch which takes the strategy I sketched in
the ticket linked to above. The result is the update site here,

 http://download.scala-ide.org/nightly-update-wip-responsiveness-2.8.0.final/

(this is relative to Eclipse Galileo, and Scala 2.8.0.final).

Great! I just downloaded it and had a mixed experience... Editing is much much smoother, even on my machine.

One problem I noticed is the startup time, when again the UI thread was blocked waiting for the presentation compiler. The annoying thing is that during this time (10-15 seconds) not even the menu is accessible. Here's the stack trace:

"main" prio=6 tid=0000000013001000 nid=0xa0ac2500 in Object.wait() [00000000bfffd000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0000000015f169f0> (a scala.concurrent.SyncVar)
at java.lang.Object.wait(Object.java:485)
at scala.concurrent.SyncVar.get(SyncVar.scala:25)
- locked <0000000015f169f0> (a scala.concurrent.SyncVar)
at scala.tools.eclipse.ScalaPresentationCompiler$CachedCompilerResult$$anon$3.<init>(ScalaPresentationCompiler.scala:73)
at scala.tools.eclipse.ScalaPresentationCompiler$CachedCompilerResult.create(ScalaPresentationCompiler.scala:67)
at scala.tools.eclipse.ScalaPresentationCompiler$CachedCompilerResult.create(ScalaPresentationCompiler.scala:64)
at scala.tools.eclipse.util.Cached$class.apply(Cached.scala:44)
at scala.tools.eclipse.ScalaPresentationCompiler$CachedCompilerResult.apply(ScalaPresentationCompiler.scala:64)
at scala.tools.eclipse.ScalaPresentationCompiler.withCompilerResult(ScalaPresentationCompiler.scala:97)
at scala.tools.eclipse.ScalaProject$$anonfun$withCompilerResult$1.apply(ScalaProject.scala:369)
at scala.tools.eclipse.ScalaProject$$anonfun$withCompilerResult$1.apply(ScalaProject.scala:368)
at scala.tools.eclipse.util.Cached$$anonfun$apply$1.apply$mcV$sp(Cached.scala:22)
at scala.tools.eclipse.util.Cached$$anonfun$apply$1.apply(Cached.scala:21)
at scala.tools.eclipse.util.Cached$$anonfun$apply$1.apply(Cached.scala:21)
at scala.tools.eclipse.util.Cached$class.locked(Cached.scala:83)
at scala.tools.eclipse.util.Cached$class.apply(Cached.scala:20)
at scala.tools.eclipse.ScalaProject$$anon$1.apply(ScalaProject.scala:40)
at scala.tools.eclipse.ScalaProject.withPresentationCompiler(ScalaProject.scala:364)
at scala.tools.eclipse.ScalaProject.withCompilerResult(ScalaProject.scala:368)
at scala.tools.eclipse.javaelements.ScalaCompilationUnit$class.withCompilerResult(ScalaCompilationUnit.scala:58)
at scala.tools.eclipse.javaelements.ScalaSourceFile.withCompilerResult(ScalaSourceFile.scala:40)
at scala.tools.eclipse.javaelements.ScalaCompilationUnit$class.buildStructure(ScalaCompilationUnit.scala:103)
at scala.tools.eclipse.javaelements.ScalaSourceFile.buildStructure(ScalaSourceFile.scala:40)
at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:258)
at org.eclipse.jdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:515)
at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:252)
at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:238)
at org.eclipse.jdt.internal.core.JavaElement.getChildren(JavaElement.java:193)
at scala.tools.eclipse.javaelements.ScalaSourceFile.getCorrespondingElement(ScalaSourceFile.scala:96)
at scala.tools.eclipse.javaelements.ScalaSourceFile.getType(ScalaSourceFile.scala:102)
at org.eclipse.jdt.internal.core.JavaModelManager.secondaryTypesSearching(JavaModelManager.java:4324)
at org.eclipse.jdt.internal.core.JavaModelManager.secondaryTypes(JavaModelManager.java:4179)
at org.eclipse.jdt.internal.core.NameLookup.findSecondaryType(NameLookup.java:595)
at org.eclipse.jdt.internal.core.NameLookup.findType(NameLookup.java:697)
at org.eclipse.jdt.internal.core.NameLookup.findType(NameLookup.java:621)
at org.eclipse.jdt.internal.core.SearchableEnvironment.find(SearchableEnvironment.java:101)
at org.eclipse.jdt.internal.core.SearchableEnvironment.findType(SearchableEnvironment.java:287)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.askForType(LookupEnvironment.java:127)
at org.eclipse.jdt.internal.compiler.lookup.PackageBinding.getType(PackageBinding.java:127)
at org.eclipse.jdt.internal.compiler.lookup.PackageBinding.isViewedAsDeprecated(PackageBinding.java:211)
at org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding.isViewedAsDeprecated(ReferenceBinding.java:1206)
at org.eclipse.jdt.internal.compiler.lookup.ClassScope.checkAndSetModifiers(ClassScope.java:405)
at org.eclipse.jdt.internal.compiler.lookup.ClassScope.buildType(ClassScope.java:361)
at org.eclipse.jdt.internal.compiler.lookup.ClassScope.buildMemberTypes(ClassScope.java:264)
at org.eclipse.jdt.internal.compiler.lookup.ClassScope.buildType(ClassScope.java:363)
at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.buildTypeBindings(CompilationUnitScope.java:144)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.buildTypeBindings(LookupEnvironment.java:152)
at scala.tools.eclipse.contribution.weaving.jdt.core.DOMAspect.ajc$around$scala_tools_eclipse_contribution_weaving_jdt_core_DOMAspect$1$3b9eae81(DOMAspect.aj:118)
at org.eclipse.jdt.core.dom.ASTParser.internalCreateAST(ASTParser.java:823)
at org.eclipse.jdt.core.dom.ASTParser.createAST(ASTParser.java:677)
at org.eclipse.jdt.internal.ui.text.correction.ASTResolving.createQuickFixAST(ASTResolving.java:1126)
at org.eclipse.jdt.internal.ui.text.correction.AssistContext.getASTRoot(AssistContext.java:115)
at org.eclipse.jdt.internal.ui.text.java.hover.ProblemHover$ProblemInfo.getJavaAnnotationFixes(ProblemHover.java:212)
at org.eclipse.jdt.internal.ui.text.java.hover.ProblemHover$ProblemInfo.getCompletionProposals(ProblemHover.java:192)
at org.eclipse.jdt.internal.ui.text.java.hover.AbstractAnnotationHover$AnnotationInformationControl.deferredCreateContent(AbstractAnnotationHover.java:275)
at org.eclipse.jdt.internal.ui.text.java.hover.AbstractAnnotationHover$AnnotationInformationControl.setInput(AbstractAnnotationHover.java:181)
at org.eclipse.jface.text.AbstractInformationControlManager.internalShowInformationControl(AbstractInformationControlManager.java:1170)
at org.eclipse.jface.text.AbstractInformationControlManager.presentInformation(AbstractInformationControlManager.java:1139)
at org.eclipse.jface.text.AbstractHoverInformationControlManager.presentInformation(AbstractHoverInformationControlManager.java:902)
at org.eclipse.jface.text.TextViewerHoverManager.doPresentInformation(TextViewerHoverManager.java:243)
at org.eclipse.jface.text.TextViewerHoverManager$5.run(TextViewerHoverManager.java:233)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
- locked <00000000239ac418> (a org.eclipse.swt.widgets.RunnableLock)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3405)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3102)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2405)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:368)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514)
at org.eclipse.equinox.launcher.Main.run(Main.java:1311)
For comparison I tried editing scala/tools/nsc/typechecker/Typer.scala
(at the beginning, in the middle and at the end) with the master
2.8.0.final build. This is a large and complex source file (> 4000
lines) and, as Iulian described, the lockout when the reconciler kicks
in is quite noticeable (only about .5 sec on my machine with this
file, but long enough to be annoying).

With the patch applied I would say the experience is noticeably
better: editing this file is still a little sluggish (again, on my
machine, YMMV) but I would say just about acceptable.

I would be very interested to get feedback on the patched build from
anyone who has been suffering from these pauses.

Cheers,


Miles

--
Miles Sabin
tel: +44 7813 944 528
gtalk: mi...@milessabin.com
skype: milessabin
http://www.chuusai.com/
http://twitter.com/milessabin

iulian dragos

unread,
Sep 16, 2010, 6:10:16 AM9/16/10
to Miles Sabin, scala-...@googlegroups.com
..and I stepped on this bug:


the completion (always?) throws this runtime exception, which is extremely annoying because for some reason Eclipse thinks I care a lot about it, and puts a modal dialog in front of my nose, which goes away only when I click on it. It does so twice for each completion attempt...

iulian

Miles Sabin

unread,
Sep 16, 2010, 6:10:48 AM9/16/10
to iulian dragos, scala-...@googlegroups.com
On Thu, Sep 16, 2010 at 11:04 AM, iulian dragos <jagu...@gmail.com> wrote:
> On Wed, Sep 15, 2010 at 11:45 PM, Miles Sabin <mi...@milessabin.com> wrote:
>> OK, I've put together a patch which takes the strategy I sketched in
>> the ticket linked to above. The result is the update site here,
>>
>>  http://download.scala-ide.org/nightly-update-wip-responsiveness-2.8.0.final/
>>
>> (this is relative to Eclipse Galileo, and Scala 2.8.0.final).
>
> Great! I just downloaded it and had a mixed experience... Editing is much
> much smoother, even on my machine.

Excellent! :-)

> One problem I noticed is the startup time, when again the UI thread was
> blocked waiting for the presentation compiler. The annoying thing is that
> during this time (10-15 seconds) not even the menu is accessible. Here's the
> stack trace:

Is this definitely a regression relative to the ordinary 2.8.0.final
build? Or just something you'd not noticed previously? In any case,
I'll take a look.

iulian dragos

unread,
Sep 16, 2010, 6:12:40 AM9/16/10
to Miles Sabin, scala-...@googlegroups.com
On Thu, Sep 16, 2010 at 12:10 PM, Miles Sabin <mi...@milessabin.com> wrote:
On Thu, Sep 16, 2010 at 11:04 AM, iulian dragos <jagu...@gmail.com> wrote:
> On Wed, Sep 15, 2010 at 11:45 PM, Miles Sabin <mi...@milessabin.com> wrote:
>> OK, I've put together a patch which takes the strategy I sketched in
>> the ticket linked to above. The result is the update site here,
>>
>>  http://download.scala-ide.org/nightly-update-wip-responsiveness-2.8.0.final/
>>
>> (this is relative to Eclipse Galileo, and Scala 2.8.0.final).
>
> Great! I just downloaded it and had a mixed experience... Editing is much
> much smoother, even on my machine.

Excellent! :-)

> One problem I noticed is the startup time, when again the UI thread was
> blocked waiting for the presentation compiler. The annoying thing is that
> during this time (10-15 seconds) not even the menu is accessible. Here's the
> stack trace:

Is this definitely a regression relative to the ordinary 2.8.0.final
build? Or just something you'd not noticed previously? In any case,
I'll take a look.

Actually, I don't think it's a regression.. probably I was hovering on something. It was just a bit annoying I had to wait so long, and there was no way to cancel the job.

Anyway, editing is really possible again for large files, and that's a very big plus! 

Thanks!
iulian
 

Cheers,


Miles

--
Miles Sabin
tel: +44 7813 944 528
gtalk: mi...@milessabin.com
skype: milessabin
http://www.chuusai.com/
http://twitter.com/milessabin

Miles Sabin

unread,
Sep 16, 2010, 6:15:11 AM9/16/10
to iulian dragos, scala-...@googlegroups.com
On Thu, Sep 16, 2010 at 11:12 AM, iulian dragos <jagu...@gmail.com> wrote:
> On Thu, Sep 16, 2010 at 12:10 PM, Miles Sabin <mi...@milessabin.com> wrote:
>> On Thu, Sep 16, 2010 at 11:04 AM, iulian dragos <jagu...@gmail.com>
>> > One problem I noticed is the startup time, when again the UI thread was
>> > blocked waiting for the presentation compiler. The annoying thing is
>> > that
>> > during this time (10-15 seconds) not even the menu is accessible. Here's
>> > the
>> > stack trace:
>>
>> Is this definitely a regression relative to the ordinary 2.8.0.final
>> build? Or just something you'd not noticed previously? In any case,
>> I'll take a look.
>
> Actually, I don't think it's a regression.. probably I was hovering on
> something. It was just a bit annoying I had to wait so long, and there was
> no way to cancel the job.

OK, that's good to know. I think we should be able to do something
about this one.

> Anyway, editing is really possible again for large files, and that's a very
> big plus!

Cool ... if you don't have any nasty regression to report by the end
of the day I'll merge this into master.

Reply all
Reply to author
Forward
0 new messages