diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-03-27 15:24:20 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-03-27 15:24:35 +0100 |
commit | ccf886c208a1ed5cc2ff8d8040cff2c76d6f6032 (patch) | |
tree | 96a3f69d1b90ed4e050a27547571e40348554ff1 /src/reflect | |
parent | 2efc6d56e6ee14dc7d86bc0667c921b082e8b9b4 (diff) | |
download | scala-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.scala | 20 |
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) } }) } |