MicroVM.scala 3.63 KB
Newer Older
1 2 3 4 5 6 7 8 9
package uvm.refimpl

import uvm._
import uvm.refimpl.itpr._
import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes.Word
import scala.collection.mutable.HashSet
import uvm.ir.textinput.UIRTextReader
import uvm.ir.textinput.IDFactory
Kunshan Wang's avatar
Kunshan Wang committed
10
import uvm.refimpl.nat.NativeCallHelper
11 12 13 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
}

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

22 23
  // implicitly injected resources
  private implicit val microVM = this
24

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

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

31
  implicit val nativeCallHelper = new NativeCallHelper()
Kunshan Wang's avatar
Kunshan Wang committed
32

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

37
  val irReader = new UIRTextReader(new IDFactory())
Kunshan Wang's avatar
Kunshan Wang committed
38

39
  {
Kunshan Wang's avatar
Kunshan Wang committed
40
    // The micro VM allocates stacks on the heap in the large object space. It is represented as a bug chunk of byte array.
41 42 43 44
    // So the GC must know about this type because the GC looks up the globalBundle for types.
    globalBundle.typeNs.add(InternalTypes.VOID)
    globalBundle.typeNs.add(InternalTypes.BYTE)
    globalBundle.typeNs.add(InternalTypes.BYTE_ARRAY)
45 46 47 48 49 50
    
    // Types for the @uvm.meta.* common instructions.
    globalBundle.typeNs.add(InternalTypes.BYTES)
    globalBundle.typeNs.add(InternalTypes.BYTES_R)
    globalBundle.typeNs.add(InternalTypes.REFS)
    globalBundle.typeNs.add(InternalTypes.REFS_R)
Kunshan Wang's avatar
Kunshan Wang committed
51 52 53 54 55 56 57
    
    // Some internal constants needed
    constantPool.addGlobalVar(InternalTypes.NULL_REF_VOID)
    constantPool.addGlobalVar(InternalTypes.NULL_IREF_VOID)
    constantPool.addGlobalVar(InternalTypes.NULL_FUNCREF_VV)
    constantPool.addGlobalVar(InternalTypes.NULL_THREADREF)
    constantPool.addGlobalVar(InternalTypes.NULL_STACKREF)
58
  }
59 60 61 62

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

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

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

96 97 98
  /**
   * Given an ID, get the name of an identified entity.
   */
Kunshan Wang's avatar
Kunshan Wang committed
99 100 101
  def nameOf(id: Int): String = try {
    globalBundle.allNs(id).name.get
  } catch {
Kunshan Wang's avatar
Kunshan Wang committed
102
    case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has ID %d".format(id), e)
Kunshan Wang's avatar
Kunshan Wang committed
103
  }
Kunshan Wang's avatar
Kunshan Wang committed
104
  
Kunshan Wang's avatar
Kunshan Wang committed
105 106 107 108 109 110 111
  /**
   * Set the trap handler.
   */
  def setTrapHandler(trapHandler: TrapHandler): Unit = {
    trapManager.trapHandler = trapHandler
  }

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