summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGilles Dubochet <gilles.dubochet@epfl.ch>2009-03-12 13:38:43 +0000
committerGilles Dubochet <gilles.dubochet@epfl.ch>2009-03-12 13:38:43 +0000
commit5af0e1461b7562798c3d7c3fcdce346107f5af0b (patch)
tree537a2b5d7f493e7d5fa71e1a1e320a62511edfa8 /src
parentf2dfc4a54a562bfbbf9753a3430c4186917c9788 (diff)
downloadscala-5af0e1461b7562798c3d7c3fcdce346107f5af0b.tar.gz
scala-5af0e1461b7562798c3d7c3fcdce346107f5af0b.tar.bz2
scala-5af0e1461b7562798c3d7c3fcdce346107f5af0b.zip
Bytecode generated for structural calls is impr...
Bytecode generated for structural calls is improved slightly. A test shows an improvement of roughly 5% for structural methods' call times.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala54
-rw-r--r--src/library/scala/runtime/MethodCache.scala22
2 files changed, 41 insertions, 35 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index 52fbc7b83c..db88df5dc5 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -283,14 +283,13 @@ abstract class CleanUp extends Transform {
def reflMethod$Method(forReceiver: JClass[_]): JMethod = {
var method: JMethod = reflPoly$Cache.find(forReceiver)
- if (method == null) {
+ if (method != null)
+ return method
+ else {
method = forReceiver.getMethod("xyz", reflParams$Cache)
reflPoly$Cache = reflPoly$Cache.add(forReceiver, method)
+ return method
}
- // At that point, method is always non-null: getMethod will have previously
- // returned by throwing an exception if it can't find the method. Obviously,
- // CleanUp should not generate dynamic calls that are unsound.
- method
}
*/
@@ -313,34 +312,33 @@ abstract class CleanUp extends Transform {
Select(gen.mkAttributedRef(reflPolyCacheSym), methodCache_find),
List(gen.mkAttributedRef(forReceiverSym))
)
- ),
- If(
- Apply(Select(gen.mkAttributedRef(methodSym), Object_eq), List(Literal(Constant(null)))),
- Block(
- List(
- Assign(gen.mkAttributedRef(methodSym),
- Apply(
- Select(gen.mkAttributedRef(forReceiverSym), Class_getMethod),
- List(
- Literal(Constant(method)),
- gen.mkAttributedRef(reflParamsCacheSym)
- )
- )
- ),
- Assign(
- gen.mkAttributedRef(reflPolyCacheSym),
- Apply(
- Select(gen.mkAttributedRef(reflPolyCacheSym), methodCache_add),
- List(gen.mkAttributedRef(forReceiverSym), gen.mkAttributedRef(methodSym))
+ )
+ ),
+ If(
+ Apply(Select(gen.mkAttributedRef(methodSym), Object_ne), List(Literal(Constant(null)))),
+ Return(gen.mkAttributedRef(methodSym)),
+ Block(
+ List(
+ Assign(gen.mkAttributedRef(methodSym),
+ Apply(
+ Select(gen.mkAttributedRef(forReceiverSym), Class_getMethod),
+ List(
+ Literal(Constant(method)),
+ gen.mkAttributedRef(reflParamsCacheSym)
)
)
),
- Literal(Constant(()))
+ Assign(
+ gen.mkAttributedRef(reflPolyCacheSym),
+ Apply(
+ Select(gen.mkAttributedRef(reflPolyCacheSym), methodCache_add),
+ List(gen.mkAttributedRef(forReceiverSym), gen.mkAttributedRef(methodSym))
+ )
+ )
),
- EmptyTree
+ Return(gen.mkAttributedRef(methodSym))
)
- ),
- gen.mkAttributedRef(methodSym)
+ )
)
}
diff --git a/src/library/scala/runtime/MethodCache.scala b/src/library/scala/runtime/MethodCache.scala
index a763329bc4..1c41c7db11 100644
--- a/src/library/scala/runtime/MethodCache.scala
+++ b/src/library/scala/runtime/MethodCache.scala
@@ -42,7 +42,10 @@ final class EmptyMethodCache extends MethodCache {
}
-final class MegaMethodCache(forName: String, forParameterTypes: Array[JClass[_]]) extends MethodCache {
+final class MegaMethodCache(
+ private[this] val forName: String,
+ private[this] val forParameterTypes: Array[JClass[_]]
+) extends MethodCache {
def find(forReceiver: JClass[_]): JMethod =
forReceiver.getMethod(forName, forParameterTypes:_*)
@@ -51,18 +54,23 @@ final class MegaMethodCache(forName: String, forParameterTypes: Array[JClass[_]]
}
-final class PolyMethodCache(next: MethodCache, receiver: JClass[_], method: JMethod, complexity: Int) extends MethodCache {
+final class PolyMethodCache(
+ private[this] val next: MethodCache,
+ private[this] val receiver: JClass[_],
+ private[this] val method: JMethod,
+ private[this] val complexity: Int
+) extends MethodCache {
def find(forReceiver: JClass[_]): JMethod =
- if (forReceiver == receiver)
- method
+ if (forReceiver eq receiver)
+ return method
else
- next.find(forReceiver) // tail call is optimised, confirm with -Ylog:tailcalls
+ return next.find(forReceiver) // tail call is optimised, confirm with -Ylog:tailcalls
def add(forReceiver: JClass[_], forMethod: JMethod): MethodCache =
if (complexity < 160) // TODO: come up with a more realistic number
- new PolyMethodCache(this, forReceiver, forMethod, complexity + 1)
+ return new PolyMethodCache(this, forReceiver, forMethod, complexity + 1)
else
- new MegaMethodCache(forMethod.getName, forMethod.getParameterTypes)
+ return new MegaMethodCache(forMethod.getName, forMethod.getParameterTypes)
}