MicroVM.scala 4.57 KB
Newer Older
1 2
package uvm.refimpl

Kunshan Wang's avatar
Kunshan Wang committed
3 4
import scala.collection.mutable.HashSet

5
import uvm._
Kunshan Wang's avatar
Kunshan Wang committed
6
import uvm.utils.IDFactory
Kunshan Wang's avatar
Kunshan Wang committed
7 8
import uvm.ir.textinput.UIRTextReader
import uvm.refimpl.hail.HailScriptLoader
9 10 11
import uvm.refimpl.itpr._
import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes.Word
Kunshan Wang's avatar
Kunshan Wang committed
12
import uvm.refimpl.nat.NativeCallHelper
13
import uvm.staticanalysis.StaticAnalyzer
14
import uvm.utils.IDFactory
15
import uvm.ir.irbuilder.IRBuilder
16
import uvm.ir.irbuilder.IRNode
Kunshan Wang's avatar
Kunshan Wang committed
17
import uvm.refimpl.nat.NativeLibraryHolder
18 19

object MicroVM {
20 21
  val DEFAULT_SOS_SIZE: Word = 2L * 1024L * 1024L; // 2MiB
  val DEFAULT_LOS_SIZE: Word = 2L * 1024L * 1024L; // 2MiB
22 23
  val DEFAULT_GLOBAL_SIZE: Word = 1L * 1024L * 1024L; // 1MiB
  val DEFAULT_STACK_SIZE: Word = 63L * 1024L; // 60KiB per stack
24

Kunshan Wang's avatar
Kunshan Wang committed
25
  val FIRST_CLIENT_USABLE_ID: Int = 65536
26

27
  def apply(): MicroVM = {
Kunshan Wang's avatar
Kunshan Wang committed
28 29
    val vmConf = new VMConf()
    new MicroVM(vmConf)
30 31 32
  }
  
  def apply(confStr: String): MicroVM = {
Kunshan Wang's avatar
Kunshan Wang committed
33 34
    val vmConf = VMConf(confStr)
    new MicroVM(vmConf)
35 36
  }
}
Kunshan Wang's avatar
Kunshan Wang committed
37

Kunshan Wang's avatar
Kunshan Wang committed
38
class MicroVM(vmConf: VMConf) {
39 40
  // implicitly injected resources
  private implicit val microVM = this
41

42
  val globalBundle = new GlobalBundle()
43
  val constantPool = new ConstantPool()
Kunshan Wang's avatar
Kunshan Wang committed
44
  val memoryManager = new MemoryManager(vmConf)
Kunshan Wang's avatar
Kunshan Wang committed
45 46

  private implicit val memorySupport = memoryManager.memorySupport
Kunshan Wang's avatar
Kunshan Wang committed
47

Kunshan Wang's avatar
Kunshan Wang committed
48 49
  val nativeLibraryHolder = NativeLibraryHolder(vmConf.extraLibs: _*)
  
50
  implicit val nativeCallHelper = new NativeCallHelper()
Kunshan Wang's avatar
Kunshan Wang committed
51

52
  val threadStackManager = new ThreadStackManager()
53

54
  val trapManager = new TrapManager()
Kunshan Wang's avatar
Kunshan Wang committed
55
  val contexts = new HashSet[MuCtx]()
Kunshan Wang's avatar
Kunshan Wang committed
56

57 58
  val idFactory = new IDFactory(MicroVM.FIRST_CLIENT_USABLE_ID)
  val irBuilder = new IRBuilder(globalBundle, idFactory)
59
  val irNodeRegistry = new SequentialObjectKeeper[IRNode]()
60
  val irReader = new UIRTextReader(idFactory, recordSourceInfo=vmConf.sourceInfo)
61
  val hailScriptLoader = new HailScriptLoader(recordSourceInfo=vmConf.sourceInfo)
62
  val staticAnalyzer = new StaticAnalyzer()
Kunshan Wang's avatar
Kunshan Wang committed
63

64
  {
Kunshan Wang's avatar
Kunshan Wang committed
65 66
    // 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.
67
    // So the GC must know about this type because the GC looks up the globalBundle for types.
Kunshan Wang's avatar
Kunshan Wang committed
68 69 70 71 72 73 74 75 76

    // BYTES, BYTES_R, REFS, REFS_R: Types for the @uvm.meta.* common instructions.

    import InternalTypes._
    for (ty <- Seq(VOID, BYTE, BYTE_ARRAY, BYTES, BYTES_R, REFS, REFS_R)) {
      globalBundle.typeNs.add(ty)
    }

    // Some internal constants needed by the HAIL loader
77

Kunshan Wang's avatar
Kunshan Wang committed
78 79 80 81
    for (c <- Seq(NULL_REF_VOID, NULL_IREF_VOID, NULL_FUNCREF_VV, NULL_THREADREF, NULL_STACKREF)) {
      globalBundle.constantNs.add(c)
      constantPool.addGlobalVar(c)
    }
82
  }
83 84 85 86

  /**
   * Add things from a bundle to the Micro VM.
   */
87
  def addBundle(bundle: TrantientBundle) {
88 89 90
    if (vmConf.staticCheck) {
      staticAnalyzer.checkBundle(bundle, Some(globalBundle))
    }
91

92 93 94 95 96
    globalBundle.merge(bundle);

    for (gc <- bundle.globalCellNs.all) {
      memoryManager.globalMemory.addGlobalCell(gc)
    }
97
    for (ef <- bundle.expFuncNs.all) {
98
      nativeCallHelper.exposeFuncStatic(ef)
99 100
    }
    // Must allocate the memory and expose the functions before making constants.
101 102 103 104
    for (g <- bundle.globalVarNs.all) {
      constantPool.addGlobalVar(g)
    }
  }
105 106
  
  private val contextIDFactory = new IDFactory(1)
Kunshan Wang's avatar
Kunshan Wang committed
107

108
  /**
Kunshan Wang's avatar
Kunshan Wang committed
109
   * Create a new MuCtx. Part of the API.
110
   */
111 112 113 114 115 116 117 118 119
  def newContext(): MuCtx = newContext("user")

  /**
   * Create a new MuCtx. Extended to add a name for debugging.
   */
  def newContext(name: String): MuCtx = {
    val id = contextIDFactory.getID()
    val mutator = microVM.memoryManager.heap.makeMutator("MuCtx-%d-%s".format(id, name)) // This may trigger GC
    val ca = new MuCtx(id, mutator)
Kunshan Wang's avatar
Kunshan Wang committed
120
    contexts.add(ca)
Kunshan Wang's avatar
Kunshan Wang committed
121 122
    ca
  }
123 124 125
  /**
   * Given a name, get the ID of an identified entity.
   */
Kunshan Wang's avatar
Kunshan Wang committed
126 127 128
  def idOf(name: String): Int = try {
    globalBundle.allNs(name).id
  } catch {
Kunshan Wang's avatar
Kunshan Wang committed
129
    case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has name %s".format(name), e)
Kunshan Wang's avatar
Kunshan Wang committed
130
  }
Kunshan Wang's avatar
Kunshan Wang committed
131

132 133 134
  /**
   * Given an ID, get the name of an identified entity.
   */
Kunshan Wang's avatar
Kunshan Wang committed
135 136 137
  def nameOf(id: Int): String = try {
    globalBundle.allNs(id).name.get
  } catch {
Kunshan Wang's avatar
Kunshan Wang committed
138
    case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has ID %d".format(id), e)
Kunshan Wang's avatar
Kunshan Wang committed
139
  }
Kunshan Wang's avatar
Kunshan Wang committed
140

Kunshan Wang's avatar
Kunshan Wang committed
141 142 143 144 145 146
  /**
   * Set the trap handler.
   */
  def setTrapHandler(trapHandler: TrapHandler): Unit = {
    trapManager.trapHandler = trapHandler
  }
Kunshan Wang's avatar
Kunshan Wang committed
147 148 149 150 151 152 153
  
  /**
   * Make boot image.
   */
  def makeBootImage(whiteList: Seq[Int], outputFile: String): Unit = {
    ???
  }
Kunshan Wang's avatar
Kunshan Wang committed
154

Kunshan Wang's avatar
Kunshan Wang committed
155 156 157 158 159 160
  /**
   * Execute. This is the external pusher of the execution.
   */
  def execute(): Unit = {
    threadStackManager.execute()
  }
161
}