Skip to content

Commit 31be2b0

Browse files
authored
Merge pull request #14780 from romanowski/lazyvals-in-graal
Make lazy vals and object native image friendly
2 parents 173c3ff + 3cd853a commit 31be2b0

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
382382
val thizClass = Literal(Constant(claz.info))
383383
val helperModule = requiredModule("scala.runtime.LazyVals")
384384
val getOffset = Select(ref(helperModule), lazyNme.RLazyVals.getOffset)
385+
val getOffsetStatic = Select(ref(helperModule), lazyNme.RLazyVals.getOffsetStatic)
385386
var offsetSymbol: TermSymbol | Null = null
386387
var flag: Tree = EmptyTree
387388
var ord = 0
@@ -406,7 +407,8 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
406407
val flagName = LazyBitMapName.fresh(id.toString.toTermName)
407408
val flagSymbol = newSymbol(claz, flagName, containerFlags, defn.LongType).enteredAfter(this)
408409
flag = ValDef(flagSymbol, Literal(Constant(0L)))
409-
val offsetTree = ValDef(offsetSymbol.nn, getOffset.appliedTo(thizClass, Literal(Constant(flagName.toString))))
410+
val fieldTree = thizClass.select(lazyNme.RLazyVals.getDeclaredField).appliedTo(Literal(Constant(flagName.toString)))
411+
val offsetTree = ValDef(offsetSymbol.nn, getOffsetStatic.appliedTo(fieldTree))
410412
info.defs = offsetTree :: info.defs
411413
}
412414

@@ -416,7 +418,8 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
416418
val flagName = LazyBitMapName.fresh("0".toTermName)
417419
val flagSymbol = newSymbol(claz, flagName, containerFlags, defn.LongType).enteredAfter(this)
418420
flag = ValDef(flagSymbol, Literal(Constant(0L)))
419-
val offsetTree = ValDef(offsetSymbol.nn, getOffset.appliedTo(thizClass, Literal(Constant(flagName.toString))))
421+
val fieldTree = thizClass.select(lazyNme.RLazyVals.getDeclaredField).appliedTo(Literal(Constant(flagName.toString)))
422+
val offsetTree = ValDef(offsetSymbol.nn, getOffsetStatic.appliedTo(fieldTree))
420423
appendOffsetDefs += (claz -> new OffsetInfo(List(offsetTree), ord))
421424
}
422425

@@ -453,6 +456,8 @@ object LazyVals {
453456
val state: TermName = N.state.toTermName
454457
val cas: TermName = N.cas.toTermName
455458
val getOffset: TermName = N.getOffset.toTermName
459+
val getOffsetStatic: TermName = "getOffsetStatic".toTermName
460+
val getDeclaredField: TermName = "getDeclaredField".toTermName
456461
}
457462
val flag: TermName = "flag".toTermName
458463
val state: TermName = "state".toTermName

library/src/scala/runtime/LazyVals.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package scala.runtime
22

3+
import scala.annotation.since
4+
35
/**
46
* Helper methods used in thread-safe lazy vals.
57
*/
@@ -106,6 +108,14 @@ object LazyVals {
106108
r
107109
}
108110

111+
@since("3.2")
112+
def getOffsetStatic(field: java.lang.reflect.Field) =
113+
val r = unsafe.objectFieldOffset(field)
114+
if (debug)
115+
println(s"getOffset(${field.getDeclaringClass}, ${field.getName}) = $r")
116+
r
117+
118+
109119
object Names {
110120
final val state = "STATE"
111121
final val cas = "CAS"

0 commit comments

Comments
 (0)