summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-05-09 19:07:40 +0000
committerPaul Phillips <paulp@improving.org>2011-05-09 19:07:40 +0000
commit1a92fb60e6853fca4b4e5bd0d03f913c300100ae (patch)
treeb287e88e828d2dd788d6b9c1bb0242ae4f03c21b
parent41ac77599ce022087ec595b6da4874b39472019b (diff)
downloadscala-1a92fb60e6853fca4b4e5bd0d03f913c300100ae.tar.gz
scala-1a92fb60e6853fca4b4e5bd0d03f913c300100ae.tar.bz2
scala-1a92fb60e6853fca4b4e5bd0d03f913c300100ae.zip
Another round of optimization.
exciting as the original, but not a bad way to spend a rainy afternoon. Most changes involve files and paths, which are we find exercised rather heavily at startup. This patch takes about 15 seconds off my time to build quick. No review.
-rw-r--r--src/compiler/scala/tools/nsc/io/AbstractFile.scala26
-rw-r--r--src/compiler/scala/tools/nsc/io/Path.scala17
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala42
-rw-r--r--src/library/scala/collection/mutable/StringBuilder.scala11
-rwxr-xr-xsrc/library/scala/reflect/generic/Flags.scala39
6 files changed, 99 insertions, 38 deletions
diff --git a/src/compiler/scala/tools/nsc/io/AbstractFile.scala b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
index 12a632fca6..059ca9bd9e 100644
--- a/src/compiler/scala/tools/nsc/io/AbstractFile.scala
+++ b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
@@ -19,7 +19,7 @@ import scala.collection.mutable.ArrayBuffer
*/
object AbstractFile {
/** Returns "getFile(new File(path))". */
- def getFile(path: String): AbstractFile = getFile(Path(path))
+ def getFile(path: String): AbstractFile = getFile(File(path))
def getFile(path: Path): AbstractFile = getFile(path.toFile)
/**
@@ -42,7 +42,7 @@ object AbstractFile {
*/
def getDirectory(file: File): AbstractFile =
if (file.isDirectory) new PlainFile(file)
- else if (file.isFile && Path.isJarOrZip(file)) ZipArchive fromFile file
+ else if (file.isFile && Path.isExtensionJarOrZip(file.jfile)) ZipArchive fromFile file
else null
/**
@@ -54,7 +54,7 @@ object AbstractFile {
* @return ...
*/
def getURL(url: URL): AbstractFile = {
- if (url == null || !Path.isJarOrZip(url.getPath)) null
+ if (url == null || !Path.isExtensionJarOrZip(url.getPath)) null
else ZipArchive fromURL url
}
}
@@ -92,7 +92,8 @@ abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
def path: String
/** Checks extension case insensitively. */
- def hasExtension(other: String) = Path(path) hasExtension other
+ def hasExtension(other: String) = extension == other.toLowerCase
+ private lazy val extension: String = Path.extension(name)
/** The absolute file, if this is a relative file. */
def absolute: AbstractFile
@@ -102,7 +103,6 @@ abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
/** Returns the underlying File if any and null otherwise. */
def file: JFile
- def sfile = Option(file) map (x => File(x)) // XXX
/** An underlying source, if known. Mostly, a zip/jar file. */
def underlyingSource: Option[AbstractFile] = None
@@ -111,7 +111,7 @@ abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
def exists: Boolean = (file eq null) || file.exists
/** Does this abstract file represent something which can contain classfiles? */
- def isClassContainer = isDirectory || (sfile exists (Path isJarOrZip _))
+ def isClassContainer = isDirectory || (file != null && (extension == "jar" || extension == "zip"))
/** Create a file on disk, if one does not exist already. */
def create(): Unit
@@ -217,13 +217,23 @@ abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
file
}
+ private def fileOrSubdirectoryNamed(name: String, isDir: Boolean): AbstractFile = {
+ val lookup = lookupName(name, isDir)
+ if (lookup != null) lookup
+ else {
+ val jfile = new JFile(file, name)
+ if (isDir) jfile.mkdirs() else jfile.createNewFile()
+ new PlainFile(jfile)
+ }
+ }
+
/**
* Get the file in this directory with the given name,
* creating an empty file if it does not already existing.
*/
def fileNamed(name: String): AbstractFile = {
assert(isDirectory, "Tried to find '%s' in '%s' but it is not a directory".format(name, path))
- Option(lookupName(name, false)) getOrElse new PlainFile((sfile.get / name).createFile())
+ fileOrSubdirectoryNamed(name, false)
}
/**
@@ -232,7 +242,7 @@ abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
*/
def subdirectoryNamed(name: String): AbstractFile = {
assert (isDirectory, "Tried to find '%s' in '%s' but it is not a directory".format(name, path))
- Option(lookupName(name, true)) getOrElse new PlainFile((sfile.get / name).createDirectory())
+ fileOrSubdirectoryNamed(name, true)
}
protected def unsupported(): Nothing = unsupported(null)
diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala
index beae4b8647..86839437f4 100644
--- a/src/compiler/scala/tools/nsc/io/Path.scala
+++ b/src/compiler/scala/tools/nsc/io/Path.scala
@@ -28,6 +28,19 @@ import scala.util.Random.alphanumeric
*/
object Path {
+ def isExtensionJarOrZip(jfile: JFile): Boolean = isExtensionJarOrZip(jfile.getName)
+ def isExtensionJarOrZip(name: String): Boolean = {
+ val ext = extension(name)
+ ext == "jar" || ext == "zip"
+ }
+ def extension(name: String): String = {
+ var i = name.length - 1
+ while (i >= 0 && name.charAt(i) != '.')
+ i -= 1
+
+ if (i < 0) ""
+ else name.substring(i + 1).toLowerCase
+ }
def isJarOrZip(f: Path, examineFile: Boolean = true) = Jar.isJarOrZip(f, examineFile)
// not certain these won't be problematic, but looks good so far
@@ -173,8 +186,8 @@ class Path private[io] (val jfile: JFile) {
// }
// compares against extensions in a CASE INSENSITIVE way.
def hasExtension(ext: String, exts: String*) = {
- val xs = (ext +: exts) map (_.toLowerCase)
- xs contains extension.toLowerCase
+ val lower = extension.toLowerCase
+ ext.toLowerCase == lower || exts.exists(_.toLowerCase == lower)
}
// returns the filename without the extension.
def stripExtension: String = name stripSuffix ("." + extension)
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 005a3c87ed..6b419c629d 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -316,7 +316,7 @@ trait Definitions extends reflect.generic.StandardDefinitions {
lazy val TraversableClass = getClass("scala.collection.Traversable")
lazy val ListModule = getModule("scala.collection.immutable.List")
- def List_apply = getMember(ListModule, nme.apply)
+ lazy val List_apply = getMember(ListModule, nme.apply)
lazy val NilModule = getModule("scala.collection.immutable.Nil")
lazy val SeqModule = getModule("scala.collection.Seq")
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index e1cf6e55d9..c3731150c4 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -8,7 +8,7 @@ package scala.tools.nsc
package util
import java.net.URL
-import scala.collection.mutable
+import scala.collection.{ mutable, immutable }
import io.{ File, Directory, Path, Jar, AbstractFile, ClassAndJarInfo }
import scala.tools.util.StringOps.splitWhere
import Jar.isJarOrZip
@@ -103,8 +103,10 @@ object ClassPath {
/** Expand dir out to contents, a la extdir */
def expandDir(extdir: String): List[String] = {
- val dir = Option(AbstractFile getDirectory extdir) getOrElse (return Nil)
- dir filter (_.isClassContainer) map (dir.sfile.get / _.name path) toList
+ AbstractFile getDirectory extdir match {
+ case null => Nil
+ case dir => dir filter (_.isClassContainer) map (x => new java.io.File(dir.file, x.name) getPath) toList
+ }
}
/** A useful name filter. */
@@ -298,7 +300,10 @@ abstract class ClassPath[T] {
class SourcePath[T](dir: AbstractFile, val context: ClassPathContext[T]) extends ClassPath[T] {
def name = dir.name
override def origin = dir.underlyingSource map (_.path)
- def asURLs = dir.sfile.toList map (_.toURL)
+ def asURLs = dir.file match {
+ case null => Nil
+ case file => File(file).toURL :: Nil
+ }
def asClasspathString = dir.path
val sourcepaths: IndexedSeq[AbstractFile] = IndexedSeq(dir)
@@ -321,19 +326,30 @@ class SourcePath[T](dir: AbstractFile, val context: ClassPathContext[T]) extends
class DirectoryClassPath(val dir: AbstractFile, val context: ClassPathContext[AbstractFile]) extends ClassPath[AbstractFile] {
def name = dir.name
override def origin = dir.underlyingSource map (_.path)
- def asURLs = dir.sfile.toList map (_.toURL)
+ def asURLs = dir.file match {
+ case null => Nil
+ case file => File(file).toURL :: Nil
+ }
def asClasspathString = dir.path
val sourcepaths: IndexedSeq[AbstractFile] = IndexedSeq()
- lazy val classes: IndexedSeq[ClassRep] = dir flatMap { f =>
- if (f.isDirectory || !validClassFile(f.name)) Nil
- else List(ClassRep(Some(f), None))
- } toIndexedSeq
+ lazy val classes: IndexedSeq[ClassRep] = {
+ val buf = immutable.Vector.newBuilder[ClassRep]
+ dir foreach { f =>
+ if (!f.isDirectory && validClassFile(f.name))
+ buf += ClassRep(Some(f), None)
+ }
+ buf.result
+ }
- lazy val packages: IndexedSeq[DirectoryClassPath] = dir flatMap { f =>
- if (f.isDirectory && validPackage(f.name)) List(new DirectoryClassPath(f, context))
- else Nil
- } toIndexedSeq
+ lazy val packages: IndexedSeq[DirectoryClassPath] = {
+ val buf = immutable.Vector.newBuilder[DirectoryClassPath]
+ dir foreach { f =>
+ if (f.isDirectory && validPackage(f.name))
+ buf += new DirectoryClassPath(f, context)
+ }
+ buf.result
+ }
override def toString() = "directory classpath: "+ dir
}
diff --git a/src/library/scala/collection/mutable/StringBuilder.scala b/src/library/scala/collection/mutable/StringBuilder.scala
index edd59a8221..8d7ed8bcd2 100644
--- a/src/library/scala/collection/mutable/StringBuilder.scala
+++ b/src/library/scala/collection/mutable/StringBuilder.scala
@@ -171,6 +171,17 @@ final class StringBuilder(private val underlying: JavaStringBuilder)
*/
def +=(x: Char): this.type = { append(x); this }
+ /** Optimization.
+ */
+ def ++=(s: String): this.type = {
+ underlying append s
+ this
+ }
+ def appendAll(xs: String): StringBuilder = {
+ underlying append xs
+ this
+ }
+
/** !!! This should create a new sequence.
*/
def +(x: Char): this.type = { +=(x); this }
diff --git a/src/library/scala/reflect/generic/Flags.scala b/src/library/scala/reflect/generic/Flags.scala
index d7c8ff9296..3291047831 100755
--- a/src/library/scala/reflect/generic/Flags.scala
+++ b/src/library/scala/reflect/generic/Flags.scala
@@ -102,7 +102,7 @@ class Flags extends ModifierFlags {
final val PickledFlags: Long = 0xFFFFFFFFL
- private val rawPickledCorrespondence = List(
+ private def rawPickledCorrespondence = Array(
(IMPLICIT, IMPLICIT_PKL),
(FINAL, FINAL_PKL),
(PRIVATE, PRIVATE_PKL),
@@ -116,20 +116,31 @@ class Flags extends ModifierFlags {
(MODULE, MODULE_PKL),
(INTERFACE, INTERFACE_PKL)
)
- private def mkCorrespondenceArray(correspondence: List[(Int, Int)]) = {
- def f(flags: Int): Int = {
- correspondence.foldLeft(0) {
- case (result, (oldFlag, newFlag)) =>
- if ((flags & oldFlag) != 0) result | newFlag
- else result
- }
+ private val rawFlags: Array[Int] = rawPickledCorrespondence map (_._1)
+ private val pickledFlags: Array[Int] = rawPickledCorrespondence map (_._2)
+
+ private def r2p(flags: Int): Int = {
+ var result = 0
+ var i = 0
+ while (i < rawFlags.length) {
+ if ((flags & rawFlags(i)) != 0)
+ result |= pickledFlags(i)
+
+ i += 1
+ }
+ result
+ }
+ private def p2r(flags: Int): Int = {
+ var result = 0
+ var i = 0
+ while (i < rawFlags.length) {
+ if ((flags & pickledFlags(i)) != 0)
+ result |= rawFlags(i)
+
+ i += 1
}
- 0 to PKL_MASK map f toArray
+ result
}
- /** A map from the raw to pickled flags, and vice versa.
- */
- private val r2p = mkCorrespondenceArray(rawPickledCorrespondence)
- private val p2r = mkCorrespondenceArray(rawPickledCorrespondence map (_.swap))
// Generated by mkFlagToStringMethod() at Mon Oct 11 10:07:29 PDT 2010
@annotation.switch override def flagToString(flag: Long): String = flag match {
@@ -232,7 +243,7 @@ class Flags extends ModifierFlags {
// List of the raw flags, in pickled order
protected val pickledListOrder: List[Long] = {
val all = 0 to 62 map (1L << _)
- val front = rawPickledCorrespondence map (_._1.toLong)
+ val front = rawFlags map (_.toLong)
front.toList ++ (all filterNot (front contains _))
}