diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2014-05-07 17:48:59 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2014-05-07 17:58:48 +0200 |
commit | 840234017bc6b8a3610c208883fd6ad5a563fcd3 (patch) | |
tree | f7bb232b89ace706530b9fe5e934e6d35d1258f4 /src | |
parent | 251616a107f4255203e318c9f6342f774d25e66d (diff) | |
download | scala-840234017bc6b8a3610c208883fd6ad5a563fcd3.tar.gz scala-840234017bc6b8a3610c208883fd6ad5a563fcd3.tar.bz2 scala-840234017bc6b8a3610c208883fd6ad5a563fcd3.zip |
SI-7852 for GenBCode
Avoid null checks for "someLiteral".== and SomeModule.==. This has
been implemented in GenICode in #2954.
Introduces a trait to share code between GenICode and GenBCode. This
is just a start, more such refactorings will come quite certainly.
Diffstat (limited to 'src')
4 files changed, 34 insertions, 23 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 1cea4bedda..e1183d8403 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -13,13 +13,12 @@ import scala.collection.{ mutable, immutable } import scala.collection.mutable.{ ListBuffer, Buffer } import scala.tools.nsc.symtab._ import scala.annotation.switch -import PartialFunction._ /** * @author Iulian Dragos * @version 1.0 */ -abstract class GenICode extends SubComponent { +abstract class GenICode extends SubComponent with jvm.BCodeICodeCommon { import global._ import icodes._ import icodes.opcodes._ @@ -1326,15 +1325,6 @@ abstract class GenICode extends SubComponent { List(tree) } - /** Some useful equality helpers. - */ - def isNull(t: Tree) = cond(t) { case Literal(Constant(null)) => true } - def isLiteral(t: Tree) = cond(t) { case Literal(_) => true } - def isNonNullExpr(t: Tree) = isLiteral(t) || ((t.symbol ne null) && t.symbol.isModule) - - /* If l or r is constant null, returns the other ; otherwise null */ - def ifOneIsNull(l: Tree, r: Tree) = if (isNull(l)) r else if (isNull(r)) l else null - /** * Find the label denoted by `lsym` and enter it in context `ctx`. * diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index 53142fbd87..9e27373a07 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -1020,17 +1020,6 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { tree :: Nil } - /* Some useful equality helpers. */ - def isNull(t: Tree) = { - t match { - case Literal(Constant(null)) => true - case _ => false - } - } - - /* If l or r is constant null, returns the other ; otherwise null */ - def ifOneIsNull(l: Tree, r: Tree) = if (isNull(l)) r else if (isNull(r)) l else null - /* Emit code to compare the two top-most stack values using the 'op' operator. */ private def genCJUMP(success: asm.Label, failure: asm.Label, op: TestOp, tk: BType) { if (tk.isIntSizedType) { // BOOL, BYTE, CHAR, SHORT, or INT @@ -1200,6 +1189,12 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { // expr == null -> expr eq null genLoad(l, ObjectReference) genCZJUMP(success, failure, icodes.EQ, ObjectReference) + } else if (isNonNullExpr(l)) { + // SI-7852 Avoid null check if L is statically non-null. + genLoad(l, ObjectReference) + genLoad(r, ObjectReference) + genCallMethod(Object_equals, icodes.opcodes.Dynamic) + genCZJUMP(success, failure, icodes.NE, BOOL) } else { // l == r -> if (l eq null) r eq null else l.equals(r) val eqEqTempLocal = locals.makeLocal(AnyRefReference, nme.EQEQ_LOCAL_VAR.toString) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeGlue.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeGlue.scala index cc3265c5f9..ef116324bf 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeGlue.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeGlue.scala @@ -18,7 +18,7 @@ import scala.collection.{ immutable, mutable } * @version 1.0 * */ -abstract class BCodeGlue extends SubComponent { +abstract class BCodeGlue extends SubComponent with BCodeICodeCommon { import global._ diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeICodeCommon.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeICodeCommon.scala new file mode 100644 index 0000000000..071e0cf74c --- /dev/null +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeICodeCommon.scala @@ -0,0 +1,26 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2014 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.tools.nsc.backend.jvm + +import scala.tools.nsc.Global +import PartialFunction._ + +/** + * This trait contains code shared between GenBCode and GenICode that depends on types defined in + * the compiler cake (Global). + */ +trait BCodeICodeCommon { + val global: Global + import global._ + + /** Some useful equality helpers. */ + def isNull(t: Tree) = cond(t) { case Literal(Constant(null)) => true } + def isLiteral(t: Tree) = cond(t) { case Literal(_) => true } + def isNonNullExpr(t: Tree) = isLiteral(t) || ((t.symbol ne null) && t.symbol.isModule) + + /** If l or r is constant null, returns the other ; otherwise null */ + def ifOneIsNull(l: Tree, r: Tree) = if (isNull(l)) r else if (isNull(r)) l else null +} |