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 | |
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]])
-rw-r--r-- | sources/scala/runtime/types/ScalaClassType.java | 5 | ||||
-rw-r--r-- | sources/scala/runtime/types/Statistics.java | 8 | ||||
-rw-r--r-- | sources/scalac/symtab/Definitions.java | 8 | ||||
-rw-r--r-- | sources/scalac/transformer/TypesAsValuesPhase.java | 45 | ||||
-rw-r--r-- | sources/scalac/util/Names.java | 1 |
5 files changed, 64 insertions, 3 deletions
diff --git a/sources/scala/runtime/types/ScalaClassType.java b/sources/scala/runtime/types/ScalaClassType.java index b999f1bcfb..51f002e211 100644 --- a/sources/scala/runtime/types/ScalaClassType.java +++ b/sources/scala/runtime/types/ScalaClassType.java @@ -57,6 +57,11 @@ public class ScalaClassType extends ClassType { || ((ScalaObject)o).getType().weakIsSubScalaClassType(this)); } + public boolean weakIsInstance(Object o) { + assert Statistics.incWeakInstanceOf(); + return ((ScalaObject)o).getType().weakIsSubScalaClassType(this); + } + protected boolean isSubClassType(ClassType that) { return (this == that) || (super.isSubClassType(that) diff --git a/sources/scala/runtime/types/Statistics.java b/sources/scala/runtime/types/Statistics.java index 67091cb6e8..437c1bcb80 100644 --- a/sources/scala/runtime/types/Statistics.java +++ b/sources/scala/runtime/types/Statistics.java @@ -32,6 +32,7 @@ public class Statistics { private static long uniqueInstantiationsCount = 0; private static long instanceOfCount = 0; + private static long weakInstanceOfCount = 0; private static long typeCastCount = 0; private static long ancestorSearchIterations = 0; @@ -69,6 +70,11 @@ public class Statistics { return true; } + public static synchronized boolean incWeakInstanceOf() { + ++weakInstanceOfCount; + return true; + } + public static synchronized boolean decInstanceOf() { --instanceOfCount; return true; @@ -112,6 +118,8 @@ public class Statistics { + uniqueInstantiationsCount + ")"); stream.println("(instance-of . " + instanceOfCount + ")"); + stream.println("(weak-instance-of . " + + weakInstanceOfCount + ")"); stream.println("(type-cast . " + typeCastCount + ")"); if (ancestorSearches > 0) { diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index 6dda72353e..8f306ab4ac 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -679,6 +679,14 @@ public class Definitions { return TYPECONSTRUCTOR_FUNCTIONOUTER; } + private Symbol SCALACLASSTYPE_WEAKISINSTANCE; + public Symbol SCALACLASSTYPE_WEAKISINSTANCE() { + if (SCALACLASSTYPE_WEAKISINSTANCE == null) + SCALACLASSTYPE_WEAKISINSTANCE = + loadTerm(SCALACLASSTYPE_CLASS, Names.weakIsInstance); + return SCALACLASSTYPE_WEAKISINSTANCE; + } + private Symbol SCALACLASSTYPE_SETPARENTS; public Symbol SCALACLASSTYPE_SETPARENTS() { if (SCALACLASSTYPE_SETPARENTS == null) 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. */ diff --git a/sources/scalac/util/Names.java b/sources/scalac/util/Names.java index 18013be172..0fda2848fe 100644 --- a/sources/scalac/util/Names.java +++ b/sources/scalac/util/Names.java @@ -222,6 +222,7 @@ public class Names { public static final Name update = Name.fromString("update"); public static final Name view = Name.fromString("view"); public static final Name wait = Name.fromString("wait"); + public static final Name weakIsInstance = Name.fromString("weakIsInstance"); public static final Name xml = Name.fromString("xml"); |