alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (SynchronizedTypes.scala)

This example Scala source code file (SynchronizedTypes.scala) is included in my "Source Code Warehouse" project. The intent of this project is to help you more easily find Scala source code examples by using tags.

All credit for the original source code belongs to scala-lang.org; I'm just trying to make examples easier to find. (For my Scala work, see my Scala examples and tutorials.)

Scala tags/keywords

collection, compoundtype, int, list, object, reflection, singletype, string, t, type, typeref, undolog

The SynchronizedTypes.scala Scala example source code

package scala
package reflect
package runtime

import scala.collection.mutable
import java.lang.ref.{WeakReference => jWeakRef}
import scala.ref.{WeakReference => sWeakRef}
import scala.reflect.internal.Depth

/** This trait overrides methods in reflect.internal, bracketing
 *  them in synchronized { ... } to make them thread-safe
 */
private[reflect] trait SynchronizedTypes extends internal.Types { self: SymbolTable =>

  // No sharing of map objects:
  override protected def commonOwnerMap = new CommonOwnerMap

  // we can keep this lock fine-grained, because super.unique just updates the cache
  // and, in particular, doesn't call any reflection APIs which makes deadlocks impossible
  private lazy val uniqueLock = new Object
  private val uniques = mutable.WeakHashMap[Type, jWeakRef[Type]]()
  override def unique[T <: Type](tp: T): T = uniqueLock.synchronized {
    // we need to have weak uniques for runtime reflection
    // because unlike the normal compiler universe, reflective universe isn't organized in runs
    // therefore perRunCaches can grow infinitely large
    //
    // despite that toolbox universes are decorated, toolboxes are compilers,
    // i.e. they have their caches cleaned up automatically on per-run basis,
    // therefore they should use vanilla uniques, which are faster
    if (!isCompilerUniverse) {
      val inCache = uniques get tp
      val result = if (inCache.isDefined) inCache.get.get else null
      if (result ne null) result.asInstanceOf[T]
      else {
        uniques(tp) = new jWeakRef(tp)
        tp
      }
    } else {
      super.unique(tp)
    }
  }

  private lazy val _skolemizationLevel = mkThreadLocalStorage(0)
  override def skolemizationLevel = _skolemizationLevel.get
  override def skolemizationLevel_=(value: Int) = _skolemizationLevel.set(value)

  private lazy val _undoLog = mkThreadLocalStorage(new UndoLog)
  override def undoLog = _undoLog.get

  private lazy val _intersectionWitness = mkThreadLocalStorage(perRunCaches.newWeakMap[List[Type], sWeakRef[Type]]())
  override def intersectionWitness = _intersectionWitness.get

  private lazy val _subsametypeRecursions = mkThreadLocalStorage(0)
  override def subsametypeRecursions = _subsametypeRecursions.get
  override def subsametypeRecursions_=(value: Int) = _subsametypeRecursions.set(value)

  private lazy val _pendingSubTypes = mkThreadLocalStorage(new mutable.HashSet[SubTypePair])
  override def pendingSubTypes = _pendingSubTypes.get

  private lazy val _basetypeRecursions = mkThreadLocalStorage(0)
  override def basetypeRecursions = _basetypeRecursions.get
  override def basetypeRecursions_=(value: Int) = _basetypeRecursions.set(value)

  private lazy val _pendingBaseTypes = mkThreadLocalStorage(new mutable.HashSet[Type])
  override def pendingBaseTypes = _pendingBaseTypes.get

  private lazy val _lubResults = mkThreadLocalStorage(new mutable.HashMap[(Depth, List[Type]), Type])
  override def lubResults = _lubResults.get

  private lazy val _glbResults = mkThreadLocalStorage(new mutable.HashMap[(Depth, List[Type]), Type])
  override def glbResults = _glbResults.get

  private lazy val _indent = mkThreadLocalStorage("")
  override def indent = _indent.get
  override def indent_=(value: String) = _indent.set(value)

  private lazy val _toStringRecursions = mkThreadLocalStorage(0)
  override def toStringRecursions = _toStringRecursions.get
  override def toStringRecursions_=(value: Int) = _toStringRecursions.set(value)

  private lazy val _toStringSubjects = mkThreadLocalStorage(new mutable.HashSet[Type])
  override def toStringSubjects = _toStringSubjects.get

  /* The idea of caches is as follows.
   * When in reflexive mode, a cache is either null, or one sentinal
   * value representing undefined or the final defined
   * value. Hence, we can ask in non-synchronized ode whether the cache field
   * is non null and different from the sentinel (if a sentinel exists).
   * If that's true, the cache value is current.
   * Otherwise we arrive in one of the defined... methods listed below
   * which go through all steps in synchronized mode.
   */

  override protected def defineUnderlyingOfSingleType(tpe: SingleType) =
    gilSynchronized { super.defineUnderlyingOfSingleType(tpe) }

  override protected def defineBaseTypeSeqOfCompoundType(tpe: CompoundType) =
    gilSynchronized { super.defineBaseTypeSeqOfCompoundType(tpe) }

  override protected def defineBaseClassesOfCompoundType(tpe: CompoundType) =
    gilSynchronized { super.defineBaseClassesOfCompoundType(tpe) }

  override protected def defineParentsOfTypeRef(tpe: TypeRef) =
    gilSynchronized { super.defineParentsOfTypeRef(tpe) }

  override protected def defineBaseTypeSeqOfTypeRef(tpe: TypeRef) =
    gilSynchronized { super.defineBaseTypeSeqOfTypeRef(tpe) }

}

Other Scala source code examples

Here is a short list of links related to this Scala SynchronizedTypes.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.