MicroVM.scala 3.75 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 15

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

Kunshan Wang's avatar
Kunshan Wang committed
21
  val FIRST_CLIENT_USABLE_ID: Int = 65536
22

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

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

38
  val globalBundle = new GlobalBundle()
39
  val constantPool = new ConstantPool()
Kunshan Wang's avatar
Kunshan Wang committed
40
  val memoryManager = new MemoryManager(vmConf)
Kunshan Wang's avatar
Kunshan Wang committed
41 42

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

44
  implicit val nativeCallHelper = new NativeCallHelper()
Kunshan Wang's avatar
Kunshan Wang committed
45

46
  val threadStackManager = new ThreadStackManager()
47

48
  val trapManager = new TrapManager()
Kunshan Wang's avatar
Kunshan Wang committed
49
  val contexts = new HashSet[MuCtx]()
Kunshan Wang's avatar
Kunshan Wang committed
50

Kunshan Wang's avatar
Kunshan Wang committed
51
  val irReader = new UIRTextReader(new IDFactory(MicroVM.FIRST_CLIENT_USABLE_ID))
Kunshan Wang's avatar
Kunshan Wang committed
52
  val hailScriptLoader = new HailScriptLoader()
53
  val staticAnalyzer = new StaticAnalyzer()
Kunshan Wang's avatar
Kunshan Wang committed
54

55
  {
Kunshan Wang's avatar
Kunshan Wang committed
56 57
    // 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.
58
    // So the GC must know about this type because the GC looks up the globalBundle for types.
Kunshan Wang's avatar
Kunshan Wang committed
59 60 61 62 63 64 65 66 67

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

Kunshan Wang's avatar
Kunshan Wang committed
69 70 71 72
    for (c <- Seq(NULL_REF_VOID, NULL_IREF_VOID, NULL_FUNCREF_VV, NULL_THREADREF, NULL_STACKREF)) {
      globalBundle.constantNs.add(c)
      constantPool.addGlobalVar(c)
    }
73
  }
74 75 76 77

  /**
   * Add things from a bundle to the Micro VM.
   */
78
  def addBundle(bundle: TrantientBundle) {
79
    staticAnalyzer.checkBundle(bundle, Some(globalBundle))
80

81 82 83 84 85
    globalBundle.merge(bundle);

    for (gc <- bundle.globalCellNs.all) {
      memoryManager.globalMemory.addGlobalCell(gc)
    }
86
    for (ef <- bundle.expFuncNs.all) {
87
      nativeCallHelper.exposeFuncStatic(ef)
88 89
    }
    // Must allocate the memory and expose the functions before making constants.
90 91 92 93
    for (g <- bundle.globalVarNs.all) {
      constantPool.addGlobalVar(g)
    }
  }
Kunshan Wang's avatar
Kunshan Wang committed
94

95
  /**
Kunshan Wang's avatar
Kunshan Wang committed
96
   * Create a new MuCtx. Part of the API.
97
   */
Kunshan Wang's avatar
Kunshan Wang committed
98
  def newContext(): MuCtx = {
Kunshan Wang's avatar
Kunshan Wang committed
99
    val mutator = microVM.memoryManager.heap.makeMutator() // This may trigger GC
Kunshan Wang's avatar
Kunshan Wang committed
100 101
    val ca = new MuCtx(mutator)
    contexts.add(ca)
Kunshan Wang's avatar
Kunshan Wang committed
102 103
    ca
  }
104 105 106
  /**
   * Given a name, get the ID of an identified entity.
   */
Kunshan Wang's avatar
Kunshan Wang committed
107 108 109
  def idOf(name: String): Int = try {
    globalBundle.allNs(name).id
  } catch {
Kunshan Wang's avatar
Kunshan Wang committed
110
    case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has name %s".format(name), e)
Kunshan Wang's avatar
Kunshan Wang committed
111
  }
Kunshan Wang's avatar
Kunshan Wang committed
112

113 114 115
  /**
   * Given an ID, get the name of an identified entity.
   */
Kunshan Wang's avatar
Kunshan Wang committed
116 117 118
  def nameOf(id: Int): String = try {
    globalBundle.allNs(id).name.get
  } catch {
Kunshan Wang's avatar
Kunshan Wang committed
119
    case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has ID %d".format(id), e)
Kunshan Wang's avatar
Kunshan Wang committed
120
  }
Kunshan Wang's avatar
Kunshan Wang committed
121

Kunshan Wang's avatar
Kunshan Wang committed
122 123 124 125 126 127 128
  /**
   * Set the trap handler.
   */
  def setTrapHandler(trapHandler: TrapHandler): Unit = {
    trapManager.trapHandler = trapHandler
  }

Kunshan Wang's avatar
Kunshan Wang committed
129 130 131 132 133 134
  /**
   * Execute. This is the external pusher of the execution.
   */
  def execute(): Unit = {
    threadStackManager.execute()
  }
135
}