Skip to content

Commit 67a0e2c

Browse files
committed
Fix static lazy field holder for GraalVM
1 parent 0b08074 commit 67a0e2c

File tree

6 files changed

+77
-13
lines changed

6 files changed

+77
-13
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package dotty.tools.benchmarks.lazyvals
2+
3+
import org.openjdk.jmh.annotations.*
4+
import org.openjdk.jmh.infra.Blackhole
5+
import LazyVals.LazyIntHolder
6+
import java.util.concurrent.TimeUnit
7+
8+
@BenchmarkMode(Array(Mode.AverageTime))
9+
@Fork(2)
10+
@Threads(1)
11+
@Warmup(iterations = 5)
12+
@Measurement(iterations = 5)
13+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
14+
@State(Scope.Benchmark)
15+
class InitializedAccessInt {
16+
17+
var holder: LazyIntHolder = _
18+
19+
@Setup
20+
def prepare: Unit = {
21+
holder = new LazyIntHolder
22+
holder.value
23+
}
24+
25+
@Benchmark
26+
def measureInitialized(bh: Blackhole) = {
27+
bh.consume(holder)
28+
bh.consume(holder.value)
29+
}
30+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package dotty.tools.benchmarks.lazyvals
2+
3+
import org.openjdk.jmh.annotations.*
4+
import org.openjdk.jmh.infra.Blackhole
5+
import LazyVals.ObjectHolder
6+
import java.util.concurrent.TimeUnit
7+
8+
@BenchmarkMode(Array(Mode.AverageTime))
9+
@Fork(2)
10+
@Threads(1)
11+
@Warmup(iterations = 5)
12+
@Measurement(iterations = 5)
13+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
14+
@State(Scope.Benchmark)
15+
class InitializedObject {
16+
17+
@Benchmark
18+
def measureInitialized(bh: Blackhole) = {
19+
bh.consume(ObjectHolder)
20+
bh.consume(ObjectHolder.value)
21+
}
22+
}

bench-micro/src/main/scala/dotty/tools/benchmarks/lazyvals/LazyVals.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,22 @@ object LazyVals {
5050
}
5151
}
5252
}
53+
54+
class LazyIntHolder {
55+
lazy val value: Int = {
56+
(System.nanoTime() % 1000).toInt
57+
}
58+
}
59+
60+
object ObjectHolder {
61+
lazy val value: String = {
62+
System.nanoTime() % 5 match {
63+
case 0 => "abc"
64+
case 1 => "def"
65+
case 2 => "ghi"
66+
case 3 => "jkl"
67+
case 4 => "mno"
68+
}
69+
}
70+
}
5371
}

compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ trait BCodeSkelBuilder extends BCodeHelpers {
151151

152152
// !!! Part of this logic is duplicated in JSCodeGen.genCompilationUnit
153153
claszSymbol.info.decls.foreach { f =>
154-
if f.isField && !f.name.is(LazyBitMapName) then
154+
if f.isField && !f.name.is(LazyBitMapName) && !f.name.is(LazyLocalName) then
155155
f.setFlag(JavaStatic)
156156
}
157157

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import dotty.tools.dotc.report
2222
import tpd._
2323

2424
import StdNames.nme
25-
import NameKinds.LazyBitMapName
25+
import NameKinds.{LazyBitMapName, LazyLocalName}
2626
import Names.Name
2727

2828
class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap: ReadOnlyMap[Symbol, Set[ClassSymbol]])(using val ctx: Context) {
@@ -129,10 +129,11 @@ object DottyBackendInterface {
129129
* the new lazy val encoding: https://github.com/lampepfl/dotty/issues/7140
130130
*/
131131
def isStaticModuleField(using Context): Boolean =
132-
sym.owner.isStaticModuleClass && sym.isField && !sym.name.is(LazyBitMapName)
132+
sym.owner.isStaticModuleClass && sym.isField && !sym.name.is(LazyBitMapName) && !sym.name.is(LazyLocalName)
133133

134134
def isStaticMember(using Context): Boolean = (sym ne NoSymbol) &&
135-
(sym.is(JavaStatic) || sym.isScalaStatic || sym.isStaticModuleField)
135+
(sym.is(JavaStatic) || sym.isScalaStatic || sym.isStaticModuleField)
136+
136137
// guard against no sumbol cause this code is executed to select which call type(static\dynamic) to use to call array.clone
137138

138139
/**

compiler/src/dotty/tools/dotc/transform/LazyVals.scala

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -466,13 +466,9 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
466466
val containerSymbol = newSymbol(claz, containerName, x.symbol.flags &~ containerFlagsMask | containerFlags | Private, defn.ObjectType, coord = x.symbol.coord).enteredAfter(this)
467467
containerSymbol.addAnnotation(Annotation(defn.VolatileAnnot, containerSymbol.span)) // private @volatile var _x: AnyRef
468468
containerSymbol.addAnnotations(x.symbol.annotations) // pass annotations from original definition
469-
val stat = x.symbol.isStatic
470-
if stat then
471-
containerSymbol.setFlag(JavaStatic)
469+
containerSymbol.removeAnnotation(defn.ScalaStaticAnnot)
470+
containerSymbol.resetFlag(JavaStatic)
472471
val getOffset =
473-
if stat then
474-
Select(ref(defn.LazyValsModule), lazyNme.RLazyVals.getStaticFieldOffset)
475-
else
476472
Select(ref(defn.LazyValsModule), lazyNme.RLazyVals.getOffsetStatic)
477473
val containerTree = ValDef(containerSymbol, nullLiteral)
478474

@@ -490,9 +486,6 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
490486
val offset = ref(offsetSymbol.nn)
491487

492488
val swapOver =
493-
if stat then
494-
tpd.clsOf(x.symbol.owner.typeRef)
495-
else
496489
This(claz)
497490

498491
val (accessorDef, initMethodDef) = mkThreadSafeDef(x, claz, containerSymbol, offset, swapOver)

0 commit comments

Comments
 (0)