Skip to content

Commit ae18049

Browse files
committed
Avoid using Names for fully qualified class names
There is no good reason for these dotted names to be Names and stick around in the name table. Let's use short lived strings instead. Reduces the name table by 5% in terms of entries and 10% in terms of characters when compiling src/scalap/**/*.scala
1 parent ed8d95e commit ae18049

File tree

11 files changed

+120
-94
lines changed

11 files changed

+120
-94
lines changed

src/compiler/scala/tools/nsc/Global.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,9 @@ class Global(var currentSettings: Settings, reporter0: LegacyReporter)
15521552

15531553
reporting.summarizeErrors()
15541554

1555+
// val allNamesArray: Array[String] = allNames().map(_.toString).toArray.sorted
1556+
// allNamesArray.foreach(println(_))
1557+
15551558
if (traceSymbolActivity)
15561559
units map (_.body) foreach (traceSymbols recordSymbolsInTree _)
15571560

src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
7171
protected var isScala: Boolean = _ // does class file describe a scala class?
7272
protected var isScalaRaw: Boolean = _ // this class file is a scala class with no pickled info
7373
protected var busy: Symbol = _ // lock to detect recursive reads
74-
protected var currentClass: Name = _ // JVM name of the current class
74+
protected var currentClass: String = _ // JVM name of the current class
7575
protected var classTParams = Map[Name,Symbol]()
7676
protected var srcfile0 : Option[AbstractFile] = None
7777
protected def moduleClass: Symbol = staticModule.moduleClass
@@ -177,9 +177,9 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
177177
}
178178
}
179179

180-
def getClassSymbol(name: Name): Symbol = {
180+
def getClassSymbol(name: String): Symbol = {
181181
name match {
182-
case name if nme.isModuleName(name) => rootMirror getModuleByName name.dropModule
182+
case name if name.endsWith(nme.MODULE_SUFFIX_STRING) => rootMirror getModuleByName newTermName(name).dropModule
183183
case name => classNameToSymbol(name)
184184
}
185185
}
@@ -252,7 +252,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
252252
values(index) match {
253253
case sym: Symbol => sym
254254
case _ =>
255-
val result = ClassfileParser.this.getClassSymbol(getClassName(index).name)
255+
val result = ClassfileParser.this.getClassSymbol(getClassName(index).value)
256256
recordAtIndex(result, index)
257257
}
258258
}
@@ -303,7 +303,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
303303
val name = getClassName(index)
304304
name.value.charAt(0) match {
305305
case ARRAY_TAG => recordAtIndex(sigToType(null, name.value), index)
306-
case _ => recordAtIndex(classNameToSymbol(name.name), index).tpe_*
306+
case _ => recordAtIndex(classNameToSymbol(name.value), index).tpe_*
307307
}
308308
}
309309
}
@@ -404,13 +404,13 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
404404
NoSymbol.newStubSymbol(name.toTypeName, msg)
405405
}
406406

407-
private def lookupClass(name: Name) = try {
407+
private def lookupClass(name: String) = try {
408408
def lookupTopLevel = {
409-
if (name containsChar '.')
409+
if (name contains '.')
410410
rootMirror getClassByName name
411411
else
412412
// FIXME - we shouldn't be doing ad hoc lookups in the empty package, getClassByName should return the class
413-
definitions.getMember(rootMirror.EmptyPackageClass, name.toTypeName)
413+
definitions.getMember(rootMirror.EmptyPackageClass, newTypeName(name))
414414
}
415415

416416
// For inner classes we usually don't get here: `classNameToSymbol` already returns the symbol
@@ -421,21 +421,23 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
421421
// what the logic below is for (see PR #5822 / scala/bug#9937).
422422
val split = if (isScalaRaw) -1 else name.lastIndexOf('$')
423423
if (split > 0 && split < name.length) {
424-
val outerName = name.subName(0, split)
425-
val innerName = name.subName(split + 1, name.length).toTypeName
424+
val outerName = name.substring(0, split)
425+
val innerName = name.substring(split + 1, name.length)
426426
val outerSym = classNameToSymbol(outerName)
427427

428428
// If the outer class C cannot be found, look for a top-level class C$D
429429
if (outerSym.isInstanceOf[StubSymbol]) lookupTopLevel
430430
else {
431+
val innerNameAsName = newTypeName(innerName)
432+
431433
// We have a java-defined class name C$D and look for a member D of C. But we don't know if
432434
// D is declared static or not, so we have to search both in class C and its companion.
433435
val r = if (outerSym == clazz)
434-
staticScope.lookup(innerName) orElse
435-
instanceScope.lookup(innerName)
436+
staticScope.lookup(innerNameAsName) orElse
437+
instanceScope.lookup(innerNameAsName)
436438
else
437-
lookupMemberAtTyperPhaseIfPossible(outerSym, innerName) orElse
438-
lookupMemberAtTyperPhaseIfPossible(outerSym.companionModule, innerName)
439+
lookupMemberAtTyperPhaseIfPossible(outerSym, innerNameAsName) orElse
440+
lookupMemberAtTyperPhaseIfPossible(outerSym.companionModule, innerNameAsName)
439441
r orElse lookupTopLevel
440442
}
441443
} else
@@ -451,11 +453,11 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
451453
// definitions.getMember can throw a FatalError, for example in pos/t5165b
452454
if (settings.debug)
453455
ex.printStackTrace()
454-
stubClassSymbol(name)
456+
stubClassSymbol(newTypeName(name))
455457
}
456458

457459
/** Return the class symbol of the given name. */
458-
def classNameToSymbol(name: Name): Symbol = {
460+
def classNameToSymbol(name: String): Symbol = {
459461
if (innerClasses contains name)
460462
innerClasses innerSymbol name
461463
else
@@ -467,10 +469,10 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
467469

468470
val jflags = readClassFlags()
469471
val classNameIndex = u2
470-
currentClass = pool.getClassName(classNameIndex).name
472+
currentClass = pool.getClassName(classNameIndex).value
471473

472474
// Ensure that (top-level) classfiles are in the correct directory
473-
val isTopLevel = !(currentClass containsChar '$') // Java class name; *don't* try to to use Scala name decoding (scala/bug#7532)
475+
val isTopLevel = !(currentClass contains '$') // Java class name; *don't* try to to use Scala name decoding (scala/bug#7532)
474476
if (isTopLevel) {
475477
val c = pool.getClassSymbol(classNameIndex)
476478
// scala-dev#248: when a type alias (in a package object) shadows a class symbol, getClassSymbol returns a stub
@@ -633,10 +635,10 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
633635
assert(sig.charAt(index) == ch, (sig.charAt(index), ch))
634636
index += 1
635637
}
636-
def subName(isDelimiter: Char => Boolean): Name = {
638+
def subName(isDelimiter: Char => Boolean): String = {
637639
val start = index
638640
while (!isDelimiter(sig.charAt(index))) { index += 1 }
639-
newTermName(sigChars, start, index - start)
641+
new String(sigChars, start, index - start)
640642
}
641643
def sig2type(tparams: immutable.Map[Name,Symbol], skiptvs: Boolean): Type = {
642644
val tag = sig.charAt(index); index += 1
@@ -708,7 +710,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
708710
var tpe = processClassType(processInner(classSym.tpe_*))
709711
while (sig.charAt(index) == '.') {
710712
accept('.')
711-
val name = subName(c => c == ';' || c == '<' || c == '.').toTypeName
713+
val name = newTypeName(subName(c => c == ';' || c == '<' || c == '.'))
712714
val clazz = tpe.member(name)
713715
val dummyArgs = Nil // the actual arguments are added in processClassType
714716
val inner = typeRef(pre = tpe, sym = clazz, args = dummyArgs)
@@ -745,7 +747,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
745747
sig2type(tparams, skiptvs)
746748
JavaMethodType(sym.newSyntheticValueParams(paramtypes.toList), restype)
747749
case 'T' =>
748-
val n = subName(';'.==).toTypeName
750+
val n = newTypeName(subName(';'.==))
749751
index += 1
750752
if (skiptvs) AnyTpe
751753
else tparams(n).typeConstructor
@@ -769,15 +771,15 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
769771
index += 1
770772
val start = index
771773
while (sig.charAt(index) != '>') {
772-
val tpname = subName(':'.==).toTypeName
774+
val tpname = newTypeName(subName(':'.==))
773775
val s = sym.newTypeParameter(tpname)
774776
tparams = tparams + (tpname -> s)
775777
sig2typeBounds(tparams, skiptvs = true)
776778
newTParams += s
777779
}
778780
index = start
779781
while (sig.charAt(index) != '>') {
780-
val tpname = subName(':'.==).toTypeName
782+
val tpname = newTypeName(subName(':'.==))
781783
val s = tparams(tpname)
782784
s.setInfo(sig2typeBounds(tparams, skiptvs = false))
783785
}
@@ -999,8 +1001,8 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
9991001
* and implicitly current class' superclasses.
10001002
*/
10011003
private def enterOwnInnerClasses(): Unit = {
1002-
def className(name: Name): Name =
1003-
name.subName(name.lastPos('.') + 1, name.length)
1004+
def className(name: String): String =
1005+
name.substring(name.lastIndexOf('.') + 1, name.length)
10041006

10051007
def enterClassAndModule(entry: InnerClassEntry, file: AbstractFile): Unit = {
10061008
def jflags = entry.jflags
@@ -1048,8 +1050,8 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
10481050
decls unlink e
10491051
}
10501052

1051-
val cName = className(entry.externalName)
1052-
unlinkIfPresent(cName.toTermName)
1053+
val cName = newTermName(className(entry.externalName))
1054+
unlinkIfPresent(cName)
10531055
unlinkIfPresent(cName.toTypeName)
10541056
}
10551057

@@ -1195,15 +1197,15 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
11951197

11961198
/** An entry in the InnerClasses attribute of this class file. */
11971199
case class InnerClassEntry(external: NameOrString, outer: NameOrString, name: NameOrString, jflags: JavaAccFlags) {
1198-
def externalName = external.name
1199-
def outerName = outer.name
1200+
def externalName = external.value
1201+
def outerName = outer.value
12001202
def originalName = name.name
12011203
def isModule = originalName.isTermName
12021204
def scope = if (jflags.isStatic) staticScope else instanceScope
12031205
def enclosing = if (jflags.isStatic) enclModule else enclClass
12041206

12051207
// The name of the outer class, without its trailing $ if it has one.
1206-
private def strippedOuter = outerName.dropModule
1208+
private def strippedOuter = outerName.stripSuffix(nme.MODULE_SUFFIX_STRING)
12071209
private def isInner = innerClasses contains strippedOuter
12081210
private def enclClass = if (isInner) innerClasses innerSymbol strippedOuter else classNameToSymbol(strippedOuter)
12091211
private def enclModule = enclClass.companionModule
@@ -1215,10 +1217,10 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
12151217
* If the given name is not an inner class, it returns the symbol found in `definitions`.
12161218
*/
12171219
object innerClasses {
1218-
private val inners = mutable.HashMap[Name, InnerClassEntry]()
1220+
private val inners = mutable.HashMap[String, InnerClassEntry]()
12191221

1220-
def contains(name: Name) = inners contains name
1221-
def getEntry(name: Name) = inners get name
1222+
def contains(name: String) = inners contains name
1223+
def getEntry(name: String) = inners get name
12221224
def entries = inners.values
12231225

12241226
def add(entry: InnerClassEntry): Unit = {
@@ -1228,7 +1230,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
12281230
}
12291231
inners(entry.externalName) = entry
12301232
}
1231-
def innerSymbol(externalName: Name): Symbol = this getEntry externalName match {
1233+
def innerSymbol(externalName: String): Symbol = this getEntry externalName match {
12321234
case Some(entry) => innerSymbol(entry)
12331235
case _ => NoSymbol
12341236
}
@@ -1270,8 +1272,8 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
12701272
private final class ClassTypeCompleter(name: Name, jflags: JavaAccFlags, parent: NameOrString, ifaces: List[NameOrString]) extends JavaTypeCompleter {
12711273
override def complete(sym: symbolTable.Symbol): Unit = {
12721274
val info = if (sig != null) sigToType(sym, sig) else {
1273-
val superTpe = if (parent == null) definitions.AnyClass.tpe_* else getClassSymbol(parent.name).tpe_*
1274-
var ifacesTypes = ifaces.filterNot(_ eq null).map(x => getClassSymbol(x.name).tpe_*)
1275+
val superTpe = if (parent == null) definitions.AnyClass.tpe_* else getClassSymbol(parent.value).tpe_*
1276+
var ifacesTypes = ifaces.filterNot(_ eq null).map(x => getClassSymbol(x.value).tpe_*)
12751277
ClassInfoType(superTpe :: ifacesTypes, instanceScope, clazz)
12761278
}
12771279
sym.setInfo(info)
@@ -1280,7 +1282,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
12801282

12811283
private final class MemberTypeCompleter(name: Name, jflags: JavaAccFlags, descriptor: String) extends JavaTypeCompleter {
12821284
override def isJavaVarargsMethod: Boolean = jflags.isVarargs
1283-
override def javaThrownExceptions: List[Symbol] = exceptions.map(e => classNameToSymbol(e.name))
1285+
override def javaThrownExceptions: List[Symbol] = exceptions.map(e => classNameToSymbol(e.value))
12841286
override def complete(sym: symbolTable.Symbol): Unit = {
12851287
def descriptorInfo = sigToType(sym, descriptor)
12861288
val hasOuterParam = (name == nme.CONSTRUCTOR) && (descriptorInfo match {
@@ -1337,7 +1339,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
13371339
for (e <- exceptions) {
13381340
// we call initialize due to the fact that we call Symbol.isMonomorphicType in addThrowsAnnotation
13391341
// and that method requires Symbol to be forced to give the right answers, see scala/bug#7107 for details
1340-
val cls = getClassSymbol(e.name)
1342+
val cls = getClassSymbol(e.value)
13411343
sym withAnnotation AnnotationInfo.lazily {
13421344
val throwableTpe = cls.tpe_*
13431345
AnnotationInfo(appliedType(ThrowsClass, throwableTpe), List(Literal(Constant(throwableTpe))), Nil)

src/reflect/scala/reflect/internal/Definitions.scala

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,11 @@ trait Definitions extends api.StandardDefinitions {
190190

191191
// It becomes tricky to create dedicated objects for other symbols because
192192
// of initialization order issues.
193-
lazy val JavaLangPackage = getPackage(TermName("java.lang"))
193+
lazy val JavaLangPackage = getPackage("java.lang")
194194
lazy val JavaLangPackageClass = JavaLangPackage.moduleClass.asClass
195-
lazy val ScalaPackage = getPackage(TermName("scala"))
195+
lazy val ScalaPackage = getPackage("scala")
196196
lazy val ScalaPackageClass = ScalaPackage.moduleClass.asClass
197-
lazy val RuntimePackage = getPackage(TermName("scala.runtime"))
197+
lazy val RuntimePackage = getPackage("scala.runtime")
198198
lazy val RuntimePackageClass = RuntimePackage.moduleClass.asClass
199199

200200
def javaTypeToValueClass(jtype: Class[_]): Symbol = jtype match {
@@ -290,7 +290,7 @@ trait Definitions extends api.StandardDefinitions {
290290
// top types
291291
lazy val AnyClass = enterNewClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT) markAllCompleted
292292
lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectTpe) markAllCompleted
293-
lazy val ObjectClass = getRequiredClass(sn.Object.toString)
293+
lazy val ObjectClass = getRequiredClass("java.lang.Object")
294294

295295
// Cached types for core monomorphic classes
296296
lazy val AnyRefTpe = AnyRefClass.tpe
@@ -341,12 +341,12 @@ trait Definitions extends api.StandardDefinitions {
341341

342342
// exceptions and other throwables
343343
lazy val ClassCastExceptionClass = requiredClass[ClassCastException]
344-
lazy val IndexOutOfBoundsExceptionClass = getClassByName(sn.IOOBException)
345-
lazy val InvocationTargetExceptionClass = getClassByName(sn.InvTargetException)
344+
lazy val IndexOutOfBoundsExceptionClass = getClassByName("java.lang.IndexOutOfBoundsException")
345+
lazy val InvocationTargetExceptionClass = getClassByName("java.lang.reflect.InvocationTargetException")
346346
lazy val MatchErrorClass = requiredClass[MatchError]
347347
lazy val NonLocalReturnControlClass = requiredClass[scala.runtime.NonLocalReturnControl[_]]
348-
lazy val NullPointerExceptionClass = getClassByName(sn.NPException)
349-
lazy val ThrowableClass = getClassByName(sn.Throwable)
348+
lazy val NullPointerExceptionClass = getClassByName("java.lang.NullPointerException")
349+
lazy val ThrowableClass = getClassByName("java.lang.Throwable")
350350
lazy val UninitializedErrorClass = requiredClass[UninitializedFieldError]
351351
lazy val RuntimeExceptionClass = requiredClass[RuntimeException]
352352
lazy val IllegalArgExceptionClass = requiredClass[IllegalArgumentException]
@@ -497,7 +497,7 @@ trait Definitions extends api.StandardDefinitions {
497497

498498
// reflection / structural types
499499
lazy val SoftReferenceClass = requiredClass[java.lang.ref.SoftReference[_]]
500-
lazy val MethodClass = getClassByName(sn.MethodAsObject)
500+
lazy val MethodClass = getClassByName("java.lang.reflect.Method")
501501
lazy val EmptyMethodCacheClass = requiredClass[scala.runtime.EmptyMethodCache]
502502
lazy val MethodCacheClass = requiredClass[scala.runtime.MethodCache]
503503
def methodCache_find = getMemberMethod(MethodCacheClass, nme.find_)
@@ -1310,7 +1310,7 @@ trait Definitions extends api.StandardDefinitions {
13101310
// Trying to allow for deprecated locations
13111311
sym.isAliasType && isMetaAnnotation(sym.info.typeSymbol)
13121312
)
1313-
lazy val metaAnnotations: Set[Symbol] = getPackage(TermName("scala.annotation.meta")).info.members filter (_ isSubClass StaticAnnotationClass) toSet
1313+
lazy val metaAnnotations: Set[Symbol] = getPackage("scala.annotation.meta").info.members filter (_ isSubClass StaticAnnotationClass) toSet
13141314

13151315
// According to the scala.annotation.meta package object:
13161316
// * By default, annotations on (`val`-, `var`- or plain) constructor parameters

0 commit comments

Comments
 (0)