MicroVM.scala 3.45 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 7 8
import uvm.ir.textinput.IDFactory
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 14 15 16 17 18 19 20

object MicroVM {
  val DEFAULT_HEAP_SIZE: Word = 4L * 1024L * 1024L; // 4MiB
  val DEFAULT_GLOBAL_SIZE: Word = 1L * 1024L * 1024L; // 1MiB
  val DEFAULT_STACK_SIZE: Word = 63L * 1024L; // 60KiB per stack
}

class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
Kunshan Wang's avatar
Kunshan Wang committed
21 22
    globalSize: Word = MicroVM.DEFAULT_GLOBAL_SIZE,
    stackSize: Word = MicroVM.DEFAULT_STACK_SIZE) {
Kunshan Wang's avatar
Kunshan Wang committed
23

24 25
  // implicitly injected resources
  private implicit val microVM = this
26

27
  val globalBundle = new GlobalBundle()
28 29
  val constantPool = new ConstantPool()
  val memoryManager = new MemoryManager(heapSize, globalSize, stackSize)
Kunshan Wang's avatar
Kunshan Wang committed
30 31

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

33
  implicit val nativeCallHelper = new NativeCallHelper()
Kunshan Wang's avatar
Kunshan Wang committed
34

35 36
  val threadStackManager = new ThreadStackManager()
  val trapManager = new TrapManager()
Kunshan Wang's avatar
Kunshan Wang committed
37
  val contexts = new HashSet[MuCtx]()
Kunshan Wang's avatar
Kunshan Wang committed
38

39
  val irReader = new UIRTextReader(new IDFactory())
Kunshan Wang's avatar
Kunshan Wang committed
40
  val hailScriptLoader = new HailScriptLoader()
Kunshan Wang's avatar
Kunshan Wang committed
41

42
  {
Kunshan Wang's avatar
Kunshan Wang committed
43 44
    // 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.
45
    // So the GC must know about this type because the GC looks up the globalBundle for types.
Kunshan Wang's avatar
Kunshan Wang committed
46 47 48 49 50 51 52 53 54

    // 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
Kunshan Wang's avatar
Kunshan Wang committed
55
    
Kunshan Wang's avatar
Kunshan Wang committed
56 57 58 59
    for (c <- Seq(NULL_REF_VOID, NULL_IREF_VOID, NULL_FUNCREF_VV, NULL_THREADREF, NULL_STACKREF)) {
      globalBundle.constantNs.add(c)
      constantPool.addGlobalVar(c)
    }
60
  }
61 62 63 64

  /**
   * Add things from a bundle to the Micro VM.
   */
65
  def addBundle(bundle: TrantientBundle) {
66 67 68 69 70
    globalBundle.merge(bundle);

    for (gc <- bundle.globalCellNs.all) {
      memoryManager.globalMemory.addGlobalCell(gc)
    }
71
    for (ef <- bundle.expFuncNs.all) {
72
      nativeCallHelper.exposeFuncStatic(ef)
73 74
    }
    // Must allocate the memory and expose the functions before making constants.
75 76 77 78
    for (g <- bundle.globalVarNs.all) {
      constantPool.addGlobalVar(g)
    }
  }
Kunshan Wang's avatar
Kunshan Wang committed
79

80
  /**
Kunshan Wang's avatar
Kunshan Wang committed
81
   * Create a new MuCtx. Part of the API.
82
   */
Kunshan Wang's avatar
Kunshan Wang committed
83
  def newContext(): MuCtx = {
Kunshan Wang's avatar
Kunshan Wang committed
84
    val mutator = microVM.memoryManager.heap.makeMutator() // This may trigger GC
Kunshan Wang's avatar
Kunshan Wang committed
85 86
    val ca = new MuCtx(mutator)
    contexts.add(ca)
Kunshan Wang's avatar
Kunshan Wang committed
87 88
    ca
  }
89 90 91
  /**
   * Given a name, get the ID of an identified entity.
   */
Kunshan Wang's avatar
Kunshan Wang committed
92 93 94
  def idOf(name: String): Int = try {
    globalBundle.allNs(name).id
  } catch {
Kunshan Wang's avatar
Kunshan Wang committed
95
    case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has name %s".format(name), e)
Kunshan Wang's avatar
Kunshan Wang committed
96
  }
Kunshan Wang's avatar
Kunshan Wang committed
97

98 99 100
  /**
   * Given an ID, get the name of an identified entity.
   */
Kunshan Wang's avatar
Kunshan Wang committed
101 102 103
  def nameOf(id: Int): String = try {
    globalBundle.allNs(id).name.get
  } catch {
Kunshan Wang's avatar
Kunshan Wang committed
104
    case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has ID %d".format(id), e)
Kunshan Wang's avatar
Kunshan Wang committed
105
  }
Kunshan Wang's avatar
Kunshan Wang committed
106

Kunshan Wang's avatar
Kunshan Wang committed
107 108 109 110 111 112 113
  /**
   * Set the trap handler.
   */
  def setTrapHandler(trapHandler: TrapHandler): Unit = {
    trapManager.trapHandler = trapHandler
  }

Kunshan Wang's avatar
Kunshan Wang committed
114 115 116 117 118 119
  /**
   * Execute. This is the external pusher of the execution.
   */
  def execute(): Unit = {
    threadStackManager.execute()
  }
120
}