MicroVM.scala 3.85 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

51 52
  val irReader = new UIRTextReader(new IDFactory(MicroVM.FIRST_CLIENT_USABLE_ID), recordSourceInfo=vmConf.sourceInfo)
  val hailScriptLoader = new HailScriptLoader(recordSourceInfo=vmConf.sourceInfo)
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 80 81
    if (vmConf.staticCheck) {
      staticAnalyzer.checkBundle(bundle, Some(globalBundle))
    }
82

83 84 85 86 87
    globalBundle.merge(bundle);

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

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

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

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

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