summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-03-27 15:24:20 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-03-27 15:24:35 +0100
commitccf886c208a1ed5cc2ff8d8040cff2c76d6f6032 (patch)
tree96a3f69d1b90ed4e050a27547571e40348554ff1 /src/reflect
parent2efc6d56e6ee14dc7d86bc0667c921b082e8b9b4 (diff)
downloadscala-ccf886c208a1ed5cc2ff8d8040cff2c76d6f6032.tar.gz
scala-ccf886c208a1ed5cc2ff8d8040cff2c76d6f6032.tar.bz2
scala-ccf886c208a1ed5cc2ff8d8040cff2c76d6f6032.zip
SI-7186 Slim down some TypeRefs by 8 bytes.
By virtue of being defined in object TypeRef, they had two outer pointers. $outer scala.reflect.internal.Types$TypeRef$ $outer scala.tools.nsc.Global This commit moves them out of that object. They also now are no longer shrouded in anonymity, which is pleasant when debugging and profiling. The shallow size leaderboard now looks like: Class % Shallow % Objects Size ----------------------------------------- 1. :: 14% 25% 2. char[] 10% a 5% 3. ClassArgsTypeRef 6% 5% 4. Object[] 6% b 1% 5. TypeHistory 5% 6% 6. AbstractTypeSymbol 4% 2% 7. AbsractNoArgsTypeRef 3% 2% 8. j.l.Class 3% 2% 9. TermSymbol 2% 1% 10. HashEntry 1% c 1% a) 6% of the char[] by size is the name table. Retained source code seems to be sizable => should we discard after parsing? b) Types.uniques c) ZipArchive#DirEntry.entries Confirmation of the slimmer size can be seen in: https://github.com/retronym/scala/compare/ticket/7186 In that branch, I introduced infrastructure to query JVM object size in instrumented tests, and the diff shows: size class instance ======================================================================== - 64 bytes internal.Types$TypeRef$$anon$5 List[Int] - 64 bytes internal.Types$TypeRef$$anon$6 String + 56 bytes nternal.Types$ClassArgsTypeRef List[Int] + 56 bytes ernal.Types$ClassNoArgsTypeRef String I chose not to bring that test infrastructure across to master so as not to burden us with brittle tests built on esoteric facilities. This does not close the ticket which proposes a different space optimization which is also explored in that branch, but no a clear cut improvement.
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index d7ff4faa5d..d6eeb68452 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -2422,20 +2422,28 @@ trait Types
override def kind = "TypeRef"
}
+ // No longer defined as anonymous classes in `object TypeRef` to avoid an unnecessary outer pointer.
+ private final class AliasArgsTypeRef(pre: Type, sym: Symbol, args: List[Type]) extends ArgsTypeRef(pre, sym, args) with AliasTypeRef
+ private final class AbstractArgsTypeRef(pre: Type, sym: Symbol, args: List[Type]) extends ArgsTypeRef(pre, sym, args) with AbstractTypeRef
+ private final class ClassArgsTypeRef(pre: Type, sym: Symbol, args: List[Type]) extends ArgsTypeRef(pre, sym, args) with ClassTypeRef
+ private final class AliasNoArgsTypeRef(pre: Type, sym: Symbol) extends NoArgsTypeRef(pre, sym) with AliasTypeRef
+ private final class AbstractNoArgsTypeRef(pre: Type, sym: Symbol) extends NoArgsTypeRef(pre, sym) with AbstractTypeRef
+ private final class ClassNoArgsTypeRef(pre: Type, sym: Symbol) extends NoArgsTypeRef(pre, sym) with ClassTypeRef
+
object TypeRef extends TypeRefExtractor {
def apply(pre: Type, sym: Symbol, args: List[Type]): Type = unique({
if (args.nonEmpty) {
- if (sym.isAliasType) new ArgsTypeRef(pre, sym, args) with AliasTypeRef
- else if (sym.isAbstractType) new ArgsTypeRef(pre, sym, args) with AbstractTypeRef
- else new ArgsTypeRef(pre, sym, args) with ClassTypeRef
+ if (sym.isAliasType) new AliasArgsTypeRef(pre, sym, args)
+ else if (sym.isAbstractType) new AbstractArgsTypeRef(pre, sym, args)
+ else new ClassArgsTypeRef(pre, sym, args)
}
else {
- if (sym.isAliasType) new NoArgsTypeRef(pre, sym) with AliasTypeRef
- else if (sym.isAbstractType) new NoArgsTypeRef(pre, sym) with AbstractTypeRef
+ if (sym.isAliasType) new AliasNoArgsTypeRef(pre, sym)
+ else if (sym.isAbstractType) new AbstractNoArgsTypeRef(pre, sym)
else if (sym.isRefinementClass) new RefinementTypeRef(pre, sym)
else if (sym.isPackageClass) new PackageTypeRef(pre, sym)
else if (sym.isModuleClass) new ModuleTypeRef(pre, sym)
- else new NoArgsTypeRef(pre, sym) with ClassTypeRef
+ else new ClassNoArgsTypeRef(pre, sym)
}
})
}