summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-02-28 15:34:01 -0800
committerPaul Phillips <paulp@improving.org>2012-02-28 15:34:01 -0800
commit872c825192b30faa1b20f9cc2b1e3a0adeed8617 (patch)
tree17ec63094bbf9dd56d45aee4e4add0c784ecc4c1 /src
parent4ab3600298de995e7de6d5cfdce73e0f278341e2 (diff)
parent01ee3de96dcae707fb8fee28e93af0515519c603 (diff)
downloadscala-872c825192b30faa1b20f9cc2b1e3a0adeed8617.tar.gz
scala-872c825192b30faa1b20f9cc2b1e3a0adeed8617.tar.bz2
scala-872c825192b30faa1b20f9cc2b1e3a0adeed8617.zip
Merge remote-tracking branch 'szabolcsberecz/SI-64' into SI-64-fresh
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala1
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala3
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala7
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala27
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java1
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java4
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JMethod.java1
-rw-r--r--src/library/scala/annotation/synchronized.scala15
9 files changed, 55 insertions, 5 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 7ed3e977db..e87f7d65b0 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -734,6 +734,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val ScalaStrictFPAttr = getRequiredClass("scala.annotation.strictfp")
lazy val SerializableAttr = getRequiredClass("scala.annotation.serializable") // @serializable is deprecated
lazy val SwitchClass = getRequiredClass("scala.annotation.switch")
+ lazy val SynchronizedAttr = getRequiredClass("scala.annotation.synchronized")
lazy val TailrecClass = getRequiredClass("scala.annotation.tailrec")
lazy val VarargsClass = getRequiredClass("scala.annotation.varargs")
lazy val uncheckedStableClass = getRequiredClass("scala.annotation.unchecked.uncheckedStable")
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index ce85d65050..e997405c77 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -557,6 +557,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
def isStrictFP = hasAnnotation(ScalaStrictFPAttr) || (enclClass hasAnnotation ScalaStrictFPAttr)
+ def isSynchronized = hasAnnotation(SynchronizedAttr)
def isSerializable = (
info.baseClasses.exists(p => p == SerializableClass || p == JavaSerializableClass)
|| hasAnnotation(SerializableAttr) // last part can be removed, @serializable annotation is deprecated
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index a838c7d54d..50e84a81a8 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -857,6 +857,9 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
if (method.native)
flags |= ACC_NATIVE
+ if (m.symbol.isSynchronized)
+ flags |= ACC_SYNCHRONIZED
+
jmethod = jclass.addNewMethod(flags,
javaName(m.symbol),
resTpe,
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index d017cf94b3..09be682123 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -706,8 +706,8 @@ abstract class Inliners extends SubComponent {
if (settings.debug.value) icodes.checkValid(caller.m)
}
- def isStampedForInlining(stackLength: Int) =
- !sameSymbols && inc.m.hasCode && shouldInline && isSafeToInline(stackLength)
+ def isStampedForInlining(stack: TypeStack) =
+ !sameSymbols && inc.m.hasCode && shouldInline && isSafeToInline(stack) && !inc.m.symbol.isSynchronized
def logFailure(stackLength: Int) = log(
"""|inline failed for %s:
@@ -724,7 +724,8 @@ abstract class Inliners extends SubComponent {
def failureReason(stackLength: Int) =
if (!inc.m.hasCode) "bytecode was unavailable"
- else if (!isSafeToInline(stackLength)) "it is unsafe (target may reference private fields)"
+ else if (!isSafeToInline(stack)) "it is unsafe (target may reference private fields)"
+ else if (inc.m.symbol.isSynchronized) "method is synchronized"
else "of a bug (run with -Ylog:inline -Ydebug for more information)"
def canAccess(level: NonPublicRefs.Value) = level match {
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index 23697a4730..39ca60d870 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -173,6 +173,29 @@ abstract class TailCalls extends Transform {
trees map (t => transform(t, nctx))
}
+ /**
+ * Transforms methods with synchronized body into synchronized methods
+ */
+ private def transformSynchronizedMethods(tree: Tree): Tree = {
+ def isSelfSynchronized(body: Apply) = body.fun match {
+ case TypeApply(fun @ Select(This(_), _), List(TypeTree()))
+ if (fun.symbol == Object_synchronized &&
+ fun.qualifier.symbol == tree.symbol.enclClass &&
+ !tree.symbol.enclClass.isTrait) => true
+ case _ => false
+ }
+
+ tree match {
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs @ Apply(_, List(body)))
+ if (isSelfSynchronized(rhs)) =>
+ val res = treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, body)
+ res.symbol withAnnotation AnnotationInfo(SynchronizedAttr.tpe, Nil, Nil)
+ res
+ case _ =>
+ tree
+ }
+ }
+
override def transform(tree: Tree): Tree = {
/** A possibly polymorphic apply to be considered for tail call transformation.
*/
@@ -222,8 +245,8 @@ abstract class TailCalls extends Transform {
else rewriteTailCall(receiver)
}
- tree match {
- case dd @ DefDef(_, _, _, vparamss0, _, rhs0) =>
+ transformSynchronizedMethods(tree) match {
+ case dd @ DefDef(mods, name, tparams, vparams, tpt, rhs) =>
val newCtx = new Context(dd)
debuglog("Considering " + dd.name + " for tailcalls")
val newRHS = transform(rhs0, newCtx)
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java b/src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java
index 0a48fc1628..d254acbdc1 100644
--- a/src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java
+++ b/src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java
@@ -19,6 +19,7 @@ public interface JAccessFlags {
public static int ACC_STATIC = 0x0008;
public static int ACC_FINAL = 0x0010;
public static int ACC_SUPER = 0x0020;
+ public static int ACC_SYNCHRONIZED = 0x0020;
public static int ACC_VOLATILE = 0x0040;
public static int ACC_TRANSIENT = 0x0080;
public static int ACC_NATIVE = 0x0100;
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java b/src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java
index 3d2bf87264..beb76893f6 100644
--- a/src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java
+++ b/src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java
@@ -121,6 +121,10 @@ abstract public class JFieldOrMethod extends JMember {
return (accessFlags & JAccessFlags.ACC_VARARGS) != 0;
}
+ public boolean isSynchronized() {
+ return (accessFlags & JAccessFlags.ACC_SYNCHRONIZED) != 0;
+ }
+
public void writeTo(DataOutputStream stream) throws IOException {
if (! frozen) {
try {
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java b/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java
index ad35c76da3..9b9da3c0aa 100644
--- a/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java
+++ b/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java
@@ -194,6 +194,7 @@ public class JMethod extends JFieldOrMethod {
else if (isNative()) buf.append("native ");
if (isAbstract()) buf.append("abstract ");
else if (isFinal()) buf.append("final ");
+ if (isSynchronized()) buf.append("synchronized ");
return buf.toString();
}
}
diff --git a/src/library/scala/annotation/synchronized.scala b/src/library/scala/annotation/synchronized.scala
new file mode 100644
index 0000000000..9470c7173c
--- /dev/null
+++ b/src/library/scala/annotation/synchronized.scala
@@ -0,0 +1,15 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.annotation
+
+/**
+ * If this annotation is present on a method, the synchronized flag will be emitted.
+ * FIXME This should be internal to the compiler
+ */
+private[scala] class synchronized extends StaticAnnotation