diff options
author | schinz <schinz@epfl.ch> | 2005-03-28 07:41:32 +0000 |
---|---|---|
committer | schinz <schinz@epfl.ch> | 2005-03-28 07:41:32 +0000 |
commit | 2e064cb5740198a9a8f6fbcabc590b9874800032 (patch) | |
tree | b3b38961021aada997efef07a52af00e21bd66df /sources/scalac/transformer | |
parent | 9602bf11e93ac5a449f0ab492f3c74f2fa45fa56 (diff) | |
download | scala-2e064cb5740198a9a8f6fbcabc590b9874800032.tar.gz scala-2e064cb5740198a9a8f6fbcabc590b9874800032.tar.bz2 scala-2e064cb5740198a9a8f6fbcabc590b9874800032.zip |
- added weakIsInstance method in ScalaClassType...
- added weakIsInstance method in ScalaClassType, which make it possible
to slightly optimise instance tests when the type is that of a known
class (e.g. x.isInstanceOf[C[T]])
Diffstat (limited to 'sources/scalac/transformer')
-rw-r--r-- | sources/scalac/transformer/TypesAsValuesPhase.java | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/sources/scalac/transformer/TypesAsValuesPhase.java b/sources/scalac/transformer/TypesAsValuesPhase.java index b5dc28a0c0..e3ec60af48 100644 --- a/sources/scalac/transformer/TypesAsValuesPhase.java +++ b/sources/scalac/transformer/TypesAsValuesPhase.java @@ -329,7 +329,7 @@ public class TypesAsValuesPhase extends Phase { transformer.apply(unit); } - private class TV_Transformer extends GenTransformer { + private class TV_Transformer extends TV_MiniTransformer { private Symbol currentOwner; public TV_Transformer(Global global) { @@ -736,8 +736,29 @@ public class TypesAsValuesPhase extends Phase { */ private Tree genInstanceTest(int pos, Tree expr, Type tp) { Tree tpVal = typeAsValue(pos, tp, currentOwner, EENV); - Tree fun = gen.Select(pos, tpVal, defs.TYPE_ISINSTANCE()); - return gen.mkApply_V(pos, fun, new Tree[] { expr }); + + if (isKnowClassType(tp) && isLocalIdent(expr)) { + Symbol sym = expr.symbol(); + Tree cheapTest = + gen.mkIsInstanceOf(pos, gen.mkLocalRef(pos, sym), tp, true); + Symbol weakIsInst = defs.SCALACLASSTYPE_WEAKISINSTANCE(); + Tree scalaTpVal = gen.mkAsInstanceOf(pos, + tpVal, + defs.SCALACLASSTYPE_TYPE(), + true); + Tree expensiveTest = + gen.mkApply_V(pos, + gen.Select(pos, scalaTpVal, weakIsInst), + new Tree[] { expr }); + return gen.mkApply_V(pos, + gen.Select(pos, + cheapTest, + defs.BOOLEAN_AND()), + new Tree[] { expensiveTest }); + } else { + Tree fun = gen.Select(pos, tpVal, defs.TYPE_ISINSTANCE()); + return gen.mkApply_V(pos, fun, new Tree[] { expr }); + } } /** @@ -783,6 +804,24 @@ public class TypesAsValuesPhase extends Phase { return false; } + private boolean isKnowClassType(Type tp) { + switch (tp) { + case TypeRef(_, Symbol sym, _): + return (sym != defs.ARRAY_CLASS) && !sym.isParameter(); + default: + return false; + } + } + + private boolean isLocalIdent(Tree tree) { + switch (tree) { + case Ident(_): + return tree.symbol().isLocal(); + default: + return false; + } + } + /** * Transform a type into a tree representing it. */ |