summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-07-11 19:03:35 +0200
committerMartin Odersky <odersky@gmail.com>2012-07-11 19:35:55 +0200
commita9b85dbaad568b5c709a5eb6ab23907cdf4ee29e (patch)
tree56180948d8986aafa37e93e837db70c9106c2f6b
parent026a70d55591c3b5ee157e22998b62168afee686 (diff)
downloadscala-a9b85dbaad568b5c709a5eb6ab23907cdf4ee29e.tar.gz
scala-a9b85dbaad568b5c709a5eb6ab23907cdf4ee29e.tar.bz2
scala-a9b85dbaad568b5c709a5eb6ab23907cdf4ee29e.zip
Pickled flag reorg
Cleaned up and optimized code that maps between raw and pickled flags. Avoids mystery constants. Makes a whole bunch of new flags be pickled which were not pickled before (more precisely: Everything in InitialFlags with value greater than 1 << 31 which is not in FlagsNotPickled now gets pickled whereas before it wasn't. Among these: VARARGS, IMPLCLASS, SPECIALZED, DEFAULTINIT, SYNCHRONIZED. I am curious how many tickets will get fixed by this change. The first one I noted is t5504, which previously enforced the buggy behavior through a neg check! There are also some build manager check file changes that have to do with the fact that flags now print in a different order for performance reasons.
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Flags.scala81
-rw-r--r--test/files/buildmanager/t2651_3/t2651_3.check2
-rw-r--r--test/files/buildmanager/t2651_4/t2651_4.check4
-rw-r--r--test/files/buildmanager/t2657/t2657.check4
-rw-r--r--test/files/buildmanager/t2789/t2789.check4
-rw-r--r--test/files/neg/t5504.check4
-rw-r--r--test/files/pos/t5504/s_1.scala (renamed from test/files/neg/t5504/s_1.scala)0
-rw-r--r--test/files/pos/t5504/s_2.scala (renamed from test/files/neg/t5504/s_2.scala)0
9 files changed, 49 insertions, 54 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 192cc94b90..cc5ed0f129 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -503,7 +503,7 @@ abstract class Pickler extends SubComponent {
private def writeSymInfo(sym: Symbol) {
writeRef(sym.name)
writeRef(localizedOwner(sym))
- writeLongNat((rawFlagsToPickled(sym.flags & PickledFlags)))
+ writeLongNat((rawToPickledFlags(sym.flags & PickledFlags)))
if (sym.hasAccessBoundary) writeRef(sym.privateWithin)
writeRef(sym.info)
}
@@ -966,7 +966,7 @@ abstract class Pickler extends SubComponent {
TREE
case Modifiers(flags, privateWithin, _) =>
- val pflags = rawFlagsToPickled(flags)
+ val pflags = rawToPickledFlags(flags)
writeNat((pflags >> 32).toInt)
writeNat((pflags & 0xFFFFFFFF).toInt)
writeRef(privateWithin)
diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala
index 37e5a23819..c17600ec41 100644
--- a/src/reflect/scala/reflect/internal/Flags.scala
+++ b/src/reflect/scala/reflect/internal/Flags.scala
@@ -165,6 +165,7 @@ class Flags extends ModifierFlags {
// A Java method's type is ``cooked'' by transforming raw types to existentials
final val SYNCHRONIZED = 1L << 45 // symbol is a method which should be marked ACC_SYNCHRONIZED
+
// ------- shift definitions -------------------------------------------------------
final val InitialFlags = 0x0001FFFFFFFFFFFFL // flags that are enabled from phase 1.
@@ -211,7 +212,7 @@ class Flags extends ModifierFlags {
/** To be a little clearer to people who aren't habitual bit twiddlers.
*/
final val AllFlags = -1L
-
+
/** These flags can be set when class or module symbol is first created.
* They are the only flags to survive a call to resetFlags().
*/
@@ -279,6 +280,12 @@ class Flags extends ModifierFlags {
/** Module flags inherited by their module-class */
final val ModuleToClassFlags = AccessFlags | TopLevelCreationFlags | CASE | SYNTHETIC
+ /** These flags are not pickled */
+ final val FlagsNotPickled = IS_ERROR | OVERLOADED | LIFTED | TRANS_FLAG | LOCKED | TRIEDCOOKING
+
+ /** These flags are pickled */
+ final val PickledFlags = InitialFlags & ~FlagsNotPickled
+
def getterFlags(fieldFlags: Long): Long = ACCESSOR + (
if ((fieldFlags & MUTABLE) != 0) fieldFlags & ~MUTABLE & ~PRESUPER
else fieldFlags & ~PRESUPER | STABLE
@@ -307,47 +314,45 @@ class Flags extends ModifierFlags {
private final val PKL_MASK = 0x00000FFF
- final val PickledFlags = 0xFFFFFFFFL
-
- private def rawPickledCorrespondence = Array(
- (IMPLICIT, IMPLICIT_PKL),
- (FINAL, FINAL_PKL),
+ /** Pickler correspondence, ordered roughly by frequency of occurrence */
+ private def rawPickledCorrespondence = Array[(Long, Long)](
+ (METHOD, METHOD_PKL),
(PRIVATE, PRIVATE_PKL),
+ (FINAL, FINAL_PKL),
(PROTECTED, PROTECTED_PKL),
- (SEALED, SEALED_PKL),
- (OVERRIDE, OVERRIDE_PKL),
(CASE, CASE_PKL),
- (ABSTRACT, ABSTRACT_PKL),
(DEFERRED, DEFERRED_PKL),
- (METHOD, METHOD_PKL),
(MODULE, MODULE_PKL),
- (INTERFACE, INTERFACE_PKL)
+ (OVERRIDE, OVERRIDE_PKL),
+ (INTERFACE, INTERFACE_PKL),
+ (IMPLICIT, IMPLICIT_PKL),
+ (SEALED, SEALED_PKL),
+ (ABSTRACT, ABSTRACT_PKL)
)
- private val rawFlags: Array[Int] = rawPickledCorrespondence map (_._1)
- private val pickledFlags: Array[Int] = rawPickledCorrespondence map (_._2)
-
- private def r2p(flags: Int): Int = {
- var result = 0
- var i = 0
- while (i < rawFlags.length) {
- if ((flags & rawFlags(i)) != 0)
- result |= pickledFlags(i)
-
- i += 1
- }
- result
- }
- private def p2r(flags: Int): Int = {
- var result = 0
- var i = 0
- while (i < rawFlags.length) {
- if ((flags & pickledFlags(i)) != 0)
- result |= rawFlags(i)
-
- i += 1
+
+ private val mappedRawFlags = rawPickledCorrespondence map (_._1)
+ private val mappedPickledFlags = rawPickledCorrespondence map (_._2)
+
+ private class MapFlags(from: Array[Long], to: Array[Long]) extends (Long => Long) {
+ val fromSet = (0L /: from) (_ | _)
+
+ def apply(flags: Long): Long = {
+ var result = flags & ~fromSet
+ var tobeMapped = flags & fromSet
+ var i = 0
+ while (tobeMapped != 0) {
+ if ((tobeMapped & from(i)) != 0) {
+ result |= to(i)
+ tobeMapped &= ~from(i)
+ }
+ i += 1
+ }
+ result
}
- result
}
+
+ val rawToPickledFlags: Long => Long = new MapFlags(mappedRawFlags, mappedPickledFlags)
+ val pickledToRawFlags: Long => Long = new MapFlags(mappedPickledFlags, mappedRawFlags)
// ------ displaying flags --------------------------------------------------------
@@ -462,18 +467,12 @@ class Flags extends ModifierFlags {
}
}
- def rawFlagsToPickled(flags: Long): Long =
- (flags & ~PKL_MASK) | r2p(flags.toInt & PKL_MASK)
-
- def pickledToRawFlags(pflags: Long): Long =
- (pflags & ~PKL_MASK) | p2r(pflags.toInt & PKL_MASK)
-
// List of the raw flags, in pickled order
final val MaxBitPosition = 62
final val pickledListOrder: List[Long] = {
val all = 0 to MaxBitPosition map (1L << _)
- val front = rawFlags map (_.toLong)
+ val front = mappedRawFlags map (_.toLong)
front.toList ++ (all filterNot (front contains _))
}
diff --git a/test/files/buildmanager/t2651_3/t2651_3.check b/test/files/buildmanager/t2651_3/t2651_3.check
index d4bac196e9..2a60e3d806 100644
--- a/test/files/buildmanager/t2651_3/t2651_3.check
+++ b/test/files/buildmanager/t2651_3/t2651_3.check
@@ -3,4 +3,4 @@ compiling Set(A.scala)
Changes: Map()
builder > A.scala
compiling Set(A.scala)
-Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()S flags: <deferred> <method>]))
+Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()S flags: <method> <deferred>]))
diff --git a/test/files/buildmanager/t2651_4/t2651_4.check b/test/files/buildmanager/t2651_4/t2651_4.check
index b182f31c09..74e5d8f99b 100644
--- a/test/files/buildmanager/t2651_4/t2651_4.check
+++ b/test/files/buildmanager/t2651_4/t2651_4.check
@@ -3,8 +3,8 @@ compiling Set(A.scala, B.scala)
Changes: Map()
builder > A.scala
compiling Set(A.scala)
-Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()T flags: <deferred> <method> <triedcooking>], Changed(Definition(A.y))[method y changed from (a: T)Unit to (a: T)Unit flags: <deferred> <method>], Changed(Definition(A.z))[method z changed from [B <: T]()Unit to [B <: T]()Unit flags: <deferred> <method>]))
-invalidate B.scala because inherited method changed [Changed(Definition(A.x))[method x changed from ()T to ()T flags: <deferred> <method> <triedcooking>]]
+Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()T flags: <method> <deferred> <triedcooking>], Changed(Definition(A.y))[method y changed from (a: T)Unit to (a: T)Unit flags: <method> <deferred>], Changed(Definition(A.z))[method z changed from [B <: T]()Unit to [B <: T]()Unit flags: <method> <deferred>]))
+invalidate B.scala because inherited method changed [Changed(Definition(A.x))[method x changed from ()T to ()T flags: <method> <deferred> <triedcooking>]]
compiling Set(B.scala)
B.scala:2: error: type mismatch;
found : Int(3)
diff --git a/test/files/buildmanager/t2657/t2657.check b/test/files/buildmanager/t2657/t2657.check
index cd0357599c..0d6709e58b 100644
--- a/test/files/buildmanager/t2657/t2657.check
+++ b/test/files/buildmanager/t2657/t2657.check
@@ -4,8 +4,8 @@ warning: there were 1 feature warnings; re-run with -feature for details
Changes: Map()
builder > A.scala
compiling Set(A.scala)
-Changes: Map(class A -> List(Changed(Definition(A.y))[method y changed from (i: Int)String to (i: Int)String flags: implicit <method> <triedcooking>]))
-invalidate B.scala because inherited method changed [Changed(Definition(A.y))[method y changed from (i: Int)String to (i: Int)String flags: implicit <method> <triedcooking>]]
+Changes: Map(class A -> List(Changed(Definition(A.y))[method y changed from (i: Int)String to (i: Int)String flags: <method> implicit <triedcooking>]))
+invalidate B.scala because inherited method changed [Changed(Definition(A.y))[method y changed from (i: Int)String to (i: Int)String flags: <method> implicit <triedcooking>]]
compiling Set(B.scala)
B.scala:2: error: type mismatch;
found : Int(3)
diff --git a/test/files/buildmanager/t2789/t2789.check b/test/files/buildmanager/t2789/t2789.check
index a7c767cc45..066561ac44 100644
--- a/test/files/buildmanager/t2789/t2789.check
+++ b/test/files/buildmanager/t2789/t2789.check
@@ -3,8 +3,8 @@ compiling Set(A.scala, B.scala)
Changes: Map()
builder > A.scala
compiling Set(A.scala)
-Changes: Map(class A -> List(Changed(Definition(A.e))[method e changed from ()E to ()E flags: implicit <method> <triedcooking>]), class E -> List())
-invalidate B.scala because inherited method changed [Changed(Definition(A.e))[method e changed from ()E to ()E flags: implicit <method> <triedcooking>]]
+Changes: Map(class A -> List(Changed(Definition(A.e))[method e changed from ()E to ()E flags: <method> implicit <triedcooking>]), class E -> List())
+invalidate B.scala because inherited method changed [Changed(Definition(A.e))[method e changed from ()E to ()E flags: <method> implicit <triedcooking>]]
compiling Set(B.scala)
B.scala:2: error: could not find implicit value for parameter y: E
val y = x(3)
diff --git a/test/files/neg/t5504.check b/test/files/neg/t5504.check
deleted file mode 100644
index 2827c02d10..0000000000
--- a/test/files/neg/t5504.check
+++ /dev/null
@@ -1,4 +0,0 @@
-error: type _$1 is defined twice
- conflicting symbols both originated in file 't5504/s_1.scala'
- Note: this may be due to a bug in the compiler involving wildcards in package objects
-one error found
diff --git a/test/files/neg/t5504/s_1.scala b/test/files/pos/t5504/s_1.scala
index 35cb2c8bae..35cb2c8bae 100644
--- a/test/files/neg/t5504/s_1.scala
+++ b/test/files/pos/t5504/s_1.scala
diff --git a/test/files/neg/t5504/s_2.scala b/test/files/pos/t5504/s_2.scala
index 03eecf6e19..03eecf6e19 100644
--- a/test/files/neg/t5504/s_2.scala
+++ b/test/files/pos/t5504/s_2.scala