MicroVM.scala 4.34 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
17 18

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

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

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

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

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

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

47
  implicit val nativeCallHelper = new NativeCallHelper()
Kunshan Wang's avatar
Kunshan Wang committed
48

49
  val threadStackManager = new ThreadStackManager()
50

51
  val trapManager = new TrapManager()
Kunshan Wang's avatar
Kunshan Wang committed
52
  val contexts = new HashSet[MuCtx]()
Kunshan Wang's avatar
Kunshan Wang committed
53

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

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

    // 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
74

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

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

89 90 91 92 93
    globalBundle.merge(bundle);

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

105
  /**
Kunshan Wang's avatar
Kunshan Wang committed
106
   * Create a new MuCtx. Part of the API.
107
   */
108 109 110 111 112 113 114 115 116
  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
117
    contexts.add(ca)
Kunshan Wang's avatar
Kunshan Wang committed
118 119
    ca
  }
120 121 122
  /**
   * Given a name, get the ID of an identified entity.
   */
Kunshan Wang's avatar
Kunshan Wang committed
123 124 125
  def idOf(name: String): Int = try {
    globalBundle.allNs(name).id
  } catch {
Kunshan Wang's avatar
Kunshan Wang committed
126
    case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has name %s".format(name), e)
Kunshan Wang's avatar
Kunshan Wang committed
127
  }
Kunshan Wang's avatar
Kunshan Wang committed
128

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

Kunshan Wang's avatar
Kunshan Wang committed
138 139 140 141 142 143 144
  /**
   * Set the trap handler.
   */
  def setTrapHandler(trapHandler: TrapHandler): Unit = {
    trapManager.trapHandler = trapHandler
  }

Kunshan Wang's avatar
Kunshan Wang committed
145 146 147 148 149 150
  /**
   * Execute. This is the external pusher of the execution.
   */
  def execute(): Unit = {
    threadStackManager.execute()
  }
151
}