WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

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

MemoryOperations fix and refactor

Lifted xxxEntity outside match.

Fixed a bug in MemorySupport.cmpXchgEntity
parent 0bb90c20
......@@ -349,58 +349,58 @@ object MemoryOperations {
}
def load(ptr: Boolean, ty: Type, loc: Word, br: ValueBox)(implicit microVM: MicroVM, memorySupport: MemorySupport): 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, !ptr)
case 16 => memorySupport.loadShort(loc, !ptr)
case 32 => memorySupport.loadInt(loc, !ptr)
case 64 => memorySupport.loadLong(loc, !ptr)
case 128 => {
val lowWord = memorySupport.loadLong(loc, !ptr)
val highWord = memorySupport.loadLong(loc + 8, !ptr)
(BigInt(highWord) << 64) + lowWord
}
case _ => throw new UvmUnimplementedOperationException("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, !ptr)
br.asInstanceOf[BoxFloat].value = fv
case _: TypeDouble =>
val dv = memorySupport.loadDouble(loc, !ptr)
br.asInstanceOf[BoxDouble].value = dv
case _: AbstractPointerType =>
val addr = memorySupport.loadLong(loc, !ptr)
br.asInstanceOf[BoxPointer].addr = addr
case _: TypeRef =>
noAccessViaPointer(ptr, ty)
val addr = memorySupport.loadLong(loc)
br.asInstanceOf[BoxRef].objRef = addr
case _: TypeIRef =>
noAccessViaPointer(ptr, ty)
val base = memorySupport.loadLong(loc)
val offset = memorySupport.loadLong(loc + WORD_SIZE_BYTES)
br.asInstanceOf[BoxIRef].oo = (base, offset)
case _: TypeTagRef64 =>
noAccessViaPointer(ptr, ty)
val raw = memorySupport.loadLong(loc)
br.asInstanceOf[BoxTagRef64].raw = raw
case _: AbstractOpaqueRefType => {
def loadEntity[T: CanBeIntegerized](): Unit = {
val obj = memorySupport.loadEntity[T](loc)
br.asInstanceOf[BoxOpaque[T]].obj = obj
}
def loadScalar(ty: Type, loc: Word, br: ValueBox): Unit = {
def loadEntity[T: CanBeIntegerized](): Unit = {
noAccessViaPointer(ptr, ty)
ty match {
case _: TypeFuncRef => loadEntity[Function]()
case _: TypeThreadRef => loadEntity[InterpreterThread]()
case _: TypeStackRef => loadEntity[InterpreterStack]()
case _: TypeFrameCursorRef => loadEntity[FrameCursor]()
case _: TypeIRBuilderRef => loadEntity[IRBuilder]()
}
val obj = memorySupport.loadEntity[T](loc)
br.asInstanceOf[BoxOpaque[T]].obj = obj
}
ty match {
case TypeInt(l) =>
val bi: BigInt = l match {
case 8 => memorySupport.loadByte(loc, !ptr)
case 16 => memorySupport.loadShort(loc, !ptr)
case 32 => memorySupport.loadInt(loc, !ptr)
case 64 => memorySupport.loadLong(loc, !ptr)
case 128 => {
val lowWord = memorySupport.loadLong(loc, !ptr)
val highWord = memorySupport.loadLong(loc + 8, !ptr)
(BigInt(highWord) << 64) + lowWord
}
case _ => throw new UvmUnimplementedOperationException(
"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, !ptr)
br.asInstanceOf[BoxFloat].value = fv
case _: TypeDouble =>
val dv = memorySupport.loadDouble(loc, !ptr)
br.asInstanceOf[BoxDouble].value = dv
case _: AbstractPointerType =>
val addr = memorySupport.loadLong(loc, !ptr)
br.asInstanceOf[BoxPointer].addr = addr
case _: TypeRef =>
noAccessViaPointer(ptr, ty)
val addr = memorySupport.loadLong(loc)
br.asInstanceOf[BoxRef].objRef = addr
case _: TypeIRef =>
noAccessViaPointer(ptr, ty)
val base = memorySupport.loadLong(loc)
val offset = memorySupport.loadLong(loc + WORD_SIZE_BYTES)
br.asInstanceOf[BoxIRef].oo = (base, offset)
case _: TypeTagRef64 =>
noAccessViaPointer(ptr, ty)
val raw = memorySupport.loadLong(loc)
br.asInstanceOf[BoxTagRef64].raw = raw
case _: TypeFuncRef => loadEntity[Function]()
case _: TypeThreadRef => loadEntity[InterpreterThread]()
case _: TypeStackRef => loadEntity[InterpreterStack]()
case _: TypeFrameCursorRef => loadEntity[FrameCursor]()
case _: TypeIRBuilderRef => loadEntity[IRBuilder]()
case _ => throw new UvmUnimplementedOperationException(
"Loading of type %s is not supported".format(ty.getClass.getName))
}
case _ => throw new UvmUnimplementedOperationException("Loading of type %s is not supporing".format(ty.getClass.getName))
}
ty match {
......@@ -415,57 +415,57 @@ object MemoryOperations {
}
def store(ptr: Boolean, ty: Type, loc: Word, nvb: ValueBox)(implicit microVM: MicroVM, 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 {
case 8 => memorySupport.storeByte(loc, bi.byteValue, !ptr)
case 16 => memorySupport.storeShort(loc, bi.shortValue, !ptr)
case 32 => memorySupport.storeInt(loc, bi.intValue, !ptr)
case 64 => memorySupport.storeLong(loc, bi.longValue, !ptr)
case 128 => {
memorySupport.storeLong(loc, (bi & 0xffffffffffffffffL).longValue, !ptr)
memorySupport.storeLong(loc + 8, (bi >> 64).longValue, !ptr)
}
case _ => throw new UvmUnimplementedOperationException("Storing int of length %d is not supported".format(l))
}
case _: TypeFloat =>
val fv = nvb.asInstanceOf[BoxFloat].value
memorySupport.storeFloat(loc, fv, !ptr)
case _: TypeDouble =>
val dv = nvb.asInstanceOf[BoxDouble].value
memorySupport.storeDouble(loc, dv, !ptr)
case _: AbstractPointerType =>
val addr = nvb.asInstanceOf[BoxPointer].addr
memorySupport.storeLong(loc, addr, !ptr)
case _: TypeRef =>
noAccessViaPointer(ptr, ty)
val addr = nvb.asInstanceOf[BoxRef].objRef
memorySupport.storeLong(loc, addr)
case _: TypeIRef =>
def storeScalar(ty: Type, loc: Word, nvb: ValueBox): Unit = {
def storeEntity[T: CanBeIntegerized](): Unit = {
noAccessViaPointer(ptr, ty)
val BoxIRef(base, offset) = nvb.asInstanceOf[BoxIRef]
memorySupport.storeLong(loc, base)
memorySupport.storeLong(loc + WORD_SIZE_BYTES, offset)
case _: TypeTagRef64 =>
noAccessViaPointer(ptr, ty)
val raw = nvb.asInstanceOf[BoxTagRef64].raw
memorySupport.storeLong(loc, raw)
case _: AbstractOpaqueRefType => {
def storeEntity[T: CanBeIntegerized](): Unit = {
val obj = nvb.asInstanceOf[BoxOpaque[T]].obj
memorySupport.storeEntity[T](loc, obj)
}
noAccessViaPointer(ptr, ty)
ty match {
case _: TypeFuncRef => storeEntity[Function]()
case _: TypeThreadRef => storeEntity[InterpreterThread]()
case _: TypeStackRef => storeEntity[InterpreterStack]()
case _: TypeFrameCursorRef => storeEntity[FrameCursor]()
case _: TypeIRBuilderRef => storeEntity[IRBuilder]()
}
val obj = nvb.asInstanceOf[BoxOpaque[T]].obj
memorySupport.storeEntity[T](loc, obj)
}
ty match {
case TypeInt(l) =>
val bi = nvb.asInstanceOf[BoxInt].value
l match {
case 8 => memorySupport.storeByte(loc, bi.byteValue, !ptr)
case 16 => memorySupport.storeShort(loc, bi.shortValue, !ptr)
case 32 => memorySupport.storeInt(loc, bi.intValue, !ptr)
case 64 => memorySupport.storeLong(loc, bi.longValue, !ptr)
case 128 => {
memorySupport.storeLong(loc, (bi & 0xffffffffffffffffL).longValue, !ptr)
memorySupport.storeLong(loc + 8, (bi >> 64).longValue, !ptr)
}
case _ => throw new UvmUnimplementedOperationException(
"Storing int of length %d is not supported".format(l))
}
case _: TypeFloat =>
val fv = nvb.asInstanceOf[BoxFloat].value
memorySupport.storeFloat(loc, fv, !ptr)
case _: TypeDouble =>
val dv = nvb.asInstanceOf[BoxDouble].value
memorySupport.storeDouble(loc, dv, !ptr)
case _: AbstractPointerType =>
val addr = nvb.asInstanceOf[BoxPointer].addr
memorySupport.storeLong(loc, addr, !ptr)
case _: TypeRef =>
noAccessViaPointer(ptr, ty)
val addr = nvb.asInstanceOf[BoxRef].objRef
memorySupport.storeLong(loc, addr)
case _: TypeIRef =>
noAccessViaPointer(ptr, ty)
val BoxIRef(base, offset) = nvb.asInstanceOf[BoxIRef]
memorySupport.storeLong(loc, base)
memorySupport.storeLong(loc + WORD_SIZE_BYTES, offset)
case _: TypeTagRef64 =>
noAccessViaPointer(ptr, ty)
val raw = nvb.asInstanceOf[BoxTagRef64].raw
memorySupport.storeLong(loc, raw)
case _: TypeFuncRef => storeEntity[Function]()
case _: TypeThreadRef => storeEntity[InterpreterThread]()
case _: TypeStackRef => storeEntity[InterpreterStack]()
case _: TypeFrameCursorRef => storeEntity[FrameCursor]()
case _: TypeIRBuilderRef => storeEntity[IRBuilder]()
case _ => throw new UvmUnimplementedOperationException(
"Storing of type %s is not supported".format(ty.getClass.getName))
}
case _ => throw new UvmUnimplementedOperationException("Storing of type %s is not supporing".format(ty.getClass.getName))
}
ty match {
......@@ -483,6 +483,14 @@ object MemoryOperations {
* Compare exchange. The result (the old value) is written into br. Return true if successful, false otherwise.
*/
def cmpXchg(ptr: Boolean, ty: Type, loc: Word, eb: ValueBox, db: ValueBox, br: ValueBox)(implicit microVM: MicroVM, memorySupport: MemorySupport): Boolean = {
def cmpXchgEntity[T: CanBeIntegerized](): Boolean = {
noAccessViaPointer(ptr, ty)
val eObj = eb.asInstanceOf[BoxOpaque[T]].obj
val dObj = db.asInstanceOf[BoxOpaque[T]].obj
val (succ, rObj) = memorySupport.cmpXchgEntity(loc, eObj, dObj)
br.asInstanceOf[BoxOpaque[T]].obj = rObj
succ
}
ty match {
case TypeInt(l) =>
val ebi = eb.asInstanceOf[BoxInt].value
......@@ -520,24 +528,13 @@ object MemoryOperations {
val (succ, (rl, rh)) = memorySupport.cmpXchgI128(loc, (el, eh), (dl, dh))
br.asInstanceOf[BoxIRef].oo = (rl, rh)
succ
case _: AbstractOpaqueRefType => {
def cmpXchgEntity[T: CanBeIntegerized](): Boolean = {
val eObj = eb.asInstanceOf[BoxOpaque[T]].obj
val dObj = db.asInstanceOf[BoxOpaque[T]].obj
val (succ, rObj) = memorySupport.cmpXchgEntity(loc, eObj, dObj)
br.asInstanceOf[BoxOpaque[T]].obj = rObj
succ
}
noAccessViaPointer(ptr, ty)
ty match {
case _: TypeFuncRef => cmpXchgEntity[Function]()
case _: TypeThreadRef => cmpXchgEntity[InterpreterThread]()
case _: TypeStackRef => cmpXchgEntity[InterpreterStack]()
case _: TypeFrameCursorRef => cmpXchgEntity[FrameCursor]()
case _: TypeIRBuilderRef => cmpXchgEntity[IRBuilder]()
}
}
case _ => throw new UvmUnimplementedOperationException("CmpXchg of type %s is not supporing".format(ty.getClass.getName))
case _: TypeFuncRef => cmpXchgEntity[Function]()
case _: TypeThreadRef => cmpXchgEntity[InterpreterThread]()
case _: TypeStackRef => cmpXchgEntity[InterpreterStack]()
case _: TypeFrameCursorRef => cmpXchgEntity[FrameCursor]()
case _: TypeIRBuilderRef => cmpXchgEntity[IRBuilder]()
case _ => throw new UvmUnimplementedOperationException(
"CmpXchg of type %s is not suppored".format(ty.getClass.getName))
}
}
......@@ -555,6 +552,12 @@ object MemoryOperations {
if (op != XCHG) {
throw new UvmUnimplementedOperationException("AtomicRMW operation other than XCHG only supports int. %s found.".format(ty.getClass.getName))
} else {
def xchgEntity[T: CanBeIntegerized](): Unit = {
noAccessViaPointer(ptr, ty)
val obj = ob.asInstanceOf[BoxOpaque[T]].obj
val oldObj = memorySupport.xchgEntity(loc, obj)
br.asInstanceOf[BoxOpaque[T]].obj = oldObj
}
ty match {
case _: AbstractPointerType =>
val ol = ob.asInstanceOf[BoxPointer].addr
......@@ -570,21 +573,11 @@ object MemoryOperations {
val BoxIRef(ol, oh) = ob.asInstanceOf[BoxIRef]
val (rl, rh) = memorySupport.xchgI128(loc, (ol, oh))
br.asInstanceOf[BoxIRef].oo = (rl, rh)
case _: AbstractOpaqueRefType => {
def xchgEntity[T: CanBeIntegerized](): Unit = {
val obj = ob.asInstanceOf[BoxOpaque[T]].obj
val oldObj = memorySupport.xchgEntity(loc, obj)
br.asInstanceOf[BoxOpaque[T]].obj = oldObj
}
noAccessViaPointer(ptr, ty)
ty match {
case _: TypeFuncRef => xchgEntity[Function]()
case _: TypeThreadRef => xchgEntity[InterpreterThread]()
case _: TypeStackRef => xchgEntity[InterpreterStack]()
case _: TypeFrameCursorRef => xchgEntity[FrameCursor]()
case _: TypeIRBuilderRef => xchgEntity[IRBuilder]()
}
}
case _: TypeFuncRef => xchgEntity[Function]()
case _: TypeThreadRef => xchgEntity[InterpreterThread]()
case _: TypeStackRef => xchgEntity[InterpreterStack]()
case _: TypeFrameCursorRef => xchgEntity[FrameCursor]()
case _: TypeIRBuilderRef => xchgEntity[IRBuilder]()
case _ =>
throw new UvmUnimplementedOperationException("AtomicRMW XCHG of type %s is not supporing".format(ty.getClass.getName))
}
......
......@@ -157,7 +157,7 @@ class MemorySupport(val muMemorySize: Word) {
def cmpXchgEntity[T: CanBeIntegerized](addr: Word, expected: Option[T], desired: Option[T])(
implicit microVM: MicroVM): (Boolean, Option[T]) = {
val numExpected = implicitly[CanBeIntegerized[T]].integerize(expected)
val numDesired = implicitly[CanBeIntegerized[T]].integerize(expected)
val numDesired = implicitly[CanBeIntegerized[T]].integerize(desired)
val (succ, oldNum) = cmpXchgLong(addr, numExpected, numDesired, inMu = true)
val oldObj = try {
implicitly[CanBeIntegerized[T]].deIntegerize(oldNum)
......
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