Commit 2100d28f authored by Kunshan Wang's avatar Kunshan Wang

Refactor "integerizer" and "Word"

Moved CanBeIntegerized to its own package.

Removed "Word" from TypeSizes and uniformly import from uvm.refimpl.
parent bb294cde
package uvm
import uvm.types._
import uvm.ssavariables._
import scala.collection.mutable.HashMap
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.HashMap
import uvm.ssavariables._
import uvm.types._
/**
* The top-level type for all Mu IR AST nodes. Convenient for the IRBuilder API.
......
......@@ -18,7 +18,7 @@ trait Identified {
object Identified {
val INVALID_ID = 0
val FIRST_INTERNAL_ID = 32768
val FIRST_PRIVATE_ID = 32768
val FIRST_CLIENT_USABLE_ID = 65536
type MuID = Int
......
......@@ -2,8 +2,8 @@ package uvm
import scala.collection.mutable.ArrayBuffer
import uvm.types._
import uvm.ssavariables._
import uvm.types._
case class FuncSig(var paramTys: Seq[Type], var retTys: Seq[Type]) extends TopLevel {
override final def toString: String = FuncSig.prettyPrint(this)
......
package uvm.hail
import scala.collection.mutable.ArrayBuffer
import uvm.IdentifiedSettable
import uvm.types.Type
import uvm.ssavariables.GlobalVariable
import uvm.types.Type
import uvm.types.TypeHybrid
trait Locatable {
......
package uvm.ir.irbuilder
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.HashMap
import uvm._
import uvm.comminsts.CommInsts
import uvm.comminsts.CommInst
import uvm.refimpl.MuInternalID
import uvm.refimpl.integerize.HasID
import uvm.ssavariables._
import uvm.types._
import uvm.utils.IDFactory
import uvm.staticanalysis.InstructionResultInferer
import scala.collection.mutable.HashMap
import uvm.comminsts.CommInst
object IRBuilder {
......@@ -53,10 +53,15 @@ object IRBuilder {
}
class IRBuilder(globalBundle: GlobalBundle, idFactory: IDFactory) {
import IRBuilder._
trait IRBuilderListener {
def onBundleLoad(irBuilder: IRBuilder, bundle: TrantientBundle): Unit
def onBundleAbort(irBuilder: IRBuilder): Unit
}
class IRBuilder(val id: MuInternalID,
globalBundle: GlobalBundle, idFactory: IDFactory, irBuilderListener: Option[IRBuilderListener])
extends HasID {
import IRBuilderNode._
import uvm.RichIdentifiedSettable._
private def nextID(): Int = idFactory.getID()
......@@ -66,14 +71,18 @@ class IRBuilder(globalBundle: GlobalBundle, idFactory: IDFactory) {
private def onNewNodeCreated(node: IRBuilderNode): Unit = {
nodeList += node
}
// There are scripts in microvm-refimpl2/migrate_scripts/ to convert this program to the MuCtxIRBuilderPart or the
// common instruction executor. Keep the next line exact
// SCRIPT: BEGIN HERE
def load(): Unit = ???
def abort(): Unit = ???
def makeBundle(): TrantientBundle = ???
def load(): Unit = {
val trantientBundle = makeBundle()
irBuilderListener.foreach { l => l.onBundleLoad(this, trantientBundle) }
}
def abort(): Unit = {
irBuilderListener.foreach { l => l.onBundleAbort(this) }
}
def genSym(name: Option[String]): MuID = {
val id = nextID()
name foreach { n =>
......@@ -82,6 +91,8 @@ class IRBuilder(globalBundle: GlobalBundle, idFactory: IDFactory) {
id
}
// The following functions are generated from irBuilderNodes.scala by /migrate_scripts/irbuildernodestoirbuildermethods.py
// GEN:BEGIN:IRBUILDERNODE_CONSTRUCTORS
def newTypeInt(id: MuID, len: Int): Unit = {
val _node = new NodeTypeInt(id, len)
......
package uvm.ir.textinput
import scala.collection.JavaConversions._
import scala.collection.mutable.ArrayBuffer
import org.antlr.v4.runtime._
import org.antlr.v4.runtime.tree.TerminalNode
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm._
import uvm.comminsts.CommInsts
import uvm.ir.textinput.gen.UIRParser._
import uvm.ir.textinput.gen._
import uvm.ir.textinput.gen.UIRParser._
import uvm.ir.textinput.gen.UIRParser.StringLiteralContext
import uvm.ssavariables._
import uvm.types._
import scala.collection.JavaConversions._
import scala.collection.mutable.ArrayBuffer
import scala.collection.immutable.Stream
import java.io.StringWriter
import java.nio.CharBuffer
import uvm.utils.IOHelpers
import uvm.utils.IDFactory
import uvm.utils.AdvancedAntlrHelper
import uvm.utils.AntlrHelpers.AccumulativeAntlrErrorListener
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm.ir.textinput.gen.UIRParser.StringLiteralContext
import uvm.ir.textinput.gen.UIRParser.StringLiteralContext
import uvm.utils.IDFactory
import uvm.utils.IOHelpers
class UIRTextReader(val defaultIDFactory: IDFactory, val recordSourceInfo: Boolean = true) {
import UIRTextReader._
......
package uvm.ir.textoutput
import uvm.GlobalBundle
import scala.collection.Set
import uvm.Identified
import java.io.Writer
import scala.collection.Set
import uvm._
import uvm.types._
import uvm.ssavariables._
import uvm.ssavariables.NewStackAction
import uvm.types._
object EntityUtils {
def getName(obj: Identified): String = {
......@@ -28,8 +27,8 @@ object EntityUtils {
}
abstract class AbstractBundleSerializer(bundle: Bundle) {
import EntityUtils._
import AbstractBundleSerializer._
import EntityUtils._
def writeUIR(sb: StringBuilder): Unit
......@@ -276,7 +275,6 @@ class DebugBundleSerializer(val bundle: TrantientBundle) extends AbstractBundleS
*/
class BundleSerializer(val bundle: GlobalBundle, val whiteList: Set[TopLevel]) extends AbstractBundleSerializer(bundle) {
import EntityUtils._
import AbstractBundleSerializer._
def filter(obj: TopLevel): Boolean = {
!isMetaEntity(obj) && whiteList.contains(obj)
......
......@@ -7,12 +7,14 @@ import scala.collection.mutable.HashSet
import uvm._
import uvm.ir.irbuilder.IRBuilder
import uvm.ir.irbuilder.IRBuilderListener
import uvm.ir.textinput.UIRTextReader
import uvm.ir.textoutput.BundleSerializer
import uvm.ir.textoutput.DebugBundleSerializer
import uvm.refimpl.bootimg.BootImageBuilder
import uvm.refimpl.bootimg.BootImageLoader
import uvm.refimpl.hail.HailScriptLoader
import uvm.refimpl.integerize.IDObjectKeeper
import uvm.refimpl.itpr._
import uvm.refimpl.mem._
import uvm.refimpl.nat.NativeCallHelper
......@@ -38,33 +40,14 @@ object MicroVM {
}
}
class MicroVM(val vmConf: VMConf) {
class MicroVM(val vmConf: VMConf) extends IRBuilderListener {
// implicitly injected resources
private implicit val microVM = this
val globalBundle = new GlobalBundle()
val constantPool = new ConstantPool()
val memoryManager = new MemoryManager(vmConf)
private implicit val memorySupport = memoryManager.memorySupport
val nativeLibraryHolder = NativeLibraryHolder(vmConf.extraLibs: _*)
implicit val nativeCallHelper = new NativeCallHelper()
val threadStackManager = new ThreadStackManager()
val trapManager = new TrapManager()
val contexts = new HashSet[MuCtx]()
val idFactory = IDFactory.newClientIDFactory()
val irBuilderRegistry = new SequentialObjectKeeper[IRBuilder]()
val irReader = new UIRTextReader(idFactory, recordSourceInfo = vmConf.sourceInfo)
val hailScriptLoader = new HailScriptLoader(recordSourceInfo = vmConf.sourceInfo)
val staticAnalyzer = new StaticAnalyzer()
val bootImageBuilder = new BootImageBuilder()
/// Initialise the global bundle and constant pool with (private) pre-loaded stuff
{
// VOID, BYTE, BYTE_ARRAY: The micro VM allocates stacks on the heap in the large object space.
// It is represented as a big chunk of byte array.
......@@ -83,12 +66,48 @@ class MicroVM(val vmConf: VMConf) {
globalBundle.constantNs.add(c)
constantPool.addGlobalVar(c)
}
// Some types required by the RunMu class
for (ty <- Seq(C_INT, C_CHAR, C_CHARP, C_CHARPP)) {
globalBundle.typeNs.add(ty)
}
}
val memoryManager = new MemoryManager(vmConf)
private implicit val memorySupport = memoryManager.memorySupport
val nativeLibraryHolder = NativeLibraryHolder(vmConf.extraLibs: _*)
implicit val nativeCallHelper = new NativeCallHelper()
val threadStackManager = new ThreadStackManager()
val trapManager = new TrapManager()
val contexts = new HashSet[MuCtx]()
val idFactory = IDFactory.newClientIDFactory()
val irBuilderRegistry = new IDObjectKeeper[IRBuilder]("IR builder")
val irReader = new UIRTextReader(idFactory, recordSourceInfo = vmConf.sourceInfo)
val hailScriptLoader = new HailScriptLoader(recordSourceInfo = vmConf.sourceInfo)
val staticAnalyzer = new StaticAnalyzer()
val bootImageBuilder = new BootImageBuilder()
/// Bundle building stuff
def newIRBuilder(): IRBuilder = {
val irBuilder = new IRBuilder(irBuilderRegistry.getID(), globalBundle, idFactory, Some(this))
irBuilderRegistry.put(irBuilder)
irBuilder
}
override def onBundleLoad(irBuilder: IRBuilder, bundle: TrantientBundle): Unit = {
}
override def onBundleAbort(irBuilder: IRBuilder): Unit = {
}
......
......@@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm._
import uvm.ir.irbuilder.IRBuilder
import uvm.refimpl.itpr._
import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes._
......@@ -19,7 +20,6 @@ import uvm.ssavariables.AtomicRMWOptr._
import uvm.ssavariables.HasKeepaliveClause
import uvm.ssavariables.MemoryOrder._
import uvm.types._
import uvm.ir.irbuilder.IRBuilder
object MuCtx {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
......@@ -34,7 +34,6 @@ object MuCtx {
class MuCtx(val ctxID: MuInternalID, _mutator: Mutator)(
implicit protected val microVM: MicroVM, memorySupport: MemorySupport)
extends ObjectPinner with AutoCloseable {
import MuCtx._
implicit def mutator = _mutator
......@@ -699,7 +698,7 @@ class MuCtx(val ctxID: MuInternalID, _mutator: Mutator)(
}
def newIRBuilder(): IRBuilder = {
new IRBuilder(microVM.globalBundle, microVM.idFactory)
microVM.newIRBuilder()
}
// Internal methods for the micro VM
......
......@@ -3,7 +3,7 @@ package uvm.refimpl
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Buffer
import uvm.{ MuID, MuName }
import uvm.MuID
import uvm.ssavariables.MemoryOrder._
object RichMuCtx {
......
......@@ -5,9 +5,10 @@
*/
package uvm.refimpl
import uvm.refimpl.mem.TypeSizes._
import scala.collection.mutable.ArrayBuffer
import uvm.refimpl.mem.TypeSizes._
class VMOption[+T](
val name: String,
val desc: String,
......@@ -168,10 +169,9 @@ object VMConf {
}
def setLog(name: String, levelStr: String): Unit = {
import org.slf4j.LoggerFactory
import org.slf4j.{ Logger => SLogger }
import ch.qos.logback.classic.{ Logger => LLogger, Level }
import ch.qos.logback.classic.{ Level, Logger => LLogger }
import ch.qos.logback.classic.Level._
import org.slf4j.LoggerFactory
val level = Level.toLevel(levelStr)
......
......@@ -28,7 +28,6 @@ import uvm.refimpl.mem.TypeSizes
import uvm.refimpl.mem.scanning.MemoryDataScanner
import uvm.refimpl.mem.scanning.MemoryFieldHandler
import uvm.refimpl.nat.NativeSupport
import uvm.refimpl.nat.PlatformConstants.Word
import uvm.types._
import uvm.utils.IOHelpers
import uvm.utils.WithUtils.tryWithResource
......
......@@ -15,11 +15,11 @@ import scala.collection.Map
import scala.collection.mutable.HashMap
import uvm.{ MuID, MuName }
import uvm.refimpl.{ Word, WORD_SIZE_BYTES }
import uvm.refimpl.MicroVM
import uvm.refimpl.itpr.OpHelper
import uvm.refimpl.mem.TypeSizes
import uvm.refimpl.nat.NativeSupport
import uvm.refimpl.nat.PlatformConstants.{ Word, WORD_SIZE_BYTES }
import uvm.types.TypeHybrid
import uvm.utils.IOHelpers.forEachLine
import uvm.utils.MappedIDFactory
......
......@@ -14,7 +14,6 @@ import uvm.refimpl.itpr._
import uvm.refimpl.mem.HeaderUtils
import uvm.refimpl.mem.Space
import uvm.refimpl.mem.TypeSizes
import uvm.refimpl.mem.TypeSizes.Word
import uvm.refimpl.mem.scanning.MemoryDataScanner
import uvm.refimpl.mem.scanning.MemoryFieldHandler
import uvm.ssavariables._
......
......@@ -13,8 +13,8 @@ import uvm.refimpl.InternalTypes
import uvm.refimpl.MicroVM
import uvm.refimpl.UvmRuntimeException
import uvm.refimpl.VMConf
import uvm.refimpl.WORD_SIZE_BYTES
import uvm.refimpl.nat.NativeSupport
import uvm.refimpl.nat.PlatformConstants
import uvm.utils.WithUtils.tryWithResource
/** Run Mu from the command line. */
......@@ -96,10 +96,10 @@ object RunMu {
argvSB ++= arg += '\0'
}
val cArgv = NativeSupport.jnrMemoryManager.allocateDirect(argvOffs.length * PlatformConstants.WORD_SIZE_BYTES.toInt)
val cArgv = NativeSupport.jnrMemoryManager.allocateDirect(argvOffs.length * WORD_SIZE_BYTES.toInt)
val cArgvBuf = NativeSupport.jnrMemoryManager.allocateDirect(argvSB.length)
for (i <- 0 until argvOffs.length) {
cArgv.putAddress(i * PlatformConstants.WORD_SIZE_BYTES, cArgvBuf.address() + argvOffs(i))
cArgv.putAddress(i * WORD_SIZE_BYTES, cArgvBuf.address() + argvOffs(i))
}
for (i <- 0 until argvSB.length) {
cArgvBuf.putByte(i, argvSB.charAt(i).toByte) // Assume single-byte encoding
......
package uvm.refimpl.integerize
import scala.annotation.implicitNotFound
import uvm.refimpl._
@implicitNotFound("Mu entity type ${T} cannot be represented as an integer thus cannot be loaded/stored from the memory.")
trait CanBeIntegerized[T] {
protected def _integerize(obj: T)(implicit microVM: MicroVM): Word
protected def _deIntegerize(num: Word)(implicit microVM: MicroVM): T
def integerize(obj: Option[T])(implicit microVM: MicroVM): Word =
obj.map(_integerize).getOrElse(0L)
def deIntegerize(num: Word)(implicit microVM: MicroVM): Option[T] = {
if (num == 0L) {
None
} else {
Some(_deIntegerize(num))
}
}
}
\ No newline at end of file
package uvm.refimpl.integerize
import scala.collection.mutable.HashMap
import uvm.refimpl.MuInternalID
import uvm.refimpl.UvmRuntimeException
import uvm.refimpl.UvmUnknownIDException
import uvm.utils.IDFactory
/**
* An object with this trait can be uniquely identified within a MicroVM using an Int ID.
* <p>
* This is different from Identified because the ID in this context is used as opaque references to these objects. Currently, these
* objects are threads, stacks and frame cursors. These are referred by opaque references which, in the memory are represented as numerical
* IDs.
*/
trait HasID {
def id: MuInternalID
}
/**
* Keep HasID objects and allow looking them up by their IDs.
*
* @param kind A name that indicates what kind of object it holds. For debugging.
*/
class IDObjectKeeper[T <: HasID](val kind: String) {
val registry = new HashMap[Int, T]()
val idFactory = IDFactory.newOneBasedIDFactory()
/** Get an object by its ID. */
def apply(id: MuInternalID) = try {
registry.apply(id)
} catch {
case e: NoSuchElementException => throw new UvmUnknownIDException(
"Attempted to lookup %s object by ID %d, but it is not found".format(kind, id))
}
/** Get an object by its ID, handle non-existing cases. */
def get(id: MuInternalID) = registry.get(id)
/** Add an object to the registry. */
def put(obj: T): Unit = {
if (registry.put(obj.id, obj).isDefined) {
throw new UvmRuntimeException("%s of ID %s already exists.".format(kind, obj.id))
}
}
/** Iterate through all objects. */
def values: Iterable[T] = registry.values
/** Remove an object from the registry. */
def remove(obj: T): Unit = {
val old = registry.remove(obj.id)
if (old.isDefined && !(old.get eq obj)) {
throw new UvmRuntimeException("The %s removed is not the same object as the argument. ID: %d".format(kind, obj.id))
}
}
/** Create an ID for a new object of this type. */
def getID() = idFactory.getID()
}
package uvm.refimpl
import uvm.Function
import uvm.refimpl.itpr.InterpreterThread
import uvm.refimpl.itpr.FrameCursor
import uvm.refimpl.itpr.InterpreterStack
import uvm.ir.irbuilder.IRBuilder
package object integerize {
implicit object FunctionIntegerizer extends CanBeIntegerized[Function] {
def _integerize(obj: Function)(implicit microVM: MicroVM): Word = obj.id.toLong
def _deIntegerize(num: Word)(implicit microVM: MicroVM): Function = microVM.globalBundle.funcNs(num.toInt)
}
implicit object ThreadIntegerizer extends CanBeIntegerized[InterpreterThread] {
def _integerize(obj: InterpreterThread)(implicit microVM: MicroVM): Word = obj.id.toLong
def _deIntegerize(num: Word)(implicit microVM: MicroVM): InterpreterThread = microVM.threadStackManager.threadRegistry(num.toInt)
}
implicit object StackIntegerizer extends CanBeIntegerized[InterpreterStack] {
def _integerize(obj: InterpreterStack)(implicit microVM: MicroVM): Word = obj.id.toLong
def _deIntegerize(num: Word)(implicit microVM: MicroVM): InterpreterStack = microVM.threadStackManager.stackRegistry(num.toInt)
}
implicit object FrameCursorIntegerizer extends CanBeIntegerized[FrameCursor] {
def _integerize(obj: FrameCursor)(implicit microVM: MicroVM): Word = obj.id.toLong
def _deIntegerize(num: Word)(implicit microVM: MicroVM): FrameCursor = microVM.threadStackManager.frameCursorRegistry(num.toInt)
}
implicit object IRBuilderIntegerizer extends CanBeIntegerized[IRBuilder] {
def _integerize(obj: IRBuilder)(implicit microVM: MicroVM): Word = obj.id.toLong
def _deIntegerize(num: Word)(implicit microVM: MicroVM): IRBuilder = microVM.irBuilderRegistry(num.toInt)
}
}
\ No newline at end of file
......@@ -10,10 +10,10 @@ import uvm.utils.LazyPool
object InternalTypes {
import uvm.RichIdentifiedSettable._
val internalIDFactory = IDFactory.newInternalIDFactory() // IDs from 32768-65535 are for implementation internal use.
val privateIDFactory = IDFactory.newPrivateIDFactory() // IDs from 32768-65535 are for implementation internal use.
def internal(name: MuName): (MuID, MuName) = {
val id = internalIDFactory.getID()
val id = privateIDFactory.getID()
val n = "@uvm.internal.types." + name
(id, n)
}
......
package uvm.refimpl.itpr
import scala.annotation.tailrec
import scala.collection.mutable.ArrayBuffer
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm._
import uvm.comminsts._
import uvm.refimpl._
import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes.Word
import uvm.ssavariables._
import uvm.types._
import uvm.refimpl.nat.NativeCallResult
/**
* A part of the InterpreterThread that interprets common instructions
*/
......
package uvm.refimpl.itpr
import scala.collection.mutable.HashMap
import uvm._
import uvm.types._
import uvm.ssavariables._
import uvm.refimpl.MicroVM
import scala.collection.mutable.HashMap
import uvm.ssavariables._
import uvm.types._
class ConstantPool(implicit microVM: MicroVM) {
val globalVarBoxes = HashMap[GlobalVariable, ValueBox]()
......
package uvm.refimpl.itpr
import uvm.refimpl.mem.TypeSizes.Word
import scala.collection.mutable.{ HashSet, HashMap, MultiMap, ListBuffer, Set, TreeSet }
import scala.collection.mutable.{ HashMap, MultiMap, ListBuffer, Set, TreeSet }
import scala.math.Ordering
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm.refimpl._
object FutexManager {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
}
......
package uvm.refimpl.itpr
import scala.annotation.tailrec
import scala.collection.mutable.ArrayBuffer
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm._
import uvm.comminsts._
import uvm.ir.irbuilder._
import uvm.refimpl._
import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes.Word
import uvm.refimpl.nat.CDefs
import uvm.ssavariables._
import uvm.types._
import uvm.refimpl.nat.NativeCallResult
import uvm.refimpl.nat.CDefs
object IRBuilderCommInstExecutor {
implicit def toBinOptr(i: Int): BinOptr.Value = CDefs.toBinOptr(i)
......@@ -38,8 +33,6 @@ object IRBuilderCommInstExecutor {
*/
trait IRBuilderCommInstExecutor extends InterpreterActions with ObjectPinner {
import IRBuilderCommInstExecutor._
import InterpreterThread.logger
implicit protected def mutator: Mutator
implicit protected def memorySupport: MemorySupport
......
package uvm.refimpl.itpr
import scala.annotation.tailrec
import scala.collection.mutable.ArrayBuffer
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm._
import uvm.comminsts._
import uvm.refimpl._
import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes.Word
import uvm.ssavariables._
import uvm.types._
import uvm.refimpl.nat.NativeCallResult
/**
* Part of the InterpreterThread. It isolates the GIANT case-matching function.
......@@ -73,7 +67,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
val (op2b, op2o) = b2.asIRef
PrimOpHelpers.irefCmp(op, op1b, op1o, op2b, op2o, ctx)
}
case t:AbstractPointerType => PrimOpHelpers.intCmp(op, TypeSizes.WORD_SIZE_BITS.toInt, b1.asPtr, b2.asPtr, ctx)
case t:AbstractPointerType => PrimOpHelpers.intCmp(op, WORD_SIZE_BITS.toInt, b1.asPtr, b2.asPtr, ctx)
case _ => throw new UvmRuntimeException(ctx + "Comparison not suitable for type %s".format(opndTy))
}
}
......
......@@ -12,8 +12,8 @@ import uvm.comminsts._
import uvm.ir.irbuilder.IRBuilder
import uvm.refimpl._
import uvm.refimpl.{ HowToResume => ClientHowToResume }
import uvm.refimpl.integerize.HasID
import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes.Word
import uvm.ssavariables._
import uvm.types._
......
package uvm.refimpl.itpr
import scala.collection.mutable.ArrayBuffer