Commit 59c285d4 authored by Kunshan Wang's avatar Kunshan Wang

WIP: updating interpreter...

parent 7e002594
......@@ -16,8 +16,7 @@ case class Handle(ty: Type, vb: ValueBox)
abstract class TrapHandlerResult
case class TrapExit() extends TrapHandlerResult
case class TrapRebindPassValue(newStack: Handle, value: Handle) extends TrapHandlerResult
case class TrapRebindPassVoid(newStack: Handle) extends TrapHandlerResult
case class TrapRebindPassValues(newStack: Handle, values: Seq[Handle]) extends TrapHandlerResult
case class TrapRebindThrowExc(newStack: Handle, exc: Handle) extends TrapHandlerResult
trait TrapHandler {
......@@ -264,7 +263,7 @@ class ClientAgent(mutator: Mutator)(
def load(ord: MemoryOrder, loc: Handle): Handle = {
val (ptr, ty) = loc.ty match {
case TypeIRef(t) => (false, t)
case TypeUPtr(t) => (true, t)
case TypeUPtr(t) => (true, t)
}
val uty = InternalTypePool.unmarkedOf(ty)
val addr = MemoryOperations.addressOf(ptr, loc.vb)
......@@ -278,7 +277,7 @@ class ClientAgent(mutator: Mutator)(
def store(ord: MemoryOrder, loc: Handle, newVal: Handle): Unit = {
val (ptr, ty) = loc.ty match {
case TypeIRef(t) => (false, t)
case TypeUPtr(t) => (true, t)
case TypeUPtr(t) => (true, t)
}
val uty = InternalTypePool.unmarkedOf(ty)
val addr = MemoryOperations.addressOf(ptr, loc.vb)
......@@ -291,7 +290,7 @@ class ClientAgent(mutator: Mutator)(
def cmpXchg(ordSucc: MemoryOrder, ordFail: MemoryOrder, weak: Boolean, loc: Handle, expected: Handle, desired: Handle): (Boolean, Handle) = {
val (ptr, ty) = loc.ty match {
case TypeIRef(t) => (false, t)
case TypeUPtr(t) => (true, t)
case TypeUPtr(t) => (true, t)
}
val uty = InternalTypePool.unmarkedOf(ty)
val addr = MemoryOperations.addressOf(ptr, loc.vb)
......@@ -305,7 +304,7 @@ class ClientAgent(mutator: Mutator)(
def atomicRMW(ord: MemoryOrder, op: AtomicRMWOptr, loc: Handle, opnd: Handle): Handle = {
val (ptr, ty) = loc.ty match {
case TypeIRef(t) => (false, t)
case TypeUPtr(t) => (true, t)
case TypeUPtr(t) => (true, t)
}
val uty = InternalTypePool.unmarkedOf(ty)
val addr = MemoryOperations.addressOf(ptr, loc.vb)
......@@ -318,18 +317,12 @@ class ClientAgent(mutator: Mutator)(
def fence(ord: MemoryOrder): Unit = {
}
def newStack(func: Handle, args: Seq[Handle]): Handle = {
def newStack(func: Handle): Handle = {
val funcVal = func.vb.asInstanceOf[BoxFunc].func.getOrElse {
throw new UvmRuntimeException("Stack-bottom function must not be NULL")
}
val funcVer = funcVal.versions.headOption.getOrElse {
throw new UvmRuntimeException("Stack-bottom function %s is not defined.".format(funcVal.repr))
}
val argBoxes = args.map(_.vb)
val sta = microVM.threadStackManager.newStack(funcVer, argBoxes, mutator)
val sta = microVM.threadStackManager.newStack(funcVal, mutator)
val nb = BoxStack(Some(sta))
newHandle(InternalTypes.STACK, nb)
......@@ -377,8 +370,9 @@ class ClientAgent(mutator: Mutator)(
val sv = getStackNotNull(stack)
val fr = nthFrame(sv, frame)
fr match {
case f: NativeFrame => 0
case f: MuFrame => f.funcVer.id
case f: NativeFrame => 0
case f: UndefinedMuFrame => 0
case f: DefinedMuFrame => f.funcVer.id
}
}
......@@ -386,8 +380,9 @@ class ClientAgent(mutator: Mutator)(
val sv = getStackNotNull(stack)
val fr = nthFrame(sv, frame)
fr match {
case f: NativeFrame => 0
case f: MuFrame => f.curInst.id
case f: NativeFrame => 0
case f: UndefinedMuFrame => 0
case f: DefinedMuFrame => f.curInst.id
}
}
......@@ -398,7 +393,12 @@ class ClientAgent(mutator: Mutator)(
case f: NativeFrame => {
throw new UvmRefImplException("Attempt to dump keepalive variables for a native frame for native funciton 0x%x".format(f.func))
}
case f: MuFrame => {
case f: UndefinedMuFrame => {
for ((ty,box) <- f.func.sig.paramTys zip f.boxes) yield {
newHandle(ty, box)
}
}
case f: DefinedMuFrame => {
val i = f.curInst
i match {
case hkac: HasKeepAliveClause => {
......@@ -429,7 +429,7 @@ class ClientAgent(mutator: Mutator)(
}
}
def pushFrame(stack: Handle, func: Handle, argList: Seq[Handle]): Unit = {
def pushFrame(stack: Handle, func: Handle): Unit = {
val sta = stack.vb.asInstanceOf[BoxStack].stack.getOrElse {
throw new UvmRuntimeException("Stack must not be NULL")
}
......@@ -438,13 +438,7 @@ class ClientAgent(mutator: Mutator)(
throw new UvmRuntimeException("Stack-bottom function must not be NULL")
}
val funcVer = funcVal.versions.headOption.getOrElse {
throw new UvmRuntimeException("Stack-bottom function %s is not defined.".format(funcVal.repr))
}
val argBoxes = argList.map(_.vb)
sta.pushMuFrame(funcVer, argBoxes)
sta.pushFrame(funcVal)
}
def tr64IsFp(handle: Handle): Boolean = {
......@@ -545,19 +539,19 @@ class ClientAgent(mutator: Mutator)(
}
unpin(objRef)
}
def expose(func: Handle, callConv: Flag, cookie: Handle): Handle = {
val TypeFuncRef(sig) = func.ty
val f = func.vb.asInstanceOf[BoxFunc].func.getOrElse {
throw new UvmRuntimeException("Attempt to expose NULL Mu function")
}
val c = cookie.vb.asInstanceOf[BoxInt].value.toLong
val addr = microVM.nativeCallHelper.exposeFuncDynamic(f,c)
val addr = microVM.nativeCallHelper.exposeFuncDynamic(f, c)
newHandle(InternalTypePool.funcPtrOf(sig), BoxPointer(addr))
}
def unexpose(callConv: Flag, addr: Handle): Unit = {
val a = addr.vb.asInstanceOf[BoxPointer].addr
microVM.nativeCallHelper.unexposeFunc(a)
......
This diff is collapsed.
package uvm.refimpl.itpr
import uvm.FuncVer
import uvm.Function
import uvm.refimpl.MicroVM
import uvm.refimpl.mem._
import scala.collection.mutable.HashMap
......@@ -28,7 +28,7 @@ class ThreadStackManager(implicit microVM: MicroVM, nativeCallHelper: NativeCall
def getThreadByID(id: Int): Option[InterpreterThread] = threadRegistry.get(id)
def iterateAllLiveStacks: Iterable[InterpreterStack] = stackRegistry.values.filter(_.state != StackState.Dead)
def iterateAllLiveStacks: Iterable[InterpreterStack] = stackRegistry.values.filter(_.state != FrameState.Dead)
def iterateAllLiveThreads: Iterable[InterpreterThread] = threadRegistry.values.filter(_.isRunning)
......@@ -55,10 +55,10 @@ class ThreadStackManager(implicit microVM: MicroVM, nativeCallHelper: NativeCall
* via the "new_stack" message or micro VM threads (the InterpreterThread class) which can execute the NEWSTACK
* instruction.
*/
def newStack(funcVer: FuncVer, args: Seq[ValueBox], mutator: Mutator): InterpreterStack = {
def newStack(func: Function, mutator: Mutator): InterpreterStack = {
val stackMemory = microVM.memoryManager.makeStackMemory(mutator)
val id = makeStackID()
val sta = new InterpreterStack(id, stackMemory, funcVer, args)
val sta = new InterpreterStack(id, stackMemory, func)
stackRegistry.put(id, sta)
sta
}
......
......@@ -361,8 +361,8 @@ object MemoryOperations {
}
}
def store(ptr: Boolean, ty: Type, loc: Word, nvb: ValueBox, br: ValueBox)(implicit memorySupport: MemorySupport): Unit = {
def storeScalar(ty: Type, loc: Word, nvb: ValueBox, br: ValueBox): Unit = ty match {
def store(ptr: Boolean, ty: Type, loc: Word, nvb: ValueBox)(implicit memorySupport: MemorySupport): Unit = {
def storeScalar(ty: Type, loc: Word, nvb: ValueBox): Unit = ty match {
case TypeInt(l) =>
val bi = nvb.asInstanceOf[BoxInt].value
l match {
......@@ -412,12 +412,11 @@ object MemoryOperations {
ty match {
case TypeVector(ety, len) =>
val nvbs = nvb.asInstanceOf[BoxSeq].values
val brs = br.asInstanceOf[BoxSeq].values
val elemSkip = alignUp(sizeOf(ety), alignOf(ety))
for (((brElem, nvbElem), i) <- (brs zip nvbs).zipWithIndex) {
storeScalar(ety, loc + elemSkip * i, nvbElem, brElem)
for ((nvbElem, i) <- nvbs.zipWithIndex) {
storeScalar(ety, loc + elemSkip * i, nvbElem)
}
case sty => storeScalar(sty, loc, nvb, br)
case sty => storeScalar(sty, loc, nvb)
}
}
......
......@@ -104,7 +104,7 @@ object TypeSizes {
return align
}
def fieldOffsetOf(ty: TypeStruct, index: Int): Word = {
def fieldOffsetOf(ty: AbstractStructType, index: Int): Word = {
val fieldType = ty.fieldTys(index)
val fieldAlign = alignOf(fieldType)
val prefixSize = structPrefixSizeOf(ty, index)
......@@ -120,8 +120,6 @@ object TypeSizes {
return alignUp(sizeOf(ty), alignOf(ty)) * index
}
def fixedPartOffsetOf(ty: TypeHybrid): Word = 0L
def varPartOffsetOf(ty: TypeHybrid): Word = {
return alignUp(structPrefixSizeOf(ty, ty.fieldTys.length), alignOf(ty.varTy))
}
......
......@@ -79,7 +79,7 @@ class AllScanner(val handler: RefFieldHandler)(
private def traceStack(sta: InterpreterStack) {
logger.debug(s"Tracing stack ${sta.id} for registers...")
for (fra <- sta.muFrames; vb <- fra.boxes.values) vb match {
for (fra <- sta.muFrames; vb <- fra.scannableBoxes) vb match {
case hor: HasObjRef => this.boxToHeap(hor)
case bst: BoxStack => this.boxToStack(bst)
case _ =>
......
......@@ -185,7 +185,7 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap, val space: SimpleImmixSpac
}
private def maybeMarkStack(stack: InterpreterStack): Option[InterpreterStack] = {
if (stack.state != StackState.Dead) {
if (stack.state != FrameState.Dead) {
if (!stack.gcMark) {
stack.gcMark = true
Some(stack)
......
......@@ -7,6 +7,7 @@ import uvm.{ Function => MFunc }
import uvm.refimpl.UvmRuntimeException
import com.typesafe.scalalogging.Logger
import org.slf4j.LoggerFactory
import scala.annotation.tailrec
object PoorManAgent {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
......@@ -31,8 +32,10 @@ trait PoorManAgent[T] {
abstract class NativeCallResult
object NativeCallResult {
case class CallBack(func: MFunc, cookie: Long, args: Seq[ValueBox], maybeRetBox: Option[ValueBox]) extends NativeCallResult
case class Return() extends NativeCallResult
/** Native calls back to Mu. */
case class CallMu(func: MFunc, cookie: Long, args: Seq[ValueBox]) extends NativeCallResult
/** Native returns to Mu. maybeRvb holds the return value. */
case class ReturnToMu(maybeRvb: Option[ValueBox]) extends NativeCallResult
}
object NativeStackKeeper {
......@@ -64,8 +67,11 @@ class NativeStackKeeper(implicit nativeCallHelper: NativeCallHelper) extends Poo
abstract class ToSlave
object ToSlave {
case class CallNative(sig: FuncSig, func: Word, args: Seq[ValueBox], retBox: ValueBox) extends ToSlave
case class ReturnToCallBack() extends ToSlave
/** Mu wants to call a native function. */
case class CallNative(sig: FuncSig, func: Word, args: Seq[ValueBox]) extends ToSlave
/** Mu wants to return to a native function. maybeRvb holds the return value. */
case class ReturnToNative(maybeRvb: Option[ValueBox]) extends ToSlave
/** Mu wants the slave to stop. */
case class Stop() extends ToSlave
}
......@@ -74,7 +80,8 @@ class NativeStackKeeper(implicit nativeCallHelper: NativeCallHelper) extends Poo
class Slave extends Runnable with PoorManAgent[ToSlave] {
def run(): Unit = {
while (true) {
@tailrec
def receiving(): Unit = {
val received = try {
receive()
} catch {
......@@ -83,12 +90,13 @@ class NativeStackKeeper(implicit nativeCallHelper: NativeCallHelper) extends Poo
return
}
received match {
case ToSlave.CallNative(sig, func, args, retBox) => {
nativeCallHelper.callNative(master, sig, func, args, retBox)
master.send(NativeCallResult.Return())
case ToSlave.CallNative(sig, func, args) => {
val maybeRvb = nativeCallHelper.callNative(master, sig, func, args)
master.send(NativeCallResult.ReturnToMu(maybeRvb))
receiving()
}
case ToSlave.ReturnToCallBack() => {
case ToSlave.ReturnToNative(maybeRvb) => {
throw new UvmNativeCallException("Attempt to return to native function, but no native function called back before")
}
......@@ -98,14 +106,17 @@ class NativeStackKeeper(implicit nativeCallHelper: NativeCallHelper) extends Poo
}
}
}
receiving()
}
def onCallBack(func: MFunc, cookie: Long, args: Seq[ValueBox], maybeRetBox: Option[ValueBox]): Unit = {
def onCallBack(func: MFunc, cookie: Long, args: Seq[ValueBox]): Option[ValueBox] = {
logger.debug("sending master the CallBack message...")
master.send(NativeCallResult.CallBack(func, cookie, args, maybeRetBox))
master.send(NativeCallResult.CallMu(func, cookie, args))
logger.debug("msg sent. Waiting for master's reply...")
try {
while (true) {
@tailrec
def receiving(): Option[ValueBox] = {
val received = try {
receive()
} catch {
......@@ -116,13 +127,14 @@ class NativeStackKeeper(implicit nativeCallHelper: NativeCallHelper) extends Poo
throw e
}
received match {
case ToSlave.CallNative(sig, func, args, retBox) => {
nativeCallHelper.callNative(master, sig, func, args, retBox)
master.send(NativeCallResult.Return())
case ToSlave.CallNative(sig, func, args) => {
val maybeRvb = nativeCallHelper.callNative(master, sig, func, args)
master.send(NativeCallResult.ReturnToMu(maybeRvb))
receiving()
}
case ToSlave.ReturnToCallBack() => {
return
case ToSlave.ReturnToNative(maybeRvb) => {
maybeRvb
}
case ToSlave.Stop() => {
......@@ -132,15 +144,15 @@ class NativeStackKeeper(implicit nativeCallHelper: NativeCallHelper) extends Poo
throw new UvmNativeCallException(msg)
}
}
}
receiving()
} catch {
case e: Throwable =>
logger.debug("Exception occured in the slave thread when there are native threads alive. " +
"Prepare for undefined behaviours in native frames (or JVM frames if the native calls back again).", e)
throw e
}
logger.debug("returning...")
}
}
......@@ -148,14 +160,14 @@ class NativeStackKeeper(implicit nativeCallHelper: NativeCallHelper) extends Poo
val slaveThread = new Thread(slave)
slaveThread.start()
def callNative(sig: FuncSig, func: Word, args: Seq[ValueBox], retBox: ValueBox): NativeCallResult = {
slave.send(ToSlave.CallNative(sig, func, args, retBox))
def callNative(sig: FuncSig, func: Word, args: Seq[ValueBox]): NativeCallResult = {
slave.send(ToSlave.CallNative(sig, func, args))
val result = receive()
result
}
def returnToCallBack(): NativeCallResult = {
slave.send(ToSlave.ReturnToCallBack())
def returnToNative(maybeRvBox: Option[ValueBox]): NativeCallResult = {
slave.send(ToSlave.ReturnToNative(maybeRvBox))
val result = receive()
result
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment