Commit 5da7141d authored by Kunshan Wang's avatar Kunshan Wang

Tested the relocator.

parent 1e77a314
......@@ -691,11 +691,12 @@ class MuCtx(val ctxID: MuInternalID, _mutator: Mutator)(
}
}
// do nothing
assert(microVM.memoryManager.globalMemory.isInSpace(objRef) || pinSet.contains(objRef),
val addr = objRef + offset
assert(microVM.memoryManager.globalMemory.isInSpace(addr) || pinSet.contains(objRef),
"Attempt to get address of objref %d 0x%x, offset %d, 0x%x, which is neither a global cell nor pinned by the current thread.".format(
objRef, objRef, offset, offset))
val ptrTy = InternalTypePool.ptrOf(objTy)
val box = new BoxPointer(objRef + offset)
val box = new BoxPointer(addr)
addHandle(MuUPtrValue(ptrTy, box))
}
......
......@@ -131,6 +131,10 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
val symsMap = syms.map(_.toAddrSymPair).toMap
val symsRevMap = syms.map(_.toAddrSymPair.swap).toMap
val relocsMap = relocs.map(_.toAddrSymPair).toMap
{
logger.debug("Relocation map: " + relocsMap.toString)
}
val idNameMapPath = tempDir.resolve(IDNAMEMAP_FILE)
val uirBundlePath = tempDir.resolve(UIRBUNDLE_FILE)
......@@ -220,13 +224,14 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
val begin = alloc.addr
MemoryDataScanner.scanAllocUnit(begin, new MemoryFieldHandler {
def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = if (toAddr != 0L) {
relocsMap.get(toAddr) match {
def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = {
relocsMap.get(iRef) match {
case Some(symbol) => {
// by symbol
val fieldOffset = iRef - objRef
val reloc = FieldRelocRecord(num, fieldOffset, AS_UPTR, TO_SYM, 0, 0, symbol)
group.relocRecs += reloc
logger.debug("External uptr relocation: %d 0x%x -> %s".format(iRef, iRef, symbol))
}
case None => {
// maybe a "reasonable" pointer to a mu global cell. Relocate it too.
......@@ -239,12 +244,21 @@ class BootImageWriter(tcb: TransitiveClosureBuilder, syms: Seq[FieldAndSymbol],
val targetOffset = toAddr - targetAddr
val reloc = FieldRelocRecord(num, fieldOffset, AS_UPTR, TO_GLOBAL, targetNum, targetOffset, NO_SYM)
group.relocRecs += reloc
case None => logger.info("UPtr field not pointing to Mu global cell: %d 0x%x -> %d 0x%x".format(
logger.info("Relocation entry for uptr field automatically generated: %d 0x%x -> %d 0x%x".format(
iRef, iRef, toAddr, toAddr))
}
case None => }
}
}
}
def visitUFPField(objRef: Word, iRef: Word, toAddr: Word): Unit = {
relocsMap.get(iRef).foreach { symbol =>
// by symbol
val fieldOffset = iRef - objRef
val reloc = FieldRelocRecord(num, fieldOffset, AS_UPTR, TO_SYM, 0, 0, symbol)
group.relocRecs += reloc
logger.debug("External ufuncptr relocation: %d 0x%x -> %s".format(iRef, iRef, symbol))
}
}
def visitRefField(objRef: Word, iRef: Word, toObj: Word, isWeak: Boolean): Unit = if (toObj != 0L) {
val fieldOffset = iRef - objRef
......
......@@ -165,15 +165,16 @@ class TransitiveClosureBuilder(initialSet: Seq[TopLevel], val primordial: Primor
}
def maybeGetGlobalCellRec(iref: Word): Option[GlobalCellRec] = {
require(microVM.memoryManager.globalMemory.isInSpace(iref),
"Address %d 0x%x is not in the global space".format(iref, iref))
for ((begin, gcr) <- globalCellMap.to(iref).lastOption) yield {
assert(begin <= iref && iref < gcr.end,
"Address %d 0x%x is in the global space, but the previous global cell's address range is %d 0x%x - %d 0x%x".format(
iref, iref, begin, begin, gcr.end, gcr.end))
if (microVM.memoryManager.globalMemory.isInSpace(iref)) {
for ((begin, gcr) <- globalCellMap.to(iref).lastOption) yield {
assert(begin <= iref && iref < gcr.end,
"Address %d 0x%x is in the global space, but the previous global cell's address range is %d 0x%x - %d 0x%x".format(
iref, iref, begin, begin, gcr.end, gcr.end))
gcr
gcr
}
} else {
None
}
}
......@@ -383,7 +384,12 @@ class TransitiveClosureBuilder(initialSet: Seq[TopLevel], val primordial: Primor
toFunc.foreach(tls+=)
}
override def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = {}
override def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = {
maybeGetGlobalCellRec(toAddr).foreach{ gcr =>
tls += gcr.g
}
}
override def visitUFPField(objRef: Word, iRef: Word, toAddr: Word): Unit = {}
override def visitStackRefField(objRef: Word, iRef: Word, toStack: Option[InterpreterStack]): Unit =
toStack.foreach(o => throw noReach("stack", objRef, iRef, o))
override def visitThreadRefField(objRef: Word, iRef: Word, toThread: Option[InterpreterThread]): Unit =
......
......@@ -47,6 +47,11 @@ object MemoryDataScanner extends StrictLogging {
logger.debug(logField("UPtr", toAddr))
handler.visitUPtrField(objRef, iRef, toAddr)
}
case t: TypeUFuncPtr => {
val toAddr = memorySupport.loadLong(iRef, false)
logger.debug(logField("UFuncPtr", toAddr))
handler.visitUFPField(objRef, iRef, toAddr)
}
case t: TypeRef => {
val toObj = memorySupport.loadLong(iRef)
logger.debug(logField("Ref", toObj))
......
......@@ -23,6 +23,7 @@ import uvm.refimpl.mem.MemorySupport
*/
trait MemoryFieldHandler {
def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit
def visitUFPField(objRef: Word, iRef: Word, toAddr: Word): Unit
def visitRefField(objRef: Word, iRef: Word, toObj: Word, isWeak: Boolean): Unit
def visitIRefField(objRef: Word, iRef: Word, toObj: Word, toOffset: Word): Unit
......@@ -81,6 +82,7 @@ trait RefFieldHandler extends MemoryFieldHandler {
}
def visitUPtrField(objRef: Word, iRef: Word, toAddr: Word): Unit = {}
def visitUFPField(objRef: Word, iRef: Word, toAddr: Word): Unit = {}
def visitFuncRefField(objRef: Word, iRef: Word, toFunc: Option[Function]): Unit = {}
def visitThreadRefField(objRef: Word, iRef: Word, toThread: Option[InterpreterThread]): Unit = {}
def visitFCRefField(objRef: Word, iRef: Word, toFCRef: Option[FrameCursor]): Unit = {}
......
......@@ -8,12 +8,28 @@ import uvm.ir.textinput.TestingBundlesValidators.MagicalOur
import uvm.refimpl.mem.HeaderUtils
import uvm.types.Type
import uvm.refimpl.Word
import uvm.utils.WithUtils._
import uvm.ssavariables.MemoryOrder
import uvm.refimpl.MuUPtrValue
import uvm.refimpl.MuUFPValue
class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers {
override def makeMicroVM = new MicroVM(new VMConf())
preloadBundles("tests/uvm-refimpl-test/transitive-closure.uir")
preloadHails("tests/uvm-refimpl-test/transitive-closure.hail")
{
tryWithResource(microVM.newContext()) { ctx =>
val h_gs = ctx.handleFromGlobal("@gs")
val h_gs_2 = ctx.getFieldIRef(h_gs, 2)
val h_gs_2_ptr = ctx.getAddr(h_gs_2)
val h_gs3 = ctx.handleFromGlobal("@gs3")
val h_gs3_2 = ctx.getFieldIRef(h_gs3, 2)
ctx.store(MemoryOrder.NOT_ATOMIC, h_gs3_2, h_gs_2_ptr)
}
}
val our = new MagicalOur(microVM.globalBundle)
......@@ -33,11 +49,35 @@ class BootImageWriterTest extends UvmBundleTesterBase with ExtraMatchers {
val filename = "target/boot-image-read-write-test.muref"
val everything = microVM.globalBundle.allTopLevels()
microVM.makeBootImage(everything.map(_.id), filename)
tryWithResource(microVM.newContext()) { ctx =>
val h_gs3 = ctx.handleFromGlobal("@gs3")
val h_gs3_3 = ctx.getFieldIRef(h_gs3, 3)
ctx.makeBootImage(everything.map(_.id), None, None, None, Seq(), Seq(), Seq(h_gs3_3), Seq("getchar"), filename)
}
val anotherMicroVM = MicroVM()
anotherMicroVM.loadBootImage(filename)
microVM.globalBundle.allNs("@gd").id shouldEqual anotherMicroVM.globalBundle.allNs("@gd").id
tryWithResource(anotherMicroVM.newContext()) { ctx =>
val h_gs = ctx.handleFromGlobal("@gs")
val h_gs_2 = ctx.getFieldIRef(h_gs, 2)
val h_gs_2_ptr = ctx.getAddr(h_gs_2)
val h_gs3 = ctx.handleFromGlobal("@gs3")
val h_gs3_2 = ctx.getFieldIRef(h_gs3, 2)
val h_gs3_2_val = ctx.load(MemoryOrder.NOT_ATOMIC, h_gs3_2).asInstanceOf[MuUPtrValue]
val h_gs3_3 = ctx.getFieldIRef(h_gs3, 3)
val h_gs3_3_val = ctx.load(MemoryOrder.NOT_ATOMIC, h_gs3_3).asInstanceOf[MuUFPValue]
val gs_2_ptr = ctx.handleToPtr(h_gs_2_ptr)
val gs3_2_val = ctx.handleToPtr(h_gs3_2_val)
val gs3_3_val = ctx.handleToFP(h_gs3_3_val)
gs3_2_val shouldEqual gs_2_ptr
val getchar_val = anotherMicroVM.nativeLibraryHolder.getSymbolAddress("getchar")
gs3_3_val shouldEqual getchar_val
}
}
}
\ No newline at end of file
......@@ -11,3 +11,6 @@
.init @gr1 = 42
.init @gr2 = &@gr1
.init @gs3[0] = 43
.init @gs3[1] = 44
......@@ -49,3 +49,10 @@
.global @gr1 <@i64>
.global @gr2 <@irefi64>
.funcsig @getchar.sig = (@i32) -> ()
.typedef @getchar.fp = ufuncptr<@getchar.sig>
.typedef @s3 = struct<@i32 @pi32 @pi32 @getchar.fp>
.typedef @pi32 = uptr<@i32>
.global @gs3 <@s3>
.global @gs <@s>
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