To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit ff938bc6 authored by Kunshan Wang's avatar Kunshan Wang
Browse files

Refactored common operations out of ClientAgent.

parent 663822a2
...@@ -245,59 +245,10 @@ class ClientAgent(microVM: MicroVM) { ...@@ -245,59 +245,10 @@ class ClientAgent(microVM: MicroVM) {
val uty = InternalTypePool.unmarkedOf(ty) val uty = InternalTypePool.unmarkedOf(ty)
val b = loc.vb.asInstanceOf[BoxIRef] val b = loc.vb.asInstanceOf[BoxIRef]
val iRef = b.objRef + b.offset val iRef = b.objRef + b.offset
val nb = uty match { val nb = ValueBox.makeBoxForType(uty)
case TypeInt(l) =>
val bi: BigInt = l match { MemoryOperations.load(uty, iRef, nb, microVM)
case 8 => MemorySupport.loadByte(iRef)
case 16 => MemorySupport.loadShort(iRef)
case 32 => MemorySupport.loadInt(iRef)
case 64 => MemorySupport.loadLong(iRef)
case _ => throw new UnimplementedOprationException("Loading int of length %d is not supported".format(l))
}
BoxInt(OpHelper.unprepare(bi, l))
case _: TypeFloat =>
val fv = MemorySupport.loadFloat(iRef)
BoxFloat(fv)
case _: TypeDouble =>
val dv = MemorySupport.loadDouble(iRef)
BoxDouble(dv)
case _: TypeRef =>
val addr = MemorySupport.loadLong(iRef)
BoxRef(addr)
case _: TypeIRef =>
val base = MemorySupport.loadLong(iRef)
val offset = MemorySupport.loadLong(iRef + WORD_SIZE_BYTES)
BoxIRef(base, offset)
case _: TypeFunc =>
val fid = MemorySupport.loadLong(iRef).toInt
val func = microVM.globalBundle.funcNs.get(fid)
BoxFunc(func)
case _: TypeThread =>
val tid = MemorySupport.loadLong(iRef).toInt
val thr = microVM.threadStackManager.getThreadByID(tid)
BoxThread(thr)
case _: TypeStack =>
val sid = MemorySupport.loadLong(iRef).toInt
val sta = microVM.threadStackManager.getStackByID(sid)
BoxStack(sta)
case _: TypeTagRef64 =>
val raw = MemorySupport.loadLong(iRef)
BoxTagRef64(raw)
case TypeVector(ety, len) =>
ety match {
case TypeInt(32) =>
val vs = for (i <- (0L until len)) yield MemorySupport.loadInt(iRef + i * 4L)
BoxVector(vs.map(v => BoxInt(OpHelper.unprepare(v, 32))))
case _: TypeFloat =>
val vs = for (i <- (0L until len)) yield MemorySupport.loadFloat(iRef + i * 4L)
BoxVector(vs.map(v => BoxFloat(v)))
case _: TypeDouble =>
val vs = for (i <- (0L until len)) yield MemorySupport.loadDouble(iRef + i * 8L)
BoxVector(vs.map(v => BoxDouble(v)))
case _ => throw new UnimplementedOprationException("Loading of vector type with element type %s is not supporing".format(ety.getClass.getName))
}
case _ => throw new UnimplementedOprationException("Loading of type %s is not supporing".format(uty.getClass.getName))
}
newHandle(uty, nb) newHandle(uty, nb)
} }
...@@ -306,56 +257,10 @@ class ClientAgent(microVM: MicroVM) { ...@@ -306,56 +257,10 @@ class ClientAgent(microVM: MicroVM) {
val uty = InternalTypePool.unmarkedOf(ty) val uty = InternalTypePool.unmarkedOf(ty)
val lb = loc.vb.asInstanceOf[BoxIRef] val lb = loc.vb.asInstanceOf[BoxIRef]
val iRef = lb.objRef + lb.offset val iRef = lb.objRef + lb.offset
val nvb = newVal.vb val nvb = newVal.vb
uty match { val nb = ValueBox.makeBoxForType(uty)
case TypeInt(l) =>
val bi = nvb.asInstanceOf[BoxInt].value MemoryOperations.store(uty, iRef, nvb, nb, microVM)
l match {
case 8 => MemorySupport.storeByte(iRef, bi.byteValue)
case 16 => MemorySupport.storeShort(iRef, bi.shortValue)
case 32 => MemorySupport.storeInt(iRef, bi.intValue)
case 64 => MemorySupport.storeLong(iRef, bi.longValue)
case _ => throw new UnimplementedOprationException("Storing int of length %d is not supported".format(l))
}
BoxInt(OpHelper.unprepare(bi, l))
case _: TypeFloat =>
val fv = nvb.asInstanceOf[BoxFloat].value
MemorySupport.storeFloat(iRef, fv)
case _: TypeDouble =>
val dv = nvb.asInstanceOf[BoxDouble].value
MemorySupport.storeDouble(iRef, dv)
case _: TypeRef =>
val addr = nvb.asInstanceOf[BoxRef].objRef
MemorySupport.storeLong(iRef, addr)
case _: TypeIRef =>
val BoxIRef(base, offset) = nvb.asInstanceOf[BoxIRef]
MemorySupport.storeLong(iRef, base)
MemorySupport.storeLong(iRef + WORD_SIZE_BYTES, offset)
case _: TypeFunc =>
val fid = nvb.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0)
MemorySupport.storeLong(iRef, fid.toLong & 0xFFFFFFFFL)
case _: TypeThread =>
val tid = nvb.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0)
MemorySupport.storeLong(iRef, tid.toLong & 0xFFFFFFFFL)
case _: TypeStack =>
val sid = nvb.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0)
MemorySupport.storeLong(iRef, sid.toLong & 0xFFFFFFFFL)
case _: TypeTagRef64 =>
val raw = nvb.asInstanceOf[BoxTagRef64].raw
MemorySupport.storeLong(iRef, raw)
case TypeVector(ety, len) =>
val vbs = nvb.asInstanceOf[BoxVector].values
ety match {
case TypeInt(32) =>
for (i <- (0L until len)) MemorySupport.storeInt(iRef + i * 4L, vbs(i.toInt).asInstanceOf[BoxInt].value.intValue)
case _: TypeFloat =>
for (i <- (0L until len)) MemorySupport.storeFloat(iRef + i * 4L, vbs(i.toInt).asInstanceOf[BoxFloat].value)
case _: TypeDouble =>
for (i <- (0L until len)) MemorySupport.storeDouble(iRef + i * 8L, vbs(i.toInt).asInstanceOf[BoxDouble].value)
case _ => throw new UnimplementedOprationException("Storing of vector type with element type %s is not supporing".format(ety.getClass.getName))
}
case _ => throw new UnimplementedOprationException("Storing of type %s is not supporing".format(uty.getClass.getName))
}
} }
def cmpXchg(ordSucc: MemoryOrder, ordFail: MemoryOrder, weak: Boolean, loc: Handle, expected: Handle, desired: Handle): (Boolean, Handle) = { def cmpXchg(ordSucc: MemoryOrder, ordFail: MemoryOrder, weak: Boolean, loc: Handle, expected: Handle, desired: Handle): (Boolean, Handle) = {
...@@ -365,59 +270,9 @@ class ClientAgent(microVM: MicroVM) { ...@@ -365,59 +270,9 @@ class ClientAgent(microVM: MicroVM) {
val iRef = lb.objRef + lb.offset val iRef = lb.objRef + lb.offset
val eb = expected.vb val eb = expected.vb
val db = desired.vb val db = desired.vb
uty match { val br = ValueBox.makeBoxForType(uty)
case TypeInt(l) => val succ = MemoryOperations.cmpXchg(uty, iRef, eb, db, br, microVM)
val ebi = eb.asInstanceOf[BoxInt].value (succ, newHandle(uty, br))
val dbi = db.asInstanceOf[BoxInt].value
val (succ, rbi) = l match {
case 32 => {
val (succ2, rv) = MemorySupport.cmpXchgInt(iRef, ebi.intValue, dbi.intValue)
(succ2, BigInt(rv))
}
case 64 => {
val (succ2, rv) = MemorySupport.cmpXchgLong(iRef, ebi.longValue, dbi.longValue)
(succ2, BigInt(rv))
}
case _ => throw new UnimplementedOprationException("CmpXchg on int of length %d is not supported".format(l))
}
val rb = BoxInt(OpHelper.unprepare(rbi, l))
val rh = newHandle(uty, rb)
(succ, rh)
case _: TypeRef =>
val el = eb.asInstanceOf[BoxRef].objRef
val dl = db.asInstanceOf[BoxRef].objRef
val (succ, rl) = MemorySupport.cmpXchgLong(iRef, el, dl)
val rh = newHandle(uty, BoxRef(rl))
(succ, rh)
case _: TypeIRef =>
val BoxIRef(el, eh) = eb.asInstanceOf[BoxIRef]
val BoxIRef(dl, dh) = db.asInstanceOf[BoxIRef]
val (succ, (rl, rh)) = MemorySupport.cmpXchgI128(iRef, (el, eh), (dl, dh))
val rhdl = newHandle(uty, BoxIRef(rl, rh))
(succ, rhdl)
case _: TypeFunc =>
val el = eb.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0).toLong
val dl = db.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0).toLong
val (succ, rl) = MemorySupport.cmpXchgLong(iRef, el, dl)
val rf = microVM.globalBundle.funcNs.get(rl.toInt)
val rh = newHandle(uty, BoxFunc(rf))
(succ, rh)
case _: TypeThread =>
val el = eb.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0).toLong
val dl = db.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0).toLong
val (succ, rl) = MemorySupport.cmpXchgLong(iRef, el, dl)
val rt = microVM.threadStackManager.getThreadByID(rl.toInt)
val rh = newHandle(uty, BoxThread(rt))
(succ, rh)
case _: TypeStack =>
val el = eb.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0).toLong
val dl = db.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0).toLong
val (succ, rl) = MemorySupport.cmpXchgLong(iRef, el, dl)
val rs = microVM.threadStackManager.getStackByID(rl.toInt)
val rh = newHandle(uty, BoxStack(rs))
(succ, rh)
case _ => throw new UnimplementedOprationException("CmpXchg of type %s is not supporing".format(uty.getClass.getName))
}
} }
def atomicRMW(ord: MemoryOrder, op: AtomicRMWOptr, loc: Handle, opnd: Handle): Handle = { def atomicRMW(ord: MemoryOrder, op: AtomicRMWOptr, loc: Handle, opnd: Handle): Handle = {
...@@ -426,57 +281,9 @@ class ClientAgent(microVM: MicroVM) { ...@@ -426,57 +281,9 @@ class ClientAgent(microVM: MicroVM) {
val lb = loc.vb.asInstanceOf[BoxIRef] val lb = loc.vb.asInstanceOf[BoxIRef]
val iRef = lb.objRef + lb.offset val iRef = lb.objRef + lb.offset
val ob = opnd.vb val ob = opnd.vb
uty match { val br = ValueBox.makeBoxForType(uty)
case TypeInt(l) => MemoryOperations.atomicRMW(uty, op, iRef, ob, br, microVM)
val obi = ob.asInstanceOf[BoxInt].value newHandle(uty, br)
val rbi: BigInt = l match {
case 32 => {
MemorySupport.atomicRMWInt(op, iRef, obi.intValue)
}
case 64 => {
MemorySupport.atomicRMWLong(op, iRef, obi.longValue)
}
case _ => throw new UnimplementedOprationException("AtomicRMW on int of length %d is not supported".format(l))
}
val rb = BoxInt(OpHelper.unprepare(rbi, l))
newHandle(uty, rb)
case _ =>
if (op != XCHG) {
throw new UnimplementedOprationException("AtomicRMW operation other than XCHG only supports int. %s found.".format(uty.getClass.getName))
} else {
uty match {
case _: TypeRef =>
val ol = ob.asInstanceOf[BoxRef].objRef
val rl = MemorySupport.atomicRMWLong(op, iRef, ol)
newHandle(uty, BoxRef(rl))
case _: TypeIRef =>
val BoxIRef(ol, oh) = ob.asInstanceOf[BoxIRef]
val (rl, rh) = MemorySupport.xchgI128(iRef, (ol, oh))
newHandle(uty, BoxIRef(rl, rh))
case _: TypeFunc =>
val ol = ob.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0).toLong
val rl = MemorySupport.atomicRMWLong(op, iRef, ol)
val rf = microVM.globalBundle.funcNs.get(rl.toInt)
newHandle(uty, BoxFunc(rf))
case _: TypeThread =>
val ol = ob.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0).toLong
val rl = MemorySupport.atomicRMWLong(op, iRef, ol)
val rt = microVM.threadStackManager.getThreadByID(rl.toInt)
newHandle(uty, BoxThread(rt))
case _: TypeStack =>
val ol = ob.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0).toLong
val rl = MemorySupport.atomicRMWLong(op, iRef, ol)
val rs = microVM.threadStackManager.getStackByID(rl.toInt)
newHandle(uty, BoxStack(rs))
case _: TypeTagRef64 =>
val ol = ob.asInstanceOf[BoxTagRef64].raw
val rl = MemorySupport.atomicRMWLong(op, iRef, ol)
newHandle(uty, BoxTagRef64(rl))
case _ =>
throw new UnimplementedOprationException("AtomicRMW XCHG of type %s is not supporing".format(uty.getClass.getName))
}
}
}
} }
def fence(ord: MemoryOrder): Unit = { def fence(ord: MemoryOrder): Unit = {
......
...@@ -48,6 +48,10 @@ case class BoxIRef(var objRef: Word, var offset: Word) extends HasObjRef { ...@@ -48,6 +48,10 @@ case class BoxIRef(var objRef: Word, var offset: Word) extends HasObjRef {
def hasObjRef() = objRef != 0 def hasObjRef() = objRef != 0
def getObjRef() = objRef def getObjRef() = objRef
def setObjRef(newObjRef: Word): Unit = { objRef = newObjRef } def setObjRef(newObjRef: Word): Unit = { objRef = newObjRef }
// Helper to get and set the objRef and offset at the same time
def oo: (Word, Word) = (objRef, offset)
def oo_=(newVal: (Word, Word)): Unit = { objRef = newVal._1; offset = newVal._2 }
} }
case class BoxStruct(var values: Seq[ValueBox]) extends ValueBox { case class BoxStruct(var values: Seq[ValueBox]) extends ValueBox {
def copyFrom(other: ValueBox): Unit = { for ((t, o) <- this.values.zip(other.asInstanceOf[BoxStruct].values)) t.copyFrom(o) } def copyFrom(other: ValueBox): Unit = { for ((t, o) <- this.values.zip(other.asInstanceOf[BoxStruct].values)) t.copyFrom(o) }
......
package uvm.refimpl.itpr package uvm.refimpl.itpr
import uvm.types._
import uvm.ssavariables._ import uvm.ssavariables._
import uvm.refimpl._ import uvm.refimpl._
import uvm.refimpl.mem.TypeSizes._
import uvm.refimpl.mem.MemorySupport
import AtomicRMWOptr._
object OpHelper { object OpHelper {
...@@ -81,7 +85,7 @@ object OpHelper { ...@@ -81,7 +85,7 @@ object OpHelper {
val lExp = Math.getExponent(n) val lExp = Math.getExponent(n)
val rExp = lExp - 52 val rExp = lExp - 52
val frac = (java.lang.Double.doubleToRawLongBits(n) & 0xfffffffffffffL) | 0x10000000000000L; val frac = (java.lang.Double.doubleToRawLongBits(n) & 0xfffffffffffffL) | 0x10000000000000L;
if (java.lang.Double.isNaN(n)) 0 if (java.lang.Double.isNaN(n)) 0
else if (signed) { else if (signed) {
if (java.lang.Double.isInfinite(n)) { if (n > 0.0D) maxSInt(iLen) else minSIntAbs(iLen) } if (java.lang.Double.isInfinite(n)) { if (n > 0.0D) maxSInt(iLen) else minSIntAbs(iLen) }
...@@ -278,9 +282,216 @@ object PrimOpHelpers { ...@@ -278,9 +282,216 @@ object PrimOpHelpers {
} }
} }
object AggregateOperations { object MemoryOperations {
def extractValue(boxStr: BoxStruct, index: Int, boxResult: ValueBox): Unit = { def load(ty: Type, loc: Word, br: ValueBox, microVM: MicroVM): Unit = {
def loadScalar(ty: Type, loc: Word, br: ValueBox): Unit = ty match {
case TypeInt(l) =>
val bi: BigInt = l match {
case 8 => MemorySupport.loadByte(loc)
case 16 => MemorySupport.loadShort(loc)
case 32 => MemorySupport.loadInt(loc)
case 64 => MemorySupport.loadLong(loc)
case _ => throw new UnimplementedOprationException("Loading int of length %d is not supported".format(l))
}
br.asInstanceOf[BoxInt].value = OpHelper.unprepare(bi, l)
case _: TypeFloat =>
val fv = MemorySupport.loadFloat(loc)
br.asInstanceOf[BoxFloat].value = fv
case _: TypeDouble =>
val dv = MemorySupport.loadDouble(loc)
br.asInstanceOf[BoxDouble].value = dv
case _: TypeRef =>
val addr = MemorySupport.loadLong(loc)
br.asInstanceOf[BoxRef].objRef = addr
case _: TypeIRef =>
val base = MemorySupport.loadLong(loc)
val offset = MemorySupport.loadLong(loc + WORD_SIZE_BYTES)
br.asInstanceOf[BoxIRef].oo = (base, offset)
case _: TypeFunc =>
val fid = MemorySupport.loadLong(loc).toInt
val func = microVM.globalBundle.funcNs.get(fid)
br.asInstanceOf[BoxFunc].func = func
case _: TypeThread =>
val tid = MemorySupport.loadLong(loc).toInt
val thr = microVM.threadStackManager.getThreadByID(tid)
br.asInstanceOf[BoxThread].thread = thr
case _: TypeStack =>
val sid = MemorySupport.loadLong(loc).toInt
val sta = microVM.threadStackManager.getStackByID(sid)
br.asInstanceOf[BoxStack].stack = sta
case _: TypeTagRef64 =>
val raw = MemorySupport.loadLong(loc)
br.asInstanceOf[BoxTagRef64].raw = raw
case _ => throw new UnimplementedOprationException("Loading of type %s is not supporing".format(ty.getClass.getName))
}
ty match {
case TypeVector(ety, len) =>
val brs = br.asInstanceOf[BoxVector].values
val elemSkip = alignUp(sizeOf(ety), alignOf(ety))
for ((brElem, i) <- brs.zipWithIndex) {
loadScalar(ety, loc + elemSkip * i, brElem)
}
case sty => loadScalar(sty, loc, br)
}
}
def store(ty: Type, loc: Word, nvb: ValueBox, br: ValueBox, microVM: MicroVM): Unit = {
def storeScalar(ty: Type, loc: Word, nvb: ValueBox, br: ValueBox): Unit = ty match {
case TypeInt(l) =>
val bi = nvb.asInstanceOf[BoxInt].value
l match {
case 8 => MemorySupport.storeByte(loc, bi.byteValue)
case 16 => MemorySupport.storeShort(loc, bi.shortValue)
case 32 => MemorySupport.storeInt(loc, bi.intValue)
case 64 => MemorySupport.storeLong(loc, bi.longValue)
case _ => throw new UnimplementedOprationException("Storing int of length %d is not supported".format(l))
}
case _: TypeFloat =>
val fv = nvb.asInstanceOf[BoxFloat].value
MemorySupport.storeFloat(loc, fv)
case _: TypeDouble =>
val dv = nvb.asInstanceOf[BoxDouble].value
MemorySupport.storeDouble(loc, dv)
case _: TypeRef =>
val addr = nvb.asInstanceOf[BoxRef].objRef
MemorySupport.storeLong(loc, addr)
case _: TypeIRef =>
val BoxIRef(base, offset) = nvb.asInstanceOf[BoxIRef]
MemorySupport.storeLong(loc, base)
MemorySupport.storeLong(loc + WORD_SIZE_BYTES, offset)
case _: TypeFunc =>
val fid = nvb.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0)
MemorySupport.storeLong(loc, fid.toLong & 0xFFFFFFFFL)
case _: TypeThread =>
val tid = nvb.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0)
MemorySupport.storeLong(loc, tid.toLong & 0xFFFFFFFFL)
case _: TypeStack =>
val sid = nvb.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0)
MemorySupport.storeLong(loc, sid.toLong & 0xFFFFFFFFL)
case _: TypeTagRef64 =>
val raw = nvb.asInstanceOf[BoxTagRef64].raw
MemorySupport.storeLong(loc, raw)
case _ => throw new UnimplementedOprationException("Storing of type %s is not supporing".format(ty.getClass.getName))
}
ty match {
case TypeVector(ety, len) =>
val nvbs = nvb.asInstanceOf[BoxVector].values
val brs = br.asInstanceOf[BoxVector].values
val elemSkip = alignUp(sizeOf(ety), alignOf(ety))
for (((brElem, nvbElem), i) <- (brs zip nvbs).zipWithIndex) {
storeScalar(ety, loc + elemSkip * i, nvbElem, brElem)
}
case sty => storeScalar(sty, loc, nvb, br)
}
}
/**
* Compare exchange. The result (the old value) is written into br. Return true if successful, false otherwise.
*/
def cmpXchg(ty: Type, loc: Word, eb: ValueBox, db: ValueBox, br: ValueBox, microVM: MicroVM): Boolean = {
ty match {
case TypeInt(l) =>
val ebi = eb.asInstanceOf[BoxInt].value
val dbi = db.asInstanceOf[BoxInt].value
val (succ, rbi) = l match {
case 32 => {
val (succ2, rv) = MemorySupport.cmpXchgInt(loc, ebi.intValue, dbi.intValue)
(succ2, BigInt(rv))
}
case 64 => {
val (succ2, rv) = MemorySupport.cmpXchgLong(loc, ebi.longValue, dbi.longValue)
(succ2, BigInt(rv))
}
case _ => throw new UnimplementedOprationException("CmpXchg on int of length %d is not supported".format(l))
}
br.asInstanceOf[BoxInt].value = OpHelper.unprepare(rbi, l)
succ
case _: TypeRef =>
val el = eb.asInstanceOf[BoxRef].objRef
val dl = db.asInstanceOf[BoxRef].objRef
val (succ, rl) = MemorySupport.cmpXchgLong(loc, el, dl)
br.asInstanceOf[BoxRef].objRef = rl
succ
case _: TypeIRef =>
val BoxIRef(el, eh) = eb.asInstanceOf[BoxIRef]
val BoxIRef(dl, dh) = db.asInstanceOf[BoxIRef]
val (succ, (rl, rh)) = MemorySupport.cmpXchgI128(loc, (el, eh), (dl, dh))
br.asInstanceOf[BoxIRef].oo = (rl, rh)
succ
case _: TypeFunc =>
val el = eb.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0).toLong
val dl = db.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0).toLong
val (succ, rl) = MemorySupport.cmpXchgLong(loc, el, dl)
val rf = microVM.globalBundle.funcNs.get(rl.toInt)
br.asInstanceOf[BoxFunc].func = rf
succ
case _: TypeThread =>
val el = eb.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0).toLong
val dl = db.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0).toLong
val (succ, rl) = MemorySupport.cmpXchgLong(loc, el, dl)
val rt = microVM.threadStackManager.getThreadByID(rl.toInt)
br.asInstanceOf[BoxThread].thread = rt
succ
case _: TypeStack =>
val el = eb.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0).toLong
val dl = db.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0).toLong
val (succ, rl) = MemorySupport.cmpXchgLong(loc, el, dl)
val rs = microVM.threadStackManager.getStackByID(rl.toInt)
br.asInstanceOf[BoxStack].stack = rs
succ
case _ => throw new UnimplementedOprationException("CmpXchg of type %s is not supporing".format(ty.getClass.getName))
}
}
def atomicRMW(ty: Type, op: AtomicRMWOptr, loc: Word, ob: ValueBox, br: ValueBox, microVM: MicroVM): Unit = {
ty match {
case TypeInt(l) =>
val obi = ob.asInstanceOf[BoxInt].value
val rbi: BigInt = l match {
case 32 => MemorySupport.atomicRMWInt(op, loc, obi.intValue)
case 64 => MemorySupport.atomicRMWLong(op, loc, obi.longValue)
case _ => throw new UnimplementedOprationException("AtomicRMW on int of length %d is not supported".format(l))
}
br.asInstanceOf[BoxInt].value = OpHelper.unprepare(rbi, l)
case _ =>
if (op != XCHG) {
throw new UnimplementedOprationException("AtomicRMW operation other than XCHG only supports int. %s found.".format(ty.getClass.getName))
} else {
ty match {
case _: TypeRef =>
val ol = ob.asInstanceOf[BoxRef].objRef
val rl = MemorySupport.atomicRMWLong(op, loc, ol)
br.asInstanceOf[BoxRef].objRef = rl
case _: TypeIRef =>
val BoxIRef(ol, oh) = ob.asInstanceOf[BoxIRef]
val (rl, rh) = MemorySupport.xchgI128(loc, (ol, oh))
br.asInstanceOf[BoxIRef].oo = (rl, rh)
case _: TypeFunc =>
val ol = ob.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0).toLong
val rl = MemorySupport.atomicRMWLong(op, loc, ol)
val rf = microVM.globalBundle.funcNs.get(rl.toInt)
br.asInstanceOf[BoxFunc].func = rf
case _: TypeThread =>
val ol = ob.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0).toLong
val rl = MemorySupport.atomicRMWLong(op, loc, ol)
val rt = microVM.threadStackManager.getThreadByID(rl.toInt)
br.asInstanceOf[BoxThread].thread = rt
case _: TypeStack =>
val ol = ob.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0).toLong
val rl = MemorySupport.atomicRMWLong(op, loc, ol)
val rs = microVM.threadStackManager.getStackByID(rl.toInt)
br.asInstanceOf[BoxStack].stack = rs
case _: TypeTagRef64 =>
val ol = ob.asInstanceOf[BoxTagRef64].raw
val rl = MemorySupport.atomicRMWLong(op, loc, ol)
br.asInstanceOf[BoxTagRef64].raw = rl
case _ =>
throw new UnimplementedOprationException("AtomicRMW XCHG of type %s is not supporing".format(ty.getClass.getName))
}
}
}
} }
} }
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