Commit 90f3e558 authored by Kunshan Wang's avatar Kunshan Wang

GC SOS fix and incr travis log lvl

parent 03df71ff
......@@ -12,35 +12,6 @@ addons:
script:
- pushd tests/c-snippets && make CC=gcc-6 && popd
- sbt compile
- sbt 'test-only uvm.clientsupport.text.BundleBuilderTest'
- sbt 'test-only uvm.ir.textinput.SourceInfoRepoTest'
- sbt 'test-only uvm.ir.textinput.UIRTextReaderSpec'
- sbt 'test-only uvm.NameSpaceSpec'
- sbt 'test-only uvm.refimpl.hail.UvmHailBasicTest'
- sbt 'test-only uvm.refimpl.hail.UvmHailHelloWorldTest'
- sbt 'test-only uvm.refimpl.itpr.UvmConversionOperationSpec'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterFutexTests'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterGCTests'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterInt128Test'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterMetaTests'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterNativeCallbackTests'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterNativeTests'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterNativeTestsExtra'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterSimpleSumTest'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterSimpleTests'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterSpec'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterStackGCTests'
- sbt 'test-only uvm.refimpl.itpr.UvmInterpreterTestBigFunc'
- sbt 'test-only uvm.refimpl.mem.NativeMemoryAccessTest'
- sbt 'test-only uvm.refimpl.mem.ObjectPinningTest'
- sbt 'test-only uvm.refimpl.mem.UvmMemLayoutSpec'
- sbt 'test-only uvm.refimpl.mem.UvmMemOperationsSpec'
- sbt 'test-only uvm.refimpl.misc.FuncRedefTests'
- sbt 'test-only uvm.refimpl.misc.HashableSSAValueTest'
- sbt 'test-only uvm.refimpl.nat.NativeClientSupportTest'
- sbt 'test-only uvm.refimpl.nat.NativeStackKeeperTest'
- sbt 'test-only uvm.refimpl.osr.UvmOSRTests'
- sbt 'test-only uvm.staticanalysis.StaticAnalysisTest'
- sbt 'test-only uvm.testutil.HexDumpTest'
- sbt test
# vim: ts=2 sw=2 sts=2
......@@ -29,6 +29,8 @@ libraryDependencies ++= Seq(
testOptions in Test += Tests.Argument("-oF") // print full stack trace when testing
parallelExecution in Test := false // disable parallel tests because the refimpl2 is not thread-safe
antlr4Settings
antlr4PackageName in Antlr4 := Some("uvm.ir.textinput.gen")
......
......@@ -11,6 +11,7 @@ import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes.Word
import uvm.refimpl.nat.NativeCallHelper
import uvm.staticanalysis.StaticAnalyzer
import uvm.utils.IDFactory
object MicroVM {
val DEFAULT_SOS_SIZE: Word = 2L * 1024L * 1024L; // 2MiB
......@@ -93,13 +94,21 @@ class MicroVM(vmConf: VMConf) {
constantPool.addGlobalVar(g)
}
}
private val contextIDFactory = new IDFactory(1)
/**
* Create a new MuCtx. Part of the API.
*/
def newContext(): MuCtx = {
val mutator = microVM.memoryManager.heap.makeMutator() // This may trigger GC
val ca = new MuCtx(mutator)
def newContext(): MuCtx = newContext("user")
/**
* Create a new MuCtx. Extended to add a name for debugging.
*/
def newContext(name: String): MuCtx = {
val id = contextIDFactory.getID()
val mutator = microVM.memoryManager.heap.makeMutator("MuCtx-%d-%s".format(id, name)) // This may trigger GC
val ca = new MuCtx(id, mutator)
contexts.add(ca)
ca
}
......
......@@ -106,7 +106,7 @@ object MuCtx {
* A client context. The main part of the API. It keeps thread-local states, including a set of handles. It provides
* operations on the Mu VM.
*/
class MuCtx(_mutator: Mutator)(
class MuCtx(val ctxID: Int, _mutator: Mutator)(
implicit microVM: MicroVM, memorySupport: MemorySupport) extends ObjectPinner {
import MuCtx._
......
......@@ -358,6 +358,7 @@ trait InterpreterActions extends InterpreterThreadState {
/** Terminate the thread. Please only let the thread terminate itself. */
protected def threadExit(): Unit = {
curStack.kill()
curThread.mutator.close()
isRunning = false
}
......@@ -405,7 +406,7 @@ trait InterpreterActions extends InterpreterThreadState {
protected def doTrap(retTys: Seq[Type], wpID: Int) = {
val curCtx = ctx // save the context string for debugging
val c = microVM.newContext()
val c = microVM.newContext("trap")
val hThread = c.handleFromInterpreterThread(Some(curThread))
val hStack = c.handleFromInterpreterStack(Some(curStack))
......
......@@ -104,8 +104,8 @@ class ThreadStackManager(implicit microVM: MicroVM, nativeCallHelper: NativeCall
* Create a new thread, bind to a given stack.
*/
def newThread(stack: InterpreterStack, threadLocal: Long, htr: HowToResume): InterpreterThread = {
val mutator = microVM.memoryManager.makeMutator()
val id = threadRegistry.getID()
val mutator = microVM.memoryManager.makeMutator("Itpr-%d".format(id))
val thr = new InterpreterThread(id, stack, threadLocal, htr, mutator)
threadRegistry.put(thr)
thr
......
......@@ -98,7 +98,8 @@ abstract class Heap {
lock.unlock()
}
def makeMutator(): Mutator
/** @param who A string that identifies a mutator. Used for debug purpose. */
def makeMutator(who: String): Mutator
def getMustFreeSpace(): Boolean = mustFreeSpace
}
......@@ -46,7 +46,7 @@ class MemoryManager(val vmConf: VMConf)(implicit microVM: MicroVM) {
val heap = new SimpleImmixHeap(heapBegin, vmConf.sosSize, vmConf.losSize)
val globalMemory = new GlobalMemory(globalBegin, vmConf.globalSize)
def makeMutator(): Mutator = heap.makeMutator()
def makeMutator(name: String): Mutator = heap.makeMutator(name)
def makeStackMemory(mutator: Mutator): StackMemory = {
val objRef = mutator.newHybrid(InternalTypes.BYTE_ARRAY, vmConf.stackSize)
......
......@@ -9,7 +9,7 @@ object Mutator {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
}
abstract class Mutator(implicit memorySupport: MemorySupport) {
abstract class Mutator(val name: String)(implicit memorySupport: MemorySupport) {
import Mutator._
def alloc(size: Word, align: Word, headerSize: Word): Word
......
......@@ -12,7 +12,7 @@ object LargeObjectSpace {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
val BLOCK_SIZE = SimpleImmixSpace.BLOCK_SIZE / 4
val BLOCK_SIZE = SimpleImmixSpace.BLOCK_SIZE / 8
private val OFFSET_PREV = 0 * TypeSizes.WORD_SIZE_BYTES
......
......@@ -7,14 +7,17 @@ import com.typesafe.scalalogging.Logger
import TypeSizes.Word
import uvm.refimpl.UvmRefImplException
import uvm.utils.RetryUtils._
import uvm.utils.IDFactory
object SimpleImmixDefragMutator {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
val defragMutatorIDFactory = new IDFactory(1)
}
class SimpleImmixDefragMutator(val heap: SimpleImmixHeap, val space: SimpleImmixSpace)(
implicit memorySupport: MemorySupport)
extends Mutator with Allocator {
extends Mutator("defrag-" + SimpleImmixDefragMutator.defragMutatorIDFactory.getID()) with Allocator {
import SimpleImmixDefragMutator._
......@@ -27,7 +30,7 @@ class SimpleImmixDefragMutator(val heap: SimpleImmixHeap, val space: SimpleImmix
getNewBlock()
private def getNewBlock() {
curBlockAddr = space.getDefragBlock(curBlockAddr)
curBlockAddr = space.getDefragBlock(curBlockAddr, this)
curBlockAddr match {
case Some(addr) =>
cursor = addr
......@@ -72,6 +75,6 @@ class SimpleImmixDefragMutator(val heap: SimpleImmixHeap, val space: SimpleImmix
def close() {
logger.debug("Closing defrag mutator...")
curBlockAddr.foreach(space.returnBlock)
curBlockAddr.foreach(a => space.returnDefragBlock(a, this))
}
}
......@@ -39,8 +39,8 @@ class SimpleImmixHeap(val begin: Word, val sosSize: Word, val losSize: Word)(
collectorThread.start()
override def makeMutator(): SimpleImmixMutator = {
val mutator = new SimpleImmixMutator(this, space, los)
override def makeMutator(name: String): SimpleImmixMutator = {
val mutator = new SimpleImmixMutator(this, space, los, name)
mutator
}
......
......@@ -12,12 +12,14 @@ object SimpleImmixMutator {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
}
class SimpleImmixMutator(val heap: SimpleImmixHeap, val space: SimpleImmixSpace, val los: LargeObjectSpace)(
class SimpleImmixMutator(val heap: SimpleImmixHeap, val space: SimpleImmixSpace, val los: LargeObjectSpace, name: String)(
implicit memorySupport: MemorySupport)
extends Mutator with Allocator {
extends Mutator(name) with Allocator {
import SimpleImmixMutator._
logger.debug("Creating mutator %s...".format(name))
private var curBlockAddr: Option[Word] = None
private var cursor: Word = _
......@@ -28,8 +30,11 @@ class SimpleImmixMutator(val heap: SimpleImmixHeap, val space: SimpleImmixSpace,
private def getNewBlock(): Unit = {
val newAddr = tryRepeatedly {
space.tryGetBlock(curBlockAddr).orElse {
val toReturn = curBlockAddr
curBlockAddr = None
space.tryGetBlock(toReturn, this).orElse {
heap.mutatorTriggerAndWaitForGCEnd(true)
logger.debug("Try again to get block...")
None
}
}
......@@ -48,7 +53,7 @@ class SimpleImmixMutator(val heap: SimpleImmixHeap, val space: SimpleImmixSpace,
val userStart = TypeSizes.alignUp(gcStart + headerSize, align)
val userEnd = userStart + size
if (userEnd >= limit) {
if (userEnd - gcStart > SimpleImmixSpace.BLOCK_SIZE) {
if (userEnd - gcStart > SimpleImmixSpace.SOS_THRESHOLD) {
Some(los.alloc(size, align, headerSize))
} else {
logger.debug("Getting new block...")
......@@ -66,7 +71,7 @@ class SimpleImmixMutator(val heap: SimpleImmixHeap, val space: SimpleImmixSpace,
}
def close() {
logger.debug("Closing mutator...")
curBlockAddr.foreach(space.returnBlock)
logger.debug("Closing mutator %s...".format(name))
curBlockAddr.foreach(a => space.returnBlock(a, this))
}
}
......@@ -10,10 +10,23 @@ object SimpleImmixSpace {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
val BLOCK_SIZE = 32768L
val SOS_THRESHOLD = BLOCK_SIZE / 4L
val BLOCK_MARKED = 0x1
val BLOCK_RESERVED = 0x2
val BLOCK_PINNED = 0x4
val BLOCK_IN_MUTATOR = 0x4
val BLOCK_PINNED = 0x8
def prettyPrintFlags(flags: Int): String = {
def optStr(flag: Int, str: String): String = if ((flags & flag) != 0) str else ""
"0x%x (%s%s%s%s)".format(flags,
optStr(BLOCK_MARKED, "M"),
optStr(BLOCK_PINNED, "P"),
optStr(BLOCK_RESERVED, "R"),
optStr(BLOCK_IN_MUTATOR, "I"))
}
private val LINE_SIZE = 128L
......@@ -77,10 +90,13 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
/** A list of buckets, for statistics. Used by defrag. */
private val buckets: Array[Word] = new Array[Word](N_BUCKETS)
/** Which mutator is using which block? */
private val blockUser: Array[Option[Mutator]] = Array.fill(nBlocks)(None)
for (i <- 0 until nReserved) { // Block 0 to nReserved-1 are reserved
defragResv(i) = i
reserve(i) // Set the reserved flat
blockFlags(i) |= BLOCK_RESERVED // Set the reserved flat
}
for (i <- nReserved until nBlocks) { // The rest of the blocks are free to allocate
......@@ -88,10 +104,10 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
}
/**
* Try to get a free block. If not available, return None. The old block, if present, is returned from reserving.
* Try to get a free block. If not available, return None. The old block, if present, is returned.
*/
def tryGetBlock(oldBlockAddr: Option[Word]): Option[Word] = {
oldBlockAddr.foreach(returnBlock)
def tryGetBlock(oldBlockAddr: Option[Word], who: Mutator): Option[Word] = {
oldBlockAddr.foreach(a => returnBlock(a, who))
val myCursor = nextFree
if (myCursor >= freeListValidCount) {
......@@ -101,20 +117,32 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
nextFree += 1
val blockNum = freeList(myCursor)
reserve(blockNum)
mutatorGetBlock(blockNum, who)
logger.debug("Normal mutator %s got block %d".format(who.name, blockNum))
val blockAddr = blockIndexToBlockAddr(blockNum)
MemUtils.zeroRegion(blockAddr, BLOCK_SIZE)
Some(blockAddr)
}
private def reserve(blockNum: Int) {
blockFlags(blockNum) |= BLOCK_RESERVED
private def mutatorGetBlock(blockNum: Int, who: Mutator): Unit = {
blockFlags(blockNum) |= BLOCK_IN_MUTATOR
blockUser(blockNum) = Some(who)
}
private def unreserve(blockNum: Int) {
blockFlags(blockNum) &= ~BLOCK_RESERVED
private def mutatorReleaseBlock(blockNum: Int, who: Mutator): Unit = {
val oldUser = blockUser(blockNum)
if (oldUser != Some(who)) {
throw new UvmRefImplException("Mutator %s returned a block %d which was reserved by %s".format(
who.name, blockNum, oldUser.map(_.name).getOrElse("(nobody)")))
}
blockUser(blockNum) = None
val flags = blockFlags(blockNum)
assert((flags & BLOCK_IN_MUTATOR) != 0, "Block %d (to be returned) should have flags 0x%x. Actual flags: %s".format(
blockNum, BLOCK_IN_MUTATOR, prettyPrintFlags(flags)))
blockFlags(blockNum) &= ~BLOCK_IN_MUTATOR
}
def objRefToBlockIndex(objRef: Word): Int = {
......@@ -148,49 +176,73 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
logger.debug(s"Marked block ${blockIndex}. pin=${pin}")
}
def isPinned(pageNum: Int): Boolean = (blockFlags(pageNum) & BLOCK_MARKED) != 0
def isPinned(pageNum: Int): Boolean = (blockFlags(pageNum) & BLOCK_PINNED) != 0
def collectBlocks(): Boolean = {
logger.debug("Before collecting blocks from SOS:")
if (logger.underlying.isDebugEnabled()) {
debugLogBlockStates()
}
for (i <- 0 until nBlocks) {
val flags = blockFlags(i)
if ((flags & BLOCK_RESERVED) != 0) {
assert(flags == BLOCK_RESERVED, "Reserved block %d should have flags 0x%x. Actual flags: %s".format(
i, BLOCK_RESERVED, prettyPrintFlags(flags)))
}
}
// Shift defrag reserved blocks to the beginning;
for (i <- nextResv until defragResvFree) {
defragResv(i - nextResv) = defragResv(i)
}
var newDefragResvFree = defragResvFree - nextResv
for (i <- 0 until newDefragResvFree) {
val ind = defragResv(i)
val flags = blockFlags(ind)
assert(flags == BLOCK_RESERVED, "Block %d (from defrag freelist) should have flags 0x%x. Actual flags: %s".format(
ind, BLOCK_RESERVED, prettyPrintFlags(flags)))
}
var newNFree = 0
for (i <- 0 until nBlocks) {
var flag = blockFlags(i)
val bits = (flag & (BLOCK_MARKED | BLOCK_RESERVED | BLOCK_PINNED))
val bits = (flag & (BLOCK_MARKED | BLOCK_IN_MUTATOR | BLOCK_RESERVED | BLOCK_PINNED))
if (bits == 0) {
if (newDefragResvFree < nReserved) {
defragResv(newDefragResvFree) = i
newDefragResvFree += 1
flag |= BLOCK_RESERVED
logger.debug(s"Block ${i} added to defrag freelist")
} else {
freeList(newNFree) = i
newNFree += 1
flag &= ~BLOCK_RESERVED
logger.debug(s"Block ${i} added to normal freelist")
}
} else if ((bits & BLOCK_RESERVED) != 0) {
logger.debug(s"Block ${i} is already reserved.")
} else {
logger.debug(s"Block ${i} is not freed because flag bits is ${bits}")
}
flag &= ~(BLOCK_MARKED | BLOCK_PINNED)
flag &= ~(BLOCK_MARKED | BLOCK_PINNED) // The only place that unmarks the block
blockFlags(i) = flag
}
defragResvFree = newDefragResvFree
freeListValidCount = newNFree
nextResv = 0
nextFree = 0
if (logger.underlying.isDebugEnabled()) {
logger.debug("After collecting blocks from SOS:")
debugLogBlockStates()
}
nextResv = 0
nextFree = 0
return newNFree > 0
}
def returnBlock(blockAddr: Word) {
def returnBlock(blockAddr: Word, who: Mutator) {
val blockNum = blockAddrToBlockIndex(blockAddr)
unreserve(blockNum)
logger.debug("Block %d returned to space.".format(blockNum))
mutatorReleaseBlock(blockNum, who)
logger.debug("Block %d returned to space by %s.".format(blockNum, who.name))
}
// Statistics
......@@ -251,8 +303,8 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
}
// Defrag
def getDefragBlock(oldBlockAddr: Option[Word]): Option[Word] = {
oldBlockAddr.foreach(returnBlock)
def getDefragBlock(oldBlockAddr: Option[Word], who: SimpleImmixDefragMutator): Option[Word] = {
oldBlockAddr.foreach(a => returnBlock(a, who))
val myCursor = nextResv
......@@ -263,27 +315,41 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
nextResv += 1
val blockNum = defragResv(myCursor)
val flags = blockFlags(blockNum)
assert(flags == BLOCK_RESERVED, "Defrag block %d (to be used) should have flags 0x%x. Actual flags: %s".format(
blockNum, BLOCK_RESERVED, prettyPrintFlags(flags)))
blockFlags(blockNum) &= ~BLOCK_RESERVED
mutatorGetBlock(blockNum, who)
logger.debug("Defrag mutator %s got block %d".format(who.name, blockNum))
val blockAddr = blockIndexToBlockAddr(blockNum)
MemUtils.zeroRegion(blockAddr, BLOCK_SIZE)
return Some(blockAddr)
}
def returnDefragBlock(oldBlockAddr: Word, who: SimpleImmixDefragMutator): Unit = {
returnBlock(oldBlockAddr, who)
}
// Debugging
def debugLogBlockStates() {
val sb1 = new StringBuilder("Reserved freelist:")
for (i <- 0 until defragResvFree) {
for (i <- nextResv until defragResvFree) {
sb1.append(" ").append(defragResv(i))
}
logger.debug(sb1.toString)
val sb2 = new StringBuilder("Freelist:")
for (i <- 0 until freeListValidCount) {
for (i <- nextFree until freeListValidCount) {
sb2.append(" ").append(freeList(i))
}
logger.debug(sb2.toString)
for (i <- 0 until nBlocks) {
logger.debug(s"blockFlags[${i}] = ${blockFlags(i)}")
val prettyFlags = prettyPrintFlags(blockFlags(i))
val user = blockUser(i).map(m => "user: %s".format(m.name)).getOrElse("")
logger.debug("block %d: flag=%s %s".format(i, prettyFlags, user))
}
}
}
package uvm
import org.slf4j.LoggerFactory
import org.slf4j.{ Logger => SLogger }
import ch.qos.logback.classic.{ Logger => LLogger, Level }
import ch.qos.logback.classic.Level._
object LogSetter {
def setLevel(name: String, level: Level): Unit = {
LoggerFactory.getLogger(name).asInstanceOf[LLogger].setLevel(level)
}
val isTravis = {
System.getenv("TRAVIS") == "true"
}
}
trait LogSetter {
import LogSetter._
val ROOT_LOGGER_NAME = org.slf4j.Logger.ROOT_LOGGER_NAME
if (isTravis) { // Travis does not like logging, so just heighten the log level whenever we run tests.
setLevel(ROOT_LOGGER_NAME, WARN)
}
def setLogLevels(settings: (String, Level)*): Unit = if (isTravis) {
// Travis does not like logging, so just make it a no-op.
} else { // Configure logger
for ((name, lvl) <- settings) {
setLevel(name, lvl)
}
}
}
\ No newline at end of file
......@@ -3,7 +3,7 @@ package uvm
import org.scalatest.Matchers
import org.scalatest.FlatSpec
class NameSpaceSpec extends FlatSpec with Matchers {
class NameSpaceSpec extends UvmTestBase {
behavior of "NestedNamespace"
class Foo(val i: Int) extends IdentifiedSettable
......
package uvm
import org.scalatest.Matchers
import org.scalatest.FlatSpec
abstract class UvmTestBase extends FlatSpec with Matchers with LogSetter
\ No newline at end of file
......@@ -5,8 +5,10 @@ import org.scalatest.Matchers
import TextOutputMatchers._
import uvm.ir.textinput.UIRTextReader
import uvm.utils.IDFactory
import uvm.LogSetter
import uvm.UvmTestBase
class BundleBuilderTest extends FlatSpec with Matchers {
class BundleBuilderTest extends UvmTestBase {
val x = TypeName("x")
val y = TypeName("y")
......@@ -112,8 +114,7 @@ class BundleBuilderTest extends FlatSpec with Matchers {
Inst.PreSwitch(x, a, l1, IList(
SwitchCase(LocalVarName("v1"), LabelName("d1")),
SwitchCase(LocalVarName("v2"), LabelName("d2")),
SwitchCase(LocalVarName("v3"), LabelName("d3"))
)).toString shouldEqual "SWITCH <@x> %a %l1 { %v1: %d1; %v2: %d2; %v3: %d3; }"
SwitchCase(LocalVarName("v3"), LabelName("d3")))).toString shouldEqual "SWITCH <@x> %a %l1 { %v1: %d1; %v2: %d2; %v3: %d3; }"
PostExcClause(Inst.Call(s, f, IList(a, b, c), Some(KeepAliveClause(IList(a, b)))), nor, exc).toString shouldEqual
"CALL <@s> @f (%a %b %c) EXC(%nor() %exc()) KEEPALIVE(%a %b)"
Inst.TailCall(s, f, IList(a, b, c)).toString shouldEqual
......@@ -132,18 +133,18 @@ class BundleBuilderTest extends FlatSpec with Matchers {
PostExcClause(Inst.Alloca(x), nor, exc).toString shouldEqual "ALLOCA <@x> EXC(%nor() %exc())"
PostExcClause(Inst.AllocaHybrid(x, 91, a), nor, exc).toString shouldEqual "ALLOCAHYBRID <@x 91> %a EXC(%nor() %exc())"
Inst.GetIRef(x, a).toString shouldEqual "GETIREF <@x> %a"
Inst.GetFieldIRef(ptr=true, x, 3, a).toString shouldEqual "GETFIELDIREF PTR <@x 3> %a"
Inst.GetElemIRef(ptr=true, x, y, a, b).toString shouldEqual "GETELEMIREF PTR <@x @y> %a %b"
Inst.ShiftIRef(ptr=true, x, y, a, b).toString shouldEqual "SHIFTIREF PTR <@x @y> %a %b"
Inst.GetFixedPartIRef(ptr=true, x, a).toString shouldEqual "GETFIXEDPARTIREF PTR <@x> %a"
Inst.GetVarPartIRef(ptr=true, x, a).toString shouldEqual "GETVARPARTIREF PTR <@x> %a"
PostExcClause(Inst.Load(ptr=true, SeqConsistent, x, a), nor, exc).toString shouldEqual
Inst.GetFieldIRef(ptr = true, x, 3, a).toString shouldEqual "GETFIELDIREF PTR <@x 3> %a"
Inst.GetElemIRef(ptr = true, x, y, a, b).toString shouldEqual "GETELEMIREF PTR <@x @y> %a %b"
Inst.ShiftIRef(ptr = true, x, y, a, b).toString shouldEqual "SHIFTIREF PTR <@x @y> %a %b"
Inst.GetFixedPartIRef(ptr = true, x, a).toString shouldEqual "GETFIXEDPARTIREF PTR <@x> %a"
Inst.GetVarPartIRef(ptr = true, x, a).toString shouldEqual "GETVARPARTIREF PTR <@x> %a"
PostExcClause(Inst.Load(ptr = true, SeqConsistent, x, a), nor, exc).toString shouldEqual
"LOAD PTR SEQ_CST <@x> %a EXC(%nor() %exc())"
PostExcClause(Inst.Store(ptr=true, SeqConsistent, x, a, b), nor, exc).toString shouldEqual
PostExcClause(Inst.Store(ptr = true, SeqConsistent, x, a, b), nor, exc).toString shouldEqual
"STORE PTR SEQ_CST <@x> %a %b EXC(%nor() %exc())"
PostExcClause(Inst.CmpXchg(ptr=true, weak=true, AcquireRelease, Acquire, x, a, b, c), nor, exc).toString shouldEqual
PostExcClause(Inst.CmpXchg(ptr = true, weak = true, AcquireRelease, Acquire, x, a, b, c), nor, exc).toString shouldEqual
"CMPXCHG PTR WEAK ACQ_REL ACQUIRE <@x> %a %b %c EXC(%nor() %exc())"
PostExcClause(Inst.AtomicRMW(ptr=true, SeqConsistent, AtomicRMWOptr.Xor, x, a, b), nor, exc).toString shouldEqual
PostExcClause(Inst.AtomicRMW(ptr = true, SeqConsistent, AtomicRMWOptr.Xor, x, a, b), nor, exc).toString shouldEqual
"ATOMICRMW PTR SEQ_CST XOR <@x> %a %b EXC(%nor() %exc())"
Inst.Fence(SeqConsistent).toString shouldEqual "FENCE SEQ_CST"
PostExcClause(Inst.Trap(IList(x), Some(KeepAliveClause(IList(a, b)))), nor, exc).toString shouldEqual
......@@ -157,28 +158,24 @@ class BundleBuilderTest extends FlatSpec with Matchers {
PostExcClause(Inst.SwapStack(a,
CurStackClause.RetWith(x),
NewStackClause.PassValue(y, b),
Some(KeepAliveClause(IList(a, b)))
), nor, exc).toString shouldEqual
Some(KeepAliveClause(IList(a, b)))), nor, exc).toString shouldEqual
"SWAPSTACK %a RET_WITH <@x> PASS_VALUE <@y> %b EXC(%nor() %exc()) KEEPALIVE(%a %b)"
PostExcClause(Inst.SwapStack(a,
CurStackClause.KillOld(),
NewStackClause.PassVoid(),
Some(KeepAliveClause(IList(a, b)))
), nor, exc).toString shouldEqual
Some(KeepAliveClause(IList(a, b)))), nor, exc).toString shouldEqual
"SWAPSTACK %a KILL_OLD PASS_VOID EXC(%nor() %exc()) KEEPALIVE(%a %b)"
PostExcClause(Inst.SwapStack(a,
CurStackClause.KillOld(),
NewStackClause.ThrowExc(b),
Some(KeepAliveClause(IList(a, b)))
), nor, exc).toString shouldEqual
Some(KeepAliveClause(IList(a, b)))), nor, exc).toString shouldEqual
"SWAPSTACK %a KILL_OLD THROW_EXC %b EXC(%nor() %exc()) KEEPALIVE(%a %b)"
PostExcClause(Inst.CommInst(GlobalVarName("foo.bar"),
Some(IList(new Flag("A"), new Flag("B"))),
Some(IList(x, y)),
Some(IList(s, FuncSigName("s2"))),
Some(IList(a, b)),
Some(KeepAliveClause(IList(a, b)))
), nor, exc).toString shouldEqual
Some(KeepAliveClause(IList(a, b)))), nor, exc).toString shouldEqual
"COMMINST @foo.bar [#A #B] <@x @y> <[@s @s2]> (%a %b) EXC(%nor() %exc()) KEEPALIVE(%a %b)"
}
......@@ -189,8 +186,7 @@ class BundleBuilderTest extends FlatSpec with Matchers {
fn(builder.newFuncVersion(
GlobalVarName(name),
new IList(paramTy map builder.typeDef),
new IList(retTy map builder.typeDef)
))
new IList(retTy map builder.typeDef)))
builder
}
......@@ -199,8 +195,7 @@ class BundleBuilderTest extends FlatSpec with Matchers {
Inst.BinOp.Add,
fbuilder typeDef Int(32),
fbuilder paramNames 0,
fbuilder paramNames 1
)
fbuilder paramNames 1)
fbuilder.inst(IList(), Inst.Ret(IList(addRes)))
} should matchIRTemplate("""
.typedef @$int = int<32>
......@@ -233,8 +228,7 @@ class BundleBuilderTest extends FlatSpec with Matchers {
Inst.BinOp.Add,
fbuilder typeDef Int(32),
fbuilder paramNames 0,
fbuilder paramNames 1
)
fbuilder paramNames 1)
val next = fbuilder.newLabelName()
fbuilder.inst(IList(), Inst.PreBranch(next))
fbuilder.startNewBlock(next)
......@@ -298,9 +292,9 @@ class BundleBuilderTest extends FlatSpec with Matchers {
funcBuilder.inst(IList(), Inst.Ret(IList(c)))
val ir = builder.build().toString
println(ir)
val muBundle = new UIRTextReader(new IDFactory(0)).read(ir, new uvm.GlobalBundle())
}
}
\ No newline at end of file
......@@ -5,9 +5,9 @@ import org.scalatest.Matchers
import uvm.GlobalBundle
import uvm.TrantientBundle
import uvm.utils.IDFactory
import uvm.UvmTestBase
class NicerErrorMessage extends FlatSpec with Matchers
with TestingBundlesValidators {
class NicerErrorMessage extends UvmTestBase with TestingBundlesValidators {
def parseFile(fileName: String, globalBundle: GlobalBundle, fac: Option[IDFactory] = None): TrantientBundle = {
val idf = fac.getOrElse(new IDFactory(uvm.refimpl.MicroVM.FIRST_CLIENT_USABLE_ID))
......@@ -27,5 +27,5 @@ class NicerErrorMessage extends FlatSpec with Matchers
e.printStackTrace()
}
}