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

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
19 20
  
  val FIRST_CLIENT_USABLE_ID: Int = 65536
21 22 23
}

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

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

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

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

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

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

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

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

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

  /**
   * Add things from a bundle to the Micro VM.
   */
70
  def addBundle(bundle: TrantientBundle) {
71 72
    staticAnalyzer.checkBundle(bundle, Some(globalBundle))
    
73 74 75 76 77
    globalBundle.merge(bundle);

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

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

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

Kunshan Wang's avatar
Kunshan Wang committed
114 115 116 117 118 119 120
  /**
   * Set the trap handler.
   */
  def setTrapHandler(trapHandler: TrapHandler): Unit = {
    trapManager.trapHandler = trapHandler
  }

Kunshan Wang's avatar
Kunshan Wang committed
121 122 123 124 125 126
  /**
   * Execute. This is the external pusher of the execution.
   */
  def execute(): Unit = {
    threadStackManager.execute()
  }
127
}