From fcdc2267fe55074829c3a1c43c0bbdb403af64c0 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 27 Jan 2011 01:27:01 +0000 Subject: 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. --- src/compiler/scala/tools/nsc/ast/TreeDSL.scala | 24 ++++++++++++++------- src/library/scala/runtime/ScalaRunTime.scala | 29 +++++++++++++------------- 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 ScalaRunTime 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 -- cgit v1.2.3