summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-03-19 21:48:42 +0000
committerPaul Phillips <paulp@improving.org>2010-03-19 21:48:42 +0000
commit6613b1cdae66ae23edfd0e20eb5d4d066018681d (patch)
treec033a214a3d7e15ca01cdf778b88ac6e026c0fb7 /src/compiler
parentf2be3e6836014b3e4db9c7eca3bb4da8ab447f89 (diff)
downloadscala-6613b1cdae66ae23edfd0e20eb5d4d066018681d.tar.gz
scala-6613b1cdae66ae23edfd0e20eb5d4d066018681d.tar.bz2
scala-6613b1cdae66ae23edfd0e20eb5d4d066018681d.zip
Returning to the thrilling world of equality an...
Returning to the thrilling world of equality and hashCodes now that Any.## is a reality. Moved the hash functions from Predef to ScalaRunTime, and made what appears to be an optimization to equals by not losing the result of an instanceof test. Review by community.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/backend/JavaPlatform.scala3
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala30
2 files changed, 27 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
index 129a747e64..c4365a82ac 100644
--- a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
+++ b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
@@ -26,6 +26,9 @@ trait JavaPlatform extends Platform[AbstractFile] {
) ::: depAnalysisPhase
lazy val externalEquals = getMember(BoxesRunTimeClass, nme.equals_)
+ def externalEqualsNumNum = getMember(BoxesRunTimeClass, "equalsNumNum")
+ def externalEqualsNumChar = getMember(BoxesRunTimeClass, "equalsNumChar")
+ def externalEqualsNumObject = getMember(BoxesRunTimeClass, "equalsNumObject")
def isMaybeBoxed(sym: Symbol): Boolean = {
import definitions._
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 64e6759da2..77e14139ba 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -9,7 +9,8 @@ package scala.tools.nsc
package backend
package icode
-import scala.collection.mutable.{Map, HashMap, ListBuffer, Buffer, HashSet}
+import scala.collection.{ mutable, immutable }
+import scala.collection.mutable.{ HashMap, ListBuffer, Buffer, HashSet }
import scala.tools.nsc.symtab._
import scala.annotation.switch
import PartialFunction._
@@ -28,6 +29,7 @@ abstract class GenICode extends SubComponent {
import definitions.{
ArrayClass, ObjectClass, ThrowableClass, StringClass, NothingClass, NullClass,
Object_equals, Object_isInstanceOf, Object_asInstanceOf, ScalaRunTimeModule,
+ BoxedNumberClass, BoxedCharacterClass,
getMember
}
import scalaPrimitives.{
@@ -1362,13 +1364,29 @@ abstract class GenICode extends SubComponent {
* comparison might have a run-time type subtype of java.lang.Number or java.lang.Character.
* When it is statically known that both sides are equal and subtypes of Number of Character,
* not using the rich equality is possible (their own equals method will do ok.)*/
- def mustUseAnyComparator: Boolean =
- isMaybeBoxed(l.tpe.typeSymbol) && isMaybeBoxed(r.tpe.typeSymbol)
+ def mustUseAnyComparator: Boolean = {
+ def areSameFinals = l.tpe.isFinalType && r.tpe.isFinalType && (l.tpe =:= r.tpe)
+ !areSameFinals && isMaybeBoxed(l.tpe.typeSymbol) && isMaybeBoxed(r.tpe.typeSymbol)
+ }
if (mustUseAnyComparator) {
// when -optimise is on we call the @inline-version of equals, found in ScalaRunTime
val equalsMethod =
- if (!settings.XO.value) platform.externalEquals
+ if (!settings.XO.value) {
+ def default = platform.externalEquals
+ platform match {
+ case x: JavaPlatform =>
+ import x._
+ if (l.tpe <:< BoxedNumberClass.tpe) {
+ if (r.tpe <:< BoxedNumberClass.tpe) externalEqualsNumNum
+ else if (r.tpe <:< BoxedCharacterClass.tpe) externalEqualsNumChar
+ else externalEqualsNumObject
+ }
+ else default
+
+ case _ => default
+ }
+ }
else {
ctx.bb.emit(LOAD_MODULE(ScalaRunTimeModule))
getMember(ScalaRunTimeModule, nme.inlinedEquals)
@@ -1603,7 +1621,7 @@ abstract class GenICode extends SubComponent {
* to delay it any more: they will be used at some point.
*/
class DuplicateLabels(boundLabels: collection.Set[Symbol]) extends Transformer {
- val labels: Map[Symbol, Symbol] = new HashMap
+ val labels: mutable.Map[Symbol, Symbol] = new HashMap
var method: Symbol = _
var ctx: Context = _
@@ -2073,7 +2091,7 @@ abstract class GenICode extends SubComponent {
* jumps to the given basic block.
*/
def patch(code: Code) {
- def substMap: Map[Instruction, Instruction] = {
+ def substMap: mutable.Map[Instruction, Instruction] = {
val map = new HashMap[Instruction, Instruction]()
toPatch foreach (i => map += (i -> patch(i)))