Commit 1aaa1356 authored by Kunshan Wang's avatar Kunshan Wang

new IDFactory

parent 656d9a8a
......@@ -15,6 +15,12 @@ trait Identified {
override def toString = "%s%s".format(this.getClass.getSimpleName, this.repr)
}
object Identified {
val INVALID_ID = 0
val FIRST_INTERNAL_ID = 32768
val FIRST_CLIENT_USABLE_ID = 65536
}
trait IdentifiedSettable extends Identified {
var id: Int = 0
var name: Option[String] = None
......
......@@ -9,6 +9,7 @@ import uvm.ir.irbuilder.IRBuilder
import uvm.ir.irbuilder.IRNode
import uvm.ir.textinput.UIRTextReader
import uvm.ir.textoutput.BundleSerializer
import uvm.refimpl.bootimg.BootImageBuilder
import uvm.refimpl.hail.HailScriptLoader
import uvm.refimpl.itpr._
import uvm.refimpl.mem._
......@@ -17,7 +18,7 @@ import uvm.refimpl.nat.NativeCallHelper
import uvm.refimpl.nat.NativeLibraryHolder
import uvm.staticanalysis.StaticAnalyzer
import uvm.utils.IDFactory
import uvm.refimpl.bootimg.BootImageBuilder
import uvm.utils.SequentialIDFactory
object MicroVM {
val DEFAULT_SOS_SIZE: Word = 2L * 1024L * 1024L; // 2MiB
......@@ -25,13 +26,11 @@ object MicroVM {
val DEFAULT_GLOBAL_SIZE: Word = 1L * 1024L * 1024L; // 1MiB
val DEFAULT_STACK_SIZE: Word = 63L * 1024L; // 60KiB per stack
val FIRST_CLIENT_USABLE_ID: Int = 65536
def apply(): MicroVM = {
val vmConf = new VMConf()
new MicroVM(vmConf)
}
def apply(confStr: String): MicroVM = {
val vmConf = VMConf(confStr)
new MicroVM(vmConf)
......@@ -49,7 +48,7 @@ class MicroVM(vmConf: VMConf) {
private implicit val memorySupport = memoryManager.memorySupport
val nativeLibraryHolder = NativeLibraryHolder(vmConf.extraLibs: _*)
implicit val nativeCallHelper = new NativeCallHelper()
val threadStackManager = new ThreadStackManager()
......@@ -57,13 +56,13 @@ class MicroVM(vmConf: VMConf) {
val trapManager = new TrapManager()
val contexts = new HashSet[MuCtx]()
val idFactory = new IDFactory(MicroVM.FIRST_CLIENT_USABLE_ID)
val idFactory = IDFactory.newClientIDFactory()
val irBuilder = new IRBuilder(globalBundle, idFactory)
val irNodeRegistry = new SequentialObjectKeeper[IRNode]()
val irReader = new UIRTextReader(idFactory, recordSourceInfo=vmConf.sourceInfo)
val hailScriptLoader = new HailScriptLoader(recordSourceInfo=vmConf.sourceInfo)
val irReader = new UIRTextReader(idFactory, recordSourceInfo = vmConf.sourceInfo)
val hailScriptLoader = new HailScriptLoader(recordSourceInfo = vmConf.sourceInfo)
val staticAnalyzer = new StaticAnalyzer()
val bootImageBuilder = new BootImageBuilder()
{
......@@ -107,8 +106,8 @@ class MicroVM(vmConf: VMConf) {
constantPool.addGlobalVar(g)
}
}
private val contextIDFactory = new IDFactory(1)
private val contextIDFactory = IDFactory.newOneBasedIDFactory()
/**
* Create a new MuCtx. Part of the API.
......@@ -141,7 +140,7 @@ class MicroVM(vmConf: VMConf) {
def setTrapHandler(trapHandler: TrapHandler): Unit = {
trapManager.trapHandler = trapHandler
}
/**
* Make boot image.
*/
......@@ -151,16 +150,16 @@ class MicroVM(vmConf: VMConf) {
obj match {
case tl: TopLevel => tl
case _ => throw new UvmRuntimeException(
"White list may only contain top-level definitions. Entity ID %d%s is a %s".format(
obj.id, obj.name.map(n => s" (${n})").getOrElse(""), obj.getClass.getName))
"White list may only contain top-level definitions. Entity ID %d%s is a %s".format(
obj.id, obj.name.map(n => s" (${n})").getOrElse(""), obj.getClass.getName))
}
}
bootImageBuilder.makeBootImage(whiteListObjs, outputFile)
}
/**
*
*
*/
def debugPrintGlobalBundle(w: Writer): Unit = {
val bs = new BundleSerializer(globalBundle, globalBundle.allTopLevels().toSet)
......
......@@ -22,6 +22,7 @@ object VMConf {
var staticCheck = DEFAULT_CONF.staticCheck
var sourceInfo = DEFAULT_CONF.sourceInfo
var extraLibs = DEFAULT_CONF.extraLibs
var bootImg: Option[String] = None
confStr.lines foreach {
case ReComment() =>
case ReBlank() =>
......@@ -36,11 +37,12 @@ object VMConf {
case "vmLog" => setLog("uvm", value)
case "gcLog" => setLog("uvm.refimpl.mem", value)
case "extraLibs" => extraLibs = value.split(":")
case "bootImg" => bootImg = Some(value)
case _ => throw new UvmRefImplException("Unrecognized option %s".format(key))
}
}
}
new VMConf(sosSize, losSize, globalSize, stackSize, staticCheck, sourceInfo)
new VMConf(sosSize, losSize, globalSize, stackSize, staticCheck, sourceInfo, extraLibs, bootImg)
}
def setLog(name: String, levelStr: String): Unit = {
......@@ -62,5 +64,6 @@ class VMConf(
val stackSize: Word = MicroVM.DEFAULT_STACK_SIZE,
val staticCheck: Boolean = true,
val sourceInfo: Boolean = true,
val extraLibs: Seq[String] = Seq())
val extraLibs: Seq[String] = Seq(),
val bootImg: Option[String] = None)
package uvm.refimpl
import uvm._
import uvm.types._
import uvm.FuncSig
import uvm.ssavariables._
import uvm.utils.LazyPool
import uvm.types._
import uvm.utils.IDFactory
import scala.collection.mutable.HashMap
import uvm.FuncSig
import uvm.IdentifiedSettable
object InternalIDFactory extends IDFactory(32768) // IDs from 32768-65535 are for implementation internal use.
import uvm.utils.LazyPool
object InternalTypes {
import uvm.RichIdentifiedSettable._
val internalIDFactory = IDFactory.newInternalIDFactory() // IDs from 32768-65535 are for implementation internal use.
def internal(name: String): (Int, String) = {
val id = InternalIDFactory.getID()
val id = internalIDFactory.getID()
val n = "@uvm.internal.types." + name
(id, n)
}
......@@ -73,8 +71,8 @@ object InternalTypePool {
}
object TypeInferer {
import InternalTypes._
import InternalTypePool._
import InternalTypes._
def ptrOrIRefOf(ptr: Boolean, ty: Type): Type = {
if (ptr) ptrOf(ty) else irefOf(ty)
......
package uvm.refimpl.itpr
import uvm.Function
import uvm.refimpl.MicroVM
import uvm.refimpl.mem._
import scala.collection.mutable.HashMap
import scala.collection.mutable.ArrayBuffer
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm.refimpl.nat.NativeCallHelper
import uvm.utils.IDFactory
import uvm.Function
import uvm.refimpl.MicroVM
import uvm.refimpl.UvmRuntimeException
import uvm.refimpl.UvmUnknownIDException
import uvm.refimpl.mem._
import uvm.refimpl.nat.NativeCallHelper
import uvm.utils.IDFactory
/**
* An object with this trait can be uniquely identified within a MicroVM using an Int ID.
......@@ -30,7 +32,7 @@ trait HasID {
*/
class IDObjectKeeper[T <: HasID](val kind: String) {
val registry = new HashMap[Int, T]()
val idFactory = new IDFactory(1)
val idFactory = IDFactory.newOneBasedIDFactory()
/** Get an object by its ID. */
def apply(id: Int) = try {
......
package uvm.refimpl.mem.simpleimmix
import uvm.refimpl.mem._
import uvm.refimpl.mem.los.LargeObjectSpace
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import TypeSizes.Word
import uvm.refimpl.UvmRefImplException
import uvm.utils.RetryUtils._
import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes.Word
import uvm.utils.IDFactory
import uvm.utils.RetryUtils._
object SimpleImmixDefragMutator {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
val defragMutatorIDFactory = new IDFactory(1)
val defragMutatorIDFactory = IDFactory.newOneBasedIDFactory()
}
class SimpleImmixDefragMutator(val heap: SimpleImmixHeap, val space: SimpleImmixSpace)(
......
package uvm.utils
class IDFactory(initialID: Int) {
import uvm.Identified
object IDFactory {
def newClientIDFactory() = new SequentialIDFactory(Identified.FIRST_CLIENT_USABLE_ID)
def newInternalIDFactory() = new SequentialIDFactory(Identified.FIRST_INTERNAL_ID)
def newOneBasedIDFactory() = new SequentialIDFactory(1)
}
abstract class IDFactory {
def getID(): Int
def getID(name: String): Int
def setNextID(nextID: Int): Unit
}
class SequentialIDFactory(initialID: Int) extends IDFactory {
private var id: Int = initialID
def getID(): Int = {
......@@ -8,4 +22,28 @@ class IDFactory(initialID: Int) {
id = id + 1
return myID
}
def getID(name: String): Int = {
val myID = id
id = id + 1
return myID
}
def setNextID(nextID: Int): Unit = {
id = nextID
}
}
class MappedIDFactory(nameToID: Map[String, Int]) extends IDFactory {
def getID(): Int = {
throw new UnsupportedOperationException("MappedIDFactory can only get ID from name")
}
def getID(name: String): Int = {
return nameToID(name)
}
def setNextID(nextID: Int): Unit = {
throw new UnsupportedOperationException("MappedIDFactory cannot set the next ID")
}
}
\ No newline at end of file
package junks
import uvm.refimpl.MicroVM
import uvm.refimpl.VMConf
import uvm.GlobalBundle
import uvm.TrantientBundle
import uvm.utils.IDFactory
import uvm.ir.textinput.UIRTextReader
import java.io.Reader
import java.io.StringReader
import java.io.StringWriter
import uvm.ir.textoutput.BundleSerializer
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm.GlobalBundle
import uvm.TrantientBundle
import uvm.ir.textinput.UIRTextReader
import uvm.ir.textoutput.BundleSerializer
import uvm.testutil.StopWatch
import uvm.utils.IDFactory
object DumpLoadTimer extends App {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
def parseReader(reader: Reader, globalBundle: GlobalBundle, fac: Option[IDFactory] = None): TrantientBundle = {
val idf = fac.getOrElse(new IDFactory(uvm.refimpl.MicroVM.FIRST_CLIENT_USABLE_ID))
val idf = fac.getOrElse(IDFactory.newClientIDFactory())
val r = new UIRTextReader(idf, recordSourceInfo = false)
val ir = r.read(reader, globalBundle)
ir
......@@ -33,13 +34,13 @@ object DumpLoadTimer extends App {
def main(): Unit = {
val w = new StopWatch()
w.start()
val gb = new GlobalBundle()
logger.info("Parsing (fresh) %s ...".format(fileName))
val tb = parseFile(fileName, gb)
gb.merge(tb)
val s1 = w.split()
logger.info("Dumping loaded bundle...")
......@@ -62,10 +63,10 @@ object DumpLoadTimer extends App {
gb2.merge(tb2)
val s3 = w.stop()
val total = w.total()
logger.info("load1: %d, dump: %d, load2: %d, total: %d".format(s1,s2,s3,total))
logger.info("load1: %d, dump: %d, load2: %d, total: %d".format(s1, s2, s3, total))
}
......
......@@ -295,6 +295,6 @@ class BundleBuilderTest extends UvmTestBase {
println(ir)
val muBundle = new UIRTextReader(new IDFactory(0)).read(ir, new uvm.GlobalBundle())
val muBundle = new UIRTextReader(IDFactory.newClientIDFactory()).read(ir, new uvm.GlobalBundle())
}
}
\ No newline at end of file
package uvm.ir.textinput
import uvm.TrantientBundle
import uvm.GlobalBundle
import uvm.utils.IDFactory
import java.io.Reader
trait IRParsing {
def parseReader(reader: Reader, globalBundle: GlobalBundle, fac: Option[IDFactory] = None): TrantientBundle = {
val idf = fac.getOrElse(IDFactory.newClientIDFactory())
val r = new UIRTextReader(idf)
val ir = r.read(reader, globalBundle)
ir
}
def parseFile(fileName: String, globalBundle: GlobalBundle, fac: Option[IDFactory] = None): TrantientBundle = {
parseReader(new java.io.FileReader(fileName), globalBundle, fac)
}
def parseText(uir: String, globalBundle: GlobalBundle, fac: Option[IDFactory]=None): TrantientBundle = {
parseReader(new java.io.StringReader(uir), globalBundle, fac)
}
}
\ No newline at end of file
......@@ -7,14 +7,7 @@ import uvm.TrantientBundle
import uvm.utils.IDFactory
import uvm.UvmTestBase
class NicerErrorMessage extends UvmTestBase with TestingBundlesValidators {
def parseFile(fileName: String, globalBundle: GlobalBundle, fac: Option[IDFactory] = None): TrantientBundle = {
val idf = fac.getOrElse(new IDFactory(uvm.refimpl.MicroVM.FIRST_CLIENT_USABLE_ID))
val r = new UIRTextReader(idf)
val ir = r.read(new java.io.FileReader(fileName), globalBundle)
ir
}
class NicerErrorMessage extends UvmTestBase with TestingBundlesValidators with IRParsing {
behavior of "UIRTextReader"
......
package uvm.ir.textinput
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import uvm.GlobalBundle
import uvm.TrantientBundle
import uvm.utils.IDFactory
import org.scalatest.exceptions.TestFailedException
import uvm.LogSetter
import uvm.GlobalBundle
import uvm.UvmTestBase
class SourceInfoRepoTest extends UvmTestBase {
def parseText(globalBundle: GlobalBundle, fac: Option[IDFactory]=None)(uir: String): TrantientBundle = {
val idf = fac.getOrElse(new IDFactory(uvm.refimpl.MicroVM.FIRST_CLIENT_USABLE_ID))
val r = new UIRTextReader(idf)
val ir = r.read(new java.io.StringReader(uir), globalBundle)
ir
}
class SourceInfoRepoTest extends UvmTestBase with IRParsing {
behavior of "SourceInfoRepo"
def catchExceptionWhenParsing(text: String): Unit = {
try {
val gb = new GlobalBundle()
val b = parseText(gb)(text)
val b = parseText(text, gb)
fail()
} catch {
case e: TestFailedException => throw e
......
package uvm.ir.textinput
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import uvm.GlobalBundle
import uvm.TrantientBundle
import uvm.utils.IDFactory
import uvm.LogSetter
import uvm.UvmTestBase
class UIRTextReaderSpec extends UvmTestBase with TestingBundlesValidators {
def parseFile(fileName: String, globalBundle: GlobalBundle, fac: Option[IDFactory] = None): TrantientBundle = {
val idf = fac.getOrElse(new IDFactory(uvm.refimpl.MicroVM.FIRST_CLIENT_USABLE_ID))
val r = new UIRTextReader(idf)
val ir = r.read(new java.io.FileReader(fileName), globalBundle)
ir
}
class UIRTextReaderSpec extends UvmTestBase with TestingBundlesValidators with IRParsing {
behavior of "UIRTextReader"
......
......@@ -11,24 +11,15 @@ import org.slf4j.LoggerFactory
import java.io.StringWriter
import java.io.StringReader
import java.io.Reader
import uvm.ir.textinput.IRParsing
object BundleSerializerSmokeTest {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
}
class BundleSerializerSmokeTest extends UvmTestBase with TestingBundlesValidators {
class BundleSerializerSmokeTest extends UvmTestBase with TestingBundlesValidators with IRParsing {
import BundleSerializerSmokeTest._
def parseReader(reader: Reader, globalBundle: GlobalBundle, fac: Option[IDFactory] = None): TrantientBundle = {
val idf = fac.getOrElse(new IDFactory(uvm.refimpl.MicroVM.FIRST_CLIENT_USABLE_ID))
val r = new UIRTextReader(idf)
val ir = r.read(reader, globalBundle)
ir
}
def parseFile(fileName: String, globalBundle: GlobalBundle, fac: Option[IDFactory] = None): TrantientBundle = {
parseReader(new java.io.FileReader(fileName), globalBundle, fac)
}
behavior of "BundleSerializer"
def parseFresh(fileName: String): GlobalBundle = {
......
package uvm.staticanalysis
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import org.scalatest.exceptions.TestFailedException
import uvm.GlobalBundle
import uvm.TrantientBundle
import uvm.ir.textinput.UIRTextReader
import uvm.utils.IDFactory
import uvm.UvmTestBase
import uvm.ir.textinput.IRParsing
class StaticAnalysisTest extends UvmTestBase {
class StaticAnalysisTest extends UvmTestBase with IRParsing {
def parseText(globalBundle: GlobalBundle, fac: Option[IDFactory]=None)(uir: String): TrantientBundle = {
val idf = fac.getOrElse(new IDFactory(uvm.refimpl.MicroVM.FIRST_CLIENT_USABLE_ID))
val r = new UIRTextReader(idf)
val ir = r.read(new java.io.StringReader(uir), globalBundle)
ir
}
def printException(e: Exception): Unit = travisFriendlyExceptionPrint(e)
behavior of "StaticAnalyzer"
def shouldWorkFineIn(text: String): Unit = {
val gb = new GlobalBundle()
val b = parseText(gb)(text)
val b = parseText(text, gb)
new StaticAnalyzer().checkBundle(b, Some(gb))
}
def catchExceptionWhenAnalyzing(text: String): Unit = {
val gb = new GlobalBundle()
val b = parseText(gb)(text)
val b = parseText(text, gb)
try {
new StaticAnalyzer().checkBundle(b, Some(gb))
fail()
......@@ -40,7 +26,7 @@ class StaticAnalysisTest extends UvmTestBase {
case e: StaticCheckingException => // expected
printException(e)
}
}
it should "complain if a struct contains itself" in {
......@@ -57,7 +43,7 @@ class StaticAnalysisTest extends UvmTestBase {
.typedef @t = struct<@i64 @s @i64>
""")
}
it should "not complain if the type is recursive on refs" in {
shouldWorkFineIn("""
.typedef @i64 = int<64>
......@@ -105,7 +91,7 @@ class StaticAnalysisTest extends UvmTestBase {
.funcsig @sig = () -> (@void)
""")
}
it should "complain if a hybrid is used for value types" in {
catchExceptionWhenAnalyzing("""
.typedef @i8 = int<8>
......@@ -121,8 +107,7 @@ class StaticAnalysisTest extends UvmTestBase {
.funcsig @sig = (@wr) -> ()
""")
}
it should "complain if a int literal is used on non-integer or non-pointer types" in {
catchExceptionWhenAnalyzing("""
.typedef @double = double
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment