diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-09-13 22:45:10 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-09-14 21:10:02 +1000 |
commit | a5bb6e00f051bf93fe7df4a02583eba478fa5ca1 (patch) | |
tree | 0ee00b83916dbd5b7bb8ca42956335107432ee3f /src/compiler/scala/tools/nsc/transform/Fields.scala | |
parent | 05016d9035ab9b1c866bd9f12fdd0491f1ea0cbb (diff) | |
download | scala-a5bb6e00f051bf93fe7df4a02583eba478fa5ca1.tar.gz scala-a5bb6e00f051bf93fe7df4a02583eba478fa5ca1.tar.bz2 scala-a5bb6e00f051bf93fe7df4a02583eba478fa5ca1.zip |
SD-225 Use a "lzycompute" method for module initialization
The monitors and module instantation were inliuned into the module accessor
method in b2e0911. However, this seems to have had a detrimental impact on
performance. This might be because the module accessors are now above the
"always inline" HotSpot threshold of 35 bytes, or perhaps because they
contain monitor-entry/exit and exception handlers.
This commit returns to the the 2.11.8 appraoch of factoring
the the second check of the doublecheck locking into a method.
I've done this by declaring a nested method within the accessor;
this will be lifted out to the class level by lambdalift.
This represents a slight deviation from the implementation strategy used
for lazy accessors, which create a symbol for the slowpath method in
the info transform and generate the corresponding DefDef as a class
member. I don't believe this deviation is particular worrisome, though.
I have bootstrapped the compiler through this commit and found that
the drastic regression in compiling the shapeless test suite is solved.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/Fields.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Fields.scala | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Fields.scala b/src/compiler/scala/tools/nsc/transform/Fields.scala index a383b65192..45741eb391 100644 --- a/src/compiler/scala/tools/nsc/transform/Fields.scala +++ b/src/compiler/scala/tools/nsc/transform/Fields.scala @@ -22,7 +22,7 @@ import symtab.Flags._ * in the first (closest in the subclassing lattice) subclass (not a trait) of a trait. * * For lazy vals and modules, we emit accessors that using double-checked locking (DCL) to balance thread safety - * and performance. A lazy val gets a compute method for the DCL's slow path, for a module it's all done in the accessor. + * and performance. For both lazy vals and modules, the a compute method contains the DCL's slow path. * * Local lazy vals do not receive bitmaps, but use a Lazy*Holder that has the volatile init bit and the computed value. * See `mkLazyLocalDef`. @@ -236,7 +236,9 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor * * TODO: optimize using local variable? */ - Block(If(needsInit, gen.mkSynchronized(monitorHolder)(If(needsInit, init, EmptyTree)), EmptyTree) :: Nil, moduleVarRef) + val computeName = nme.newLazyValSlowComputeName(module.name) + val computeMethod = DefDef(NoMods, computeName, Nil, ListOfNil, TypeTree(UnitTpe), gen.mkSynchronized(monitorHolder)(If(needsInit, init, EmptyTree))) + Block(computeMethod :: If(needsInit, Apply(Ident(computeName), Nil), EmptyTree) :: Nil, moduleVarRef) } // NoSymbol for lazy accessor sym with unit result type |