summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/cmd/FromString.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-11-01 11:40:26 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-11-01 11:56:54 +0100
commita1d9656299a90d9ea4d5aa14a7873e3b4941eb59 (patch)
tree21affb2ad94f25be36b2b2c53c3f19b5c5e8a21f /src/compiler/scala/tools/cmd/FromString.scala
parentc38235fd44f1ccb280e31a2f34f58deb59c5b2ee (diff)
downloadscala-a1d9656299a90d9ea4d5aa14a7873e3b4941eb59.tar.gz
scala-a1d9656299a90d9ea4d5aa14a7873e3b4941eb59.tar.bz2
scala-a1d9656299a90d9ea4d5aa14a7873e3b4941eb59.zip
Don't use runtime reflection from the batch compiler.
Not only does this save a big chunk of time on startup by avoiding classloading and symbol table population, but it also seems to improve steady state performance of the compiler. Theory: JIT can optimize more aggressively without the SynchronizedXxx decorators and the like being in the classloader. See "Class Heirarchy Analyis" in [1] This commit does this by: - Avoiding use of FromString in pattern matcher, instead using an established mechanism to parse system properties. - Changes FromString back to use OptManifest. AFAICT, this is now only a dependency of scala.tools.cmd.gen.Codegen, so this is just a defensive measure. The REPL still uses runtime reflection, so will pay a little performance tax. Benchmark: avg shortest 10 times 744ms # before avg shortest 10 times 675ms # after [1] https://wikis.oracle.com/display/HotSpotInternals/PerformanceTechniques
Diffstat (limited to 'src/compiler/scala/tools/cmd/FromString.scala')
-rw-r--r--src/compiler/scala/tools/cmd/FromString.scala19
1 files changed, 9 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/cmd/FromString.scala b/src/compiler/scala/tools/cmd/FromString.scala
index 433bbb167e..0b074efc0f 100644
--- a/src/compiler/scala/tools/cmd/FromString.scala
+++ b/src/compiler/scala/tools/cmd/FromString.scala
@@ -6,21 +6,20 @@
package scala.tools
package cmd
-import scala.tools.nsc.io.{ File, Directory }
-import scala.reflect.runtime.{universe => ru}
-import scala.tools.reflect.StdRuntimeTags._
+import nsc.io.{ Path, File, Directory }
+import scala.reflect.OptManifest
/** A general mechanism for defining how a command line argument
* (always a String) is transformed into an arbitrary type. A few
* example instances are in the companion object, but in general
* either IntFromString will suffice or you'll want custom transformers.
*/
-abstract class FromString[+T](implicit t: ru.TypeTag[T]) extends PartialFunction[String, T] {
+abstract class FromString[+T](implicit m: OptManifest[T]) extends PartialFunction[String, T] {
def apply(s: String): T
def isDefinedAt(s: String): Boolean = true
def zero: T = apply("")
- def targetString: String = t.toString
+ def targetString: String = m.toString
}
object FromString {
@@ -29,13 +28,13 @@ object FromString {
/** Path related stringifiers.
*/
- val ExistingDir: FromString[Directory] = new FromString[Directory]()(tagOfDirectory) {
+ val ExistingDir: FromString[Directory] = new FromString[Directory] {
override def isDefinedAt(s: String) = toDir(s).isDirectory
def apply(s: String): Directory =
if (isDefinedAt(s)) toDir(s)
else cmd.runAndExit(println("'%s' is not an existing directory." format s))
}
- def ExistingDirRelativeTo(root: Directory) = new FromString[Directory]()(tagOfDirectory) {
+ def ExistingDirRelativeTo(root: Directory) = new FromString[Directory] {
private def resolve(s: String) = (toDir(s) toAbsoluteWithRoot root).toDirectory
override def isDefinedAt(s: String) = resolve(s).isDirectory
def apply(s: String): Directory =
@@ -46,19 +45,19 @@ object FromString {
/** Argument expander, i.e. turns single argument "foo bar baz" into argument
* list "foo", "bar", "baz".
*/
- val ArgumentsFromString: FromString[List[String]] = new FromString[List[String]]()(tagOfListOfString) {
+ val ArgumentsFromString: FromString[List[String]] = new FromString[List[String]] {
def apply(s: String) = toArgs(s)
}
/** Identity.
*/
- implicit val StringFromString: FromString[String] = new FromString[String]()(tagOfString) {
+ implicit val StringFromString: FromString[String] = new FromString[String] {
def apply(s: String): String = s
}
/** Implicit as the most likely to be useful as-is.
*/
- implicit val IntFromString: FromString[Int] = new FromString[Int]()(tagOfInt) {
+ implicit val IntFromString: FromString[Int] = new FromString[Int] {
override def isDefinedAt(s: String) = safeToInt(s).isDefined
def apply(s: String) = safeToInt(s).get
def safeToInt(s: String): Option[Int] = try Some(java.lang.Integer.parseInt(s)) catch { case _: NumberFormatException => None }