@@ -206,22 +206,25 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
206206 /** Create non-threadsafe lazy accessor equivalent to such code
207207 * ```
208208 * def methodSymbol() = {
209- * if (flag) target
210- * else {
209+ * if (!flag) {
211210 * target = rhs
212211 * flag = true
213212 * nullable = null
214- * target
215- * }
216213 * }
214+ * target
217215 * }
218216 * ```
219217 */
220- def mkNonThreadSafeDef (target : Tree , flag : Tree , rhs : Tree , nullables : List [Symbol ])(implicit ctx : Context ): If = {
221- val stats = new mutable.ListBuffer [Tree ]
222- if (! isWildcardArg(rhs)) stats += target.becomes(rhs)
223- stats += flag.becomes(Literal (Constant (true ))) ++= nullOut(nullables)
224- If (flag.ensureApplied, target.ensureApplied, Block (stats.toList, target.ensureApplied))
218+ def mkNonThreadSafeDef (sym : Symbol , flag : Symbol , target : Symbol , rhs : Tree )(implicit ctx : Context ): DefDef = {
219+ val targetRef = ref(target)
220+ val flagRef = ref(flag)
221+ val stats = targetRef.becomes(rhs) :: flagRef.becomes(Literal (Constant (true ))) :: nullOut(nullableFor(sym))
222+ val init = If (
223+ flagRef.ensureApplied.select(nme.UNARY_! ).ensureApplied,
224+ Block (stats.init, stats.last),
225+ unitLiteral
226+ )
227+ DefDef (sym.asTerm, Block (List (init), targetRef.ensureApplied))
225228 }
226229
227230 /** Create non-threadsafe lazy accessor for not-nullable types equivalent to such code
@@ -230,18 +233,20 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
230233 * if (target eq null) {
231234 * target = rhs
232235 * nullable = null
233- * target
234- * } else target
236+ * }
237+ * target
235238 * }
236239 * ```
237240 */
238- def mkDefNonThreadSafeNonNullable (target : Symbol , rhs : Tree , nullables : List [Symbol ])(implicit ctx : Context ): If = {
239- val cond = ref(target).select(nme.eq).appliedTo(Literal (Constant (null )))
240- val exp = ref(target)
241- val setTarget = exp.becomes(rhs)
242- val setNullables = nullOut(nullables)
243- val init = Block (setTarget :: setNullables, exp)
244- If (cond, init, exp)
241+ def mkDefNonThreadSafeNonNullable (sym : Symbol , target : Symbol , rhs : Tree )(implicit ctx : Context ): DefDef = {
242+ val targetRef = ref(target)
243+ val stats = targetRef.becomes(rhs) :: nullOut(nullableFor(sym))
244+ val init = If (
245+ targetRef.select(nme.eq).appliedTo(Literal (Constant (null ))),
246+ Block (stats.init, stats.last),
247+ unitLiteral
248+ )
249+ DefDef (sym.asTerm, Block (List (init), targetRef.ensureApplied))
245250 }
246251
247252 def transformMemberDefNonVolatile (x : ValOrDefDef )(implicit ctx : Context ): Thicket = {
@@ -255,16 +260,15 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
255260 ).enteredAfter(this )
256261
257262 val containerTree = ValDef (containerSymbol, defaultValue(tpe))
258- if (x.tpe.isNotNull && tpe <:< defn.ObjectType ) { // can use 'null' value instead of flag
259- val slowPath = DefDef (x.symbol.asTerm, mkDefNonThreadSafeNonNullable(containerSymbol, x.rhs, nullableFor(x.symbol)))
260- Thicket (containerTree, slowPath )
263+ if (x.tpe.isNotNull && tpe <:< defn.ObjectType ) {
264+ // can use 'null' value instead of flag
265+ Thicket (containerTree, mkDefNonThreadSafeNonNullable(x.symbol, containerSymbol, x.rhs) )
261266 }
262267 else {
263268 val flagName = LazyBitMapName .fresh(x.name.asTermName)
264269 val flagSymbol = ctx.newSymbol(x.symbol.owner, flagName, containerFlags | Flags .Private , defn.BooleanType ).enteredAfter(this )
265270 val flag = ValDef (flagSymbol, Literal (Constant (false )))
266- val slowPath = DefDef (x.symbol.asTerm, mkNonThreadSafeDef(ref(containerSymbol), ref(flagSymbol), x.rhs, nullableFor(x.symbol)))
267- Thicket (containerTree, flag, slowPath)
271+ Thicket (containerTree, flag, mkNonThreadSafeDef(x.symbol, flagSymbol, containerSymbol, x.rhs))
268272 }
269273 }
270274
0 commit comments