summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-01-27 01:27:01 +0000
committerPaul Phillips <paulp@improving.org>2011-01-27 01:27:01 +0000
commitfcdc2267fe55074829c3a1c43c0bbdb403af64c0 (patch)
treee5091f32538e2440204b5788038b7c12b7da3413
parent4a194bf5384a217697e7106ab5aca42946bb74cd (diff)
downloadscala-fcdc2267fe55074829c3a1c43c0bbdb403af64c0.tar.gz
scala-fcdc2267fe55074829c3a1c43c0bbdb403af64c0.tar.bz2
scala-fcdc2267fe55074829c3a1c43c0bbdb403af64c0.zip
A few minor hashcode tidbits I had stored away ...
A few minor hashcode tidbits I had stored away from previous hashcoding, and some fixups in treedsl. No review.
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala24
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala29
2 files changed, 30 insertions, 23 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
index 3ef1fd4dfb..404c9156fe 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
@@ -281,14 +281,22 @@ trait TreeDSL {
if (args.isEmpty) New(TypeTree(sym.tpe))
else New(TypeTree(sym.tpe), List(args.toList))
- def VAR(name: Name, tp: Type): ValTreeStart = VAR(name) withType tp
- def VAR(name: Name): ValTreeStart = new ValTreeStart(name) withFlags Flags.MUTABLE
- def VAL(name: Name, tp: Type): ValTreeStart = VAL(name) withType tp
- def VAL(name: Name): ValTreeStart = new ValTreeStart(name)
- def VAL(sym: Symbol): ValSymStart = new ValSymStart(sym)
-
- def DEF(name: Name): DefTreeStart = new DefTreeStart(name)
- def DEF(sym: Symbol): DefSymStart = new DefSymStart(sym)
+ def DEF(name: Name, tp: Type): DefTreeStart = DEF(name) withType tp
+ def DEF(name: Name): DefTreeStart = new DefTreeStart(name)
+ def DEF(sym: Symbol): DefSymStart = new DefSymStart(sym)
+
+ def VAL(name: Name, tp: Type): ValTreeStart = VAL(name) withType tp
+ def VAL(name: Name): ValTreeStart = new ValTreeStart(name)
+ def VAL(sym: Symbol): ValSymStart = new ValSymStart(sym)
+
+ def VAR(name: Name, tp: Type): ValTreeStart = VAL(name, tp) withFlags Flags.MUTABLE
+ def VAR(name: Name): ValTreeStart = VAL(name) withFlags Flags.MUTABLE
+ def VAR(sym: Symbol): ValSymStart = VAL(sym) withFlags Flags.MUTABLE
+
+ def LAZYVAL(name: Name, tp: Type): ValTreeStart = VAL(name, tp) withFlags Flags.LAZY
+ def LAZYVAL(name: Name): ValTreeStart = VAL(name) withFlags Flags.LAZY
+ def LAZYVAL(sym: Symbol): ValSymStart = VAL(sym) withFlags Flags.LAZY
+
def AND(guards: Tree*) =
if (guards.isEmpty) EmptyTree
else guards reduceLeft gen.mkAnd
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index 7a7afbcd88..548875bb6c 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -6,8 +6,6 @@
** |/ **
\* */
-
-
package scala.runtime
import scala.reflect.ClassManifest
@@ -17,9 +15,12 @@ import scala.collection.immutable.{ NumericRange, List, Stream, Nil, :: }
import scala.collection.generic.{ Sorted }
import scala.xml.{ Node, MetaData }
import scala.util.control.ControlThrowable
+import java.lang.Double.doubleToLongBits
import java.lang.reflect.{ Modifier, Method => JMethod }
-/* The object <code>ScalaRunTime</code> provides ...
+/** The object ScalaRunTime provides support methods required by
+ * the scala runtime. All these methods should be considered
+ * outside the API and subject to change or removal without notice.
*/
object ScalaRunTime {
def isArray(x: AnyRef): Boolean = isArray(x, 1)
@@ -212,29 +213,27 @@ object ScalaRunTime {
if (iv == fv) return iv
val lv = fv.toLong
- if (lv == fv) return lv.hashCode
+ if (lv == fv) return hash(lv)
else fv.hashCode
}
@inline def hash(lv: Long): Int = {
- val iv = lv.toInt
- if (iv == lv) iv else lv.hashCode
+ val low = lv.toInt
+ val lowSign = low >>> 31
+ val high = (lv >>> 32).toInt
+ low ^ (high + lowSign)
}
@inline def hash(x: Int): Int = x
@inline def hash(x: Short): Int = x.toInt
@inline def hash(x: Byte): Int = x.toInt
@inline def hash(x: Char): Int = x.toInt
- @inline def hash(x: Boolean): Int = x.hashCode
+ @inline def hash(x: Boolean): Int = if (x) trueHashcode else falseHashcode
@inline def hash(x: Unit): Int = 0
-
@inline def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x)
- /** XXX Why is there one boxed implementation in here? It would seem
- * we should have all the numbers or none of them.
- */
- @inline def hash(x: java.lang.Long): Int = {
- val iv = x.intValue
- if (iv == x.longValue) iv else x.hashCode
- }
+ // These are so these values are constant folded into def hash(Boolean)
+ // rather than being recalculated all the time.
+ private final val trueHashcode = true.hashCode
+ private final val falseHashcode = false.hashCode
/** A helper method for constructing case class equality methods,
* because existential types get in the way of a clean outcome and