summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschinz <schinz@epfl.ch>2005-03-28 07:41:32 +0000
committerschinz <schinz@epfl.ch>2005-03-28 07:41:32 +0000
commit2e064cb5740198a9a8f6fbcabc590b9874800032 (patch)
treeb3b38961021aada997efef07a52af00e21bd66df
parent9602bf11e93ac5a449f0ab492f3c74f2fa45fa56 (diff)
downloadscala-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.java5
-rw-r--r--sources/scala/runtime/types/Statistics.java8
-rw-r--r--sources/scalac/symtab/Definitions.java8
-rw-r--r--sources/scalac/transformer/TypesAsValuesPhase.java45
-rw-r--r--sources/scalac/util/Names.java1
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");