summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-11-09 10:35:54 +0000
committerMartin Odersky <odersky@gmail.com>2009-11-09 10:35:54 +0000
commit47ff60552398b09a8b757345cd56f12091d97b92 (patch)
tree535e5c9d5f2fdd4594c87b0dc63aceedc260dc00
parent6c6d9a042399ad3eb4847f65764e086431318350 (diff)
downloadscala-47ff60552398b09a8b757345cd56f12091d97b92.tar.gz
scala-47ff60552398b09a8b757345cd56f12091d97b92.tar.bz2
scala-47ff60552398b09a8b757345cd56f12091d97b92.zip
fast path equals and hash methods.
-rw-r--r--src/library/scala/Predef.scala5
-rw-r--r--src/library/scala/runtime/BoxesRunTime.java56
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala7
3 files changed, 51 insertions, 17 deletions
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index cab32b0595..c3f6ad9eff 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -91,6 +91,11 @@ object Predef extends LowPriorityImplicits {
def currentThread = java.lang.Thread.currentThread()
+ // hashcode and equality -------------------------------------------------
+
+ @inline def hash(x: Any): Int =
+ if (x.isInstanceOf[Number]) (x.asInstanceOf[Number]).intValue else x.hashCode
+
// errors and asserts -------------------------------------------------
def error(message: String): Nothing = throw new RuntimeException(message)
diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java
index 3e75cb213e..b5df9d8ce8 100644
--- a/src/library/scala/runtime/BoxesRunTime.java
+++ b/src/library/scala/runtime/BoxesRunTime.java
@@ -139,6 +139,45 @@ public class BoxesRunTime
/* COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON */
+ // That's the method we should use from now on.
+ public static boolean equals(Object x, Object y) {
+ if (x instanceof Number) {
+ Number xn = (Number)x;
+ if (y instanceof Number) {
+ Number yn = (Number)y;
+ if ((xn instanceof Double) || (yn instanceof Double))
+ return xn.doubleValue() == yn.doubleValue();
+ if ((xn instanceof Float) || (yn instanceof Float))
+ return xn.floatValue() == yn.floatValue();
+ if ((xn instanceof Long) || (yn instanceof Long))
+ return xn.longValue() == yn.longValue();
+ return xn.intValue() == yn.intValue();
+ }
+ if (y instanceof Character)
+ return equalsNumChar(xn, (Character)y);
+ } else if (x instanceof Character) {
+ Character xc = (Character)x;
+ if (y instanceof Character)
+ return (xc.charValue() == ((Character)y).charValue());
+ if (y instanceof Number)
+ return equalsNumChar((Number)y, xc);
+ } else if (x == null) {
+ return y == null;
+ }
+ return x.equals(y);
+ }
+
+ private static boolean equalsNumChar(Number x, Character y) {
+ char ch = y.charValue();
+ if (x instanceof Double)
+ return x.doubleValue() == ch;
+ if (x instanceof Float)
+ return x.floatValue() == ch;
+ if (x instanceof Long)
+ return x.longValue() == ch;
+ return x.intValue() == ch;
+ }
+
private static boolean equalsBonusLogicFromScala27(Object a, Object b) {
if (a instanceof Number || a instanceof Character || b instanceof Number || b instanceof Character) {
int acode = typeCode(a);
@@ -188,23 +227,6 @@ public class BoxesRunTime
}
}
- /** The current equals method. **/
- public static boolean equals(Object a, Object b) {
- if (a == null || b == null)
- return a == b;
-
- verifyEqEq(a, b,
- (Equality.dieOnBoxedCompare || Equality.dieOnBoxedCompareIfValuesAreEqual),
- (Equality.warnOnBoxedCompareIfValuesAreEqual || Equality.dieOnBoxedCompareIfValuesAreEqual)
- );
-
- if (a.equals(b))
- return true;
-
- if (Equality.use28Semantics) return false;
- else return equalsBonusLogicFromScala27(a, b);
- }
-
/* OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS */
/** arg1 + arg2 */
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index 4541c0147c..a93ff61a41 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -120,6 +120,13 @@ object ScalaRunTime {
code
}
+ /** Fast path equality method for inlining; used when -optimise is set.
+ */
+ @inline def inlinedEquals(x: Object, y: Object): Boolean =
+ if (x eq null) y eq null
+ else if (x.isInstanceOf[Number] || x.isInstanceOf[Character]) BoxesRunTime.equals(x, y)
+ else x.equals(y)
+
def _equals(x: Product, y: Any): Boolean = y match {
case y1: Product if x.productArity == y1.productArity =>
val arity = x.productArity