summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2011-06-29 10:27:23 +0000
committerIulian Dragos <jaguarul@gmail.com>2011-06-29 10:27:23 +0000
commit7a1dc55abe5c50dae3c7a0990f852c40408454e7 (patch)
treec9f794ba95a522240f732b18f9976fe805a648e0 /src/compiler
parente0a4bbdb39795ed43e487f5ef89e37518eeb6ee9 (diff)
downloadscala-7a1dc55abe5c50dae3c7a0990f852c40408454e7.tar.gz
scala-7a1dc55abe5c50dae3c7a0990f852c40408454e7.tar.bz2
scala-7a1dc55abe5c50dae3c7a0990f852c40408454e7.zip
Check that 'info' is only called on the present...
Check that 'info' is only called on the presentation compiler thread. This is a temporary debugging option for the presentation compiler. no review.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala4
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala3
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala36
4 files changed, 36 insertions, 8 deletions
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala
index 5c4d44f735..dd0994a1f6 100644
--- a/src/compiler/scala/reflect/internal/SymbolTable.scala
+++ b/src/compiler/scala/reflect/internal/SymbolTable.scala
@@ -31,6 +31,10 @@ abstract class SymbolTable extends /*reflect.generic.Universe
def abort(msg: String): Nothing = throw new Error(msg)
def abort(): Nothing = throw new Error()
+ /** Check that the executing thread is the compiler thread. No-op here,
+ * overridden in interactive.Global. */
+ def assertCorrectThread() {}
+
/** Are we compiling for Java SE? */
// def forJVM: Boolean
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index ff3677c104..2b04f479ed 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -778,6 +778,7 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
}
val current = phase
try {
+ assertCorrectThread()
phase = phaseOf(infos.validFrom)
tp.complete(this)
} finally {
@@ -828,11 +829,13 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
val curPid = phaseId(curPeriod)
if (validTo != NoPeriod) {
+
// skip any infos that concern later phases
while (curPid < phaseId(infos.validFrom) && infos.prev != null)
infos = infos.prev
if (validTo < curPeriod) {
+ assertCorrectThread()
// adapt any infos that come from previous runs
val current = phase
try {
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index f0497ca37d..0080cc98fc 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -107,6 +107,7 @@ trait Types /*extends reflect.generic.Types*/ { self: SymbolTable =>
/** Undo all changes to constraints to type variables upto `limit`. */
private def undoTo(limit: UndoLog) {
+ assertCorrectThread()
while ((log ne limit) && log.nonEmpty) {
val (tv, constr) = log.head
tv.constr = constr
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index af5b9a9882..d61edcc654 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -24,13 +24,17 @@ import symtab.Flags.{ACCESSOR, PARAMACCESSOR}
/** The main class of the presentation compiler in an interactive environment such as an IDE
*/
-class Global(settings: Settings, reporter: Reporter, projectName: String = "")
- extends scala.tools.nsc.Global(settings, reporter)
- with CompilerControl
- with RangePositions
- with ContextTrees
- with RichCompilationUnits
- with Picklers {
+class Global(settings: Settings, reporter: Reporter, projectName: String = "") extends {
+ /** Is the compiler initializing? Early def, so that the field is true during the
+ * execution of the super constructor.
+ */
+ private var initializing = true
+} with scala.tools.nsc.Global(settings, reporter)
+ with CompilerControl
+ with RangePositions
+ with ContextTrees
+ with RichCompilationUnits
+ with Picklers {
import definitions._
@@ -386,7 +390,17 @@ class Global(settings: Settings, reporter: Reporter, projectName: String = "")
private var threadId = 0
/** The current presentation compiler runner */
- @volatile private[interactive] var compileRunner = newRunnerThread()
+ @volatile private[interactive] var compileRunner: Thread = newRunnerThread()
+
+ /** Check that the currenyly executing thread is the presentation compiler thread.
+ *
+ * Compiler initialization may happen on a different thread (signalled by globalPhase being NoPhase)
+ */
+ override def assertCorrectThread() {
+ assert(initializing || (Thread.currentThread() eq compileRunner),
+ "Race condition detected: You are running a presentation compiler method outside the PC thread.[phase: %s]".format(globalPhase) +
+ " Please file a ticket with the current stack trace at https://www.assembla.com/spaces/scala-ide/support/tickets")
+ }
/** Create a new presentation compiler runner.
*/
@@ -968,6 +982,12 @@ class Global(settings: Settings, reporter: Reporter, projectName: String = "")
alt
}
}
+
+ /** The compiler has been initialized. Constructors are evaluated in textual order,
+ * so this is set to true only after all super constructors and the primary constructor
+ * have been executed.
+ */
+ initializing = false
}
object CancelException extends Exception