MicroVM.scala 3.52 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 14 15 16 17

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
Kunshan Wang's avatar
Kunshan Wang committed
18 19
  
  val FIRST_CLIENT_USABLE_ID: Int = 65536
20 21 22
}

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

26 27
  // implicitly injected resources
  private implicit val microVM = this
28

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

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

35
  implicit val nativeCallHelper = new NativeCallHelper()
Kunshan Wang's avatar
Kunshan Wang committed
36

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

Kunshan Wang's avatar
Kunshan Wang committed
42
  val irReader = new UIRTextReader(new IDFactory(MicroVM.FIRST_CLIENT_USABLE_ID))
Kunshan Wang's avatar
Kunshan Wang committed
43
  val hailScriptLoader = new HailScriptLoader()
Kunshan Wang's avatar
Kunshan Wang committed
44

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

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

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

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

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

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

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

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