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

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

Testing memory manager...

parent 25007640
...@@ -43,11 +43,4 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE, ...@@ -43,11 +43,4 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
def newClientAgent(): ClientAgent = new ClientAgent(this) def newClientAgent(): ClientAgent = new ClientAgent(this)
def addClientAgent(ca: ClientAgent): Unit = {
clientAgents.add(ca)
}
def removeClientAgent(ca: ClientAgent): Unit = {
clientAgents.remove(ca)
}
} }
\ No newline at end of file
...@@ -28,7 +28,7 @@ trait UndefinedFunctionHandler { ...@@ -28,7 +28,7 @@ trait UndefinedFunctionHandler {
class ClientAgent(microVM: MicroVM) { class ClientAgent(microVM: MicroVM) {
val handles = new HashSet[Handle]() val handles = new HashSet[Handle]()
microVM.addClientAgent(this) microVM.clientAgents.add(this)
val mutator = microVM.memoryManager.heap.makeMutator() val mutator = microVM.memoryManager.heap.makeMutator()
...@@ -45,7 +45,7 @@ class ClientAgent(microVM: MicroVM) { ...@@ -45,7 +45,7 @@ class ClientAgent(microVM: MicroVM) {
def close(): Unit = { def close(): Unit = {
handles.clear() handles.clear()
mutator.close() mutator.close()
microVM.removeClientAgent(this) microVM.clientAgents.remove(this)
} }
def loadBundle(r: Reader): Unit = { def loadBundle(r: Reader): Unit = {
......
...@@ -24,8 +24,8 @@ class ThreadStackManager(microVM: MicroVM) { ...@@ -24,8 +24,8 @@ class ThreadStackManager(microVM: MicroVM) {
private def makeThreadID(): Int = {val id = nextThreadID; nextThreadID += 1; id} private def makeThreadID(): Int = {val id = nextThreadID; nextThreadID += 1; id}
def newStack(function: Function, args: Seq[ValueBox]): InterpreterStack = { def newStack(function: Function, args: Seq[ValueBox], mutator: Mutator): InterpreterStack = {
val stackMemory = microVM.memoryManager.makeStackMemory() val stackMemory = microVM.memoryManager.makeStackMemory(mutator)
val id = makeStackID() val id = makeStackID()
val sta = new InterpreterStack(id, stackMemory, function.versions.head, args) val sta = new InterpreterStack(id, stackMemory, function.versions.head, args)
stackRegistry.put(id, sta) stackRegistry.put(id, sta)
......
...@@ -26,7 +26,7 @@ object HeaderUtils extends StrictLogging { ...@@ -26,7 +26,7 @@ object HeaderUtils extends StrictLogging {
} }
def setTag(objRef: Word, tag: Word) { def setTag(objRef: Word, tag: Word) {
logger.debug(s"Storing tag ${tag} at addr ${TypeSizes.GC_HEADER_OFFSET_TAG}") logger.debug("Storing tag 0x%x at addr 0x%x".format(tag, objRef + TypeSizes.GC_HEADER_OFFSET_TAG))
MemorySupport.storeLong(objRef + TypeSizes.GC_HEADER_OFFSET_TAG, tag) MemorySupport.storeLong(objRef + TypeSizes.GC_HEADER_OFFSET_TAG, tag)
} }
......
...@@ -15,12 +15,10 @@ class MemoryManager(val heapSize: Word, val globalSize: Word, val stackSize: Wor ...@@ -15,12 +15,10 @@ class MemoryManager(val heapSize: Word, val globalSize: Word, val stackSize: Wor
val globalMemory = new GlobalMemory(MEMORY_BEGIN + heapSize, globalSize, microVM) val globalMemory = new GlobalMemory(MEMORY_BEGIN + heapSize, globalSize, microVM)
private val internalMutator = heap.makeMutator()
def makeMutator(): Mutator = heap.makeMutator() def makeMutator(): Mutator = heap.makeMutator()
def makeStackMemory(): StackMemory = { def makeStackMemory(mutator: Mutator): StackMemory = {
val objRef = internalMutator.newHybrid(InternalTypes.BYTE_ARRAY, stackSize) val objRef = mutator.newHybrid(InternalTypes.BYTE_ARRAY, stackSize)
val stackMemory = new StackMemory(objRef, stackSize, microVM) val stackMemory = new StackMemory(objRef, stackSize, microVM)
stackMemory stackMemory
} }
......
...@@ -44,15 +44,15 @@ class RewindableBumpPointerAllocator(val begin: Word, val extend: Word, val micr ...@@ -44,15 +44,15 @@ class RewindableBumpPointerAllocator(val begin: Word, val extend: Word, val micr
var curTopLoc = top var curTopLoc = top
var reachBottom = false var reachBottom = false
while (!reachBottom) { while (!reachBottom) {
logger.debug(s"curTopLoc is ${curTopLoc}") logger.debug("curTopLoc is 0x%x".format(curTopLoc))
val iRef = MemorySupport.loadLong(curTopLoc) val iRef = MemorySupport.loadLong(curTopLoc)
logger.debug(s"iRef is ${iRef}") logger.debug("iRef is 0x%x".format(iRef))
if (iRef != 0) { if (iRef != 0) {
val hdr = HeaderUtils.getTag(iRef) val hdr = HeaderUtils.getTag(iRef)
val typeID = (hdr & 0xffffffffL).toInt val typeID = (hdr & 0xffffffffL).toInt
logger.debug(s"hdr=${hdr}, typeID=${typeID}") logger.debug("hdr=0x%x, typeID=0x%x".format(hdr, typeID))
val ty = microVM.globalBundle.typeNs(typeID) val ty = microVM.globalBundle.typeNs(typeID)
logger.debug(s"type=${ty.repr}: ${ty.toString}") logger.debug("type=%s: %s".format(ty.repr, ty.toString))
MemoryDataScanner.scanField(ty, 0, iRef, handler) MemoryDataScanner.scanField(ty, 0, iRef, handler)
var prevTopLoc: Word = 0L var prevTopLoc: Word = 0L
prevTopLoc = if (ty.isInstanceOf[TypeHybrid]) { prevTopLoc = if (ty.isInstanceOf[TypeHybrid]) {
......
...@@ -90,7 +90,7 @@ class LargeObjectSpace(val heap: SimpleImmixHeap, ...@@ -90,7 +90,7 @@ class LargeObjectSpace(val heap: SimpleImmixHeap,
def markBlockByObjRef(objRef: Word) { def markBlockByObjRef(objRef: Word) {
val blockAddr = objRefToBlockAddr(objRef) val blockAddr = objRefToBlockAddr(objRef)
logger.debug("marking block addr %d for obj %d...".format(blockAddr, objRef)) logger.debug("marking block addr 0x%x for obj 0x%x...".format(blockAddr, objRef))
markBlock(blockAddr) markBlock(blockAddr)
} }
...@@ -104,17 +104,17 @@ class LargeObjectSpace(val heap: SimpleImmixHeap, ...@@ -104,17 +104,17 @@ class LargeObjectSpace(val heap: SimpleImmixHeap,
var curBlock = head var curBlock = head
val lastBlock = getPrev(curBlock) val lastBlock = getPrev(curBlock)
var nextBlock = getNext(curBlock) var nextBlock = getNext(curBlock)
logger.debug("Begin iteration from %d to %d".format(curBlock, lastBlock)) logger.debug("Begin iteration from 0x%x to 0x%x".format(curBlock, lastBlock))
var finished = false var finished = false
while (!finished) { while (!finished) {
logger.debug("Visiting block %d..".format(curBlock)) logger.debug("Visiting block 0x%x..".format(curBlock))
val mark = getBlockMark(curBlock) val mark = getBlockMark(curBlock)
if (mark != MARK_BIT) { if (mark != MARK_BIT) {
logger.debug("Deallocating block addr %d...".format(curBlock)) logger.debug("Deallocating block addr 0x%x...".format(curBlock))
dealloc(curBlock) dealloc(curBlock)
anyDeallocated = true anyDeallocated = true
} else { } else {
logger.debug("Block addr %d contains live object.".format(curBlock)) logger.debug("Block addr 0x%x contains live object.".format(curBlock))
unmarkBlock(curBlock) unmarkBlock(curBlock)
} }
if (curBlock == lastBlock) { if (curBlock == lastBlock) {
......
...@@ -94,6 +94,7 @@ object MemoryDataScanner extends StrictLogging { ...@@ -94,6 +94,7 @@ object MemoryDataScanner extends StrictLogging {
curAddr = TypeSizes.alignUp(curAddr + varSize, varAlign) curAddr = TypeSizes.alignUp(curAddr + varSize, varAlign)
} }
} }
case _ => // Ignore non-reference fields.
} }
} }
} }
...@@ -122,14 +122,14 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap, ...@@ -122,14 +122,14 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap,
private def maybeMarkAndStat(addr: Word): Boolean = { private def maybeMarkAndStat(addr: Word): Boolean = {
assert(addr != 0L, "addr should be non-zero before calling this function") assert(addr != 0L, "addr should be non-zero before calling this function")
val oldHeader = HeaderUtils.getTag(addr) val oldHeader = HeaderUtils.getTag(addr)
logger.debug("GC header of %d is %x".format(addr, oldHeader)) logger.debug("GC header of 0x%x is 0x%x".format(addr, oldHeader))
val wasMarked = (oldHeader & MARK_MASK) != 0 val wasMarked = (oldHeader & MARK_MASK) != 0
if (!wasMarked) { if (!wasMarked) {
val newHeader = oldHeader | MARK_MASK val newHeader = oldHeader | MARK_MASK
HeaderUtils.setTag(addr, newHeader) HeaderUtils.setTag(addr, newHeader)
logger.debug("Newly marked %d".format(addr)) logger.debug("Newly marked 0x%x".format(addr))
if (space.isInSpace(addr)) { if (space.isInSpace(addr)) {
space.markBlockByObjRef(addr) //space.markBlockByObjRef(addr)
val tag = HeaderUtils.getTag(addr) val tag = HeaderUtils.getTag(addr)
val ty = HeaderUtils.getType(microVM, tag) val ty = HeaderUtils.getType(microVM, tag)
val used = ty match { val used = ty match {
...@@ -144,7 +144,7 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap, ...@@ -144,7 +144,7 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap,
val blockNum = space.objRefToBlockIndex(addr) val blockNum = space.objRefToBlockIndex(addr)
space.incStat(blockNum, used) space.incStat(blockNum, used)
} else if (los.isInSpace(addr)) { } else if (los.isInSpace(addr)) {
los.markBlockByObjRef(addr) //los.markBlockByObjRef(addr)
} else { } else {
throw new UvmRefImplException("Object ref %d not in any space".format(addr)) throw new UvmRefImplException("Object ref %d not in any space".format(addr))
} }
...@@ -179,7 +179,7 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap, ...@@ -179,7 +179,7 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap,
private def maybeMove(toObj: Word, updateFunc: Word => Unit): Boolean = { private def maybeMove(toObj: Word, updateFunc: Word => Unit): Boolean = {
val oldHeader = HeaderUtils.getTag(toObj) val oldHeader = HeaderUtils.getTag(toObj)
logger.debug("GC header of %d is %x".format(toObj, oldHeader)) logger.debug("GC header of 0x%x is 0x%x".format(toObj, oldHeader))
val markBit = oldHeader & MARK_MASK val markBit = oldHeader & MARK_MASK
val moveBit = oldHeader & MOVE_MASK val moveBit = oldHeader & MOVE_MASK
val wasMarked = markBit != 0 val wasMarked = markBit != 0
...@@ -214,14 +214,14 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap, ...@@ -214,14 +214,14 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap,
val newHeader = oldHeader | MARK_MASK val newHeader = oldHeader | MARK_MASK
HeaderUtils.setTag(actualObj, newHeader) HeaderUtils.setTag(actualObj, newHeader)
logger.debug(s"Newly marked ${actualObj}") logger.debug("Newly marked 0x%x".format(actualObj))
if (space.isInSpace(actualObj)) { if (space.isInSpace(actualObj)) {
space.markBlockByObjRef(actualObj) space.markBlockByObjRef(actualObj)
} else if (los.isInSpace(actualObj)) { } else if (los.isInSpace(actualObj)) {
los.markBlockByObjRef(actualObj) los.markBlockByObjRef(actualObj)
} else { } else {
throw new UvmRefImplException("Object ref %d not in any space".format(actualObj)) throw new UvmRefImplException("Object ref %x not in any space".format(actualObj))
} }
true true
} }
...@@ -233,7 +233,7 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap, ...@@ -233,7 +233,7 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap,
* old location when not moved. * old location when not moved.
*/ */
private def evacuate(oldObjRef: Word): Word = { private def evacuate(oldObjRef: Word): Word = {
logger.debug("Evacuating object %d".format(oldObjRef)) logger.debug("Evacuating object 0x%x".format(oldObjRef))
if (!canDefrag) { if (!canDefrag) {
logger.debug("No more reserved blocks.") logger.debug("No more reserved blocks.")
oldObjRef oldObjRef
...@@ -241,6 +241,7 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap, ...@@ -241,6 +241,7 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap,
val tag = HeaderUtils.getTag(oldObjRef) val tag = HeaderUtils.getTag(oldObjRef)
val ty = HeaderUtils.getType(microVM, tag) val ty = HeaderUtils.getType(microVM, tag)
try {
val (newObjRef, oldSize): (Long, Long) = ty match { val (newObjRef, oldSize): (Long, Long) = ty match {
case htype: TypeHybrid => { case htype: TypeHybrid => {
val len = HeaderUtils.getVarLength(oldObjRef) val len = HeaderUtils.getVarLength(oldObjRef)
...@@ -255,18 +256,19 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap, ...@@ -255,18 +256,19 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap,
} }
} }
if (newObjRef == 0) {
canDefrag = false
logger.debug("No more reserved blocks and thus no more moving.")
oldObjRef
} else {
val alignedOldSize = TypeSizes.alignUp(oldSize, TypeSizes.WORD_SIZE_BYTES) val alignedOldSize = TypeSizes.alignUp(oldSize, TypeSizes.WORD_SIZE_BYTES)
logger.debug("Copying old object %d to %d, %d bytes (aligned up to %d bytes).".format( logger.debug("Copying old object 0x%x to 0x%x, %d bytes (aligned up to %d bytes).".format(
oldObjRef, newObjRef, oldSize, alignedOldSize)) oldObjRef, newObjRef, oldSize, alignedOldSize))
MemUtils.memcpy(oldObjRef, newObjRef, alignedOldSize) MemUtils.memcpy(oldObjRef, newObjRef, alignedOldSize)
val newTag = newObjRef | MOVE_MASK val newTag = newObjRef | MOVE_MASK
HeaderUtils.setTag(oldObjRef, newTag) HeaderUtils.setTag(oldObjRef, newTag)
newObjRef newObjRef
} catch {
case e: NoMoreDefragBlockException =>
canDefrag = false
logger.debug("No more reserved blocks and thus no more moving.")
oldObjRef
} }
} }
} }
...@@ -293,7 +295,7 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap, ...@@ -293,7 +295,7 @@ class SimpleImmixCollector(val heap: SimpleImmixHeap,
private def clearMark(objRef: Long): Boolean = { private def clearMark(objRef: Long): Boolean = {
val oldHeader = HeaderUtils.getTag(objRef) val oldHeader = HeaderUtils.getTag(objRef)
logger.debug("GC header of %d is %x".format(objRef, oldHeader)) logger.debug("GC header of 0x%x is 0x%x".format(objRef, oldHeader))
val markBit = oldHeader & MARK_MASK val markBit = oldHeader & MARK_MASK
if (markBit != 0) { if (markBit != 0) {
val newHeader = oldHeader & ~(MARK_MASK | MOVE_MASK) val newHeader = oldHeader & ~(MARK_MASK | MOVE_MASK)
......
...@@ -26,8 +26,8 @@ class SimpleImmixDefragMutator(val heap: SimpleImmixHeap, val space: SimpleImmix ...@@ -26,8 +26,8 @@ class SimpleImmixDefragMutator(val heap: SimpleImmixHeap, val space: SimpleImmix
getNewBlock() getNewBlock()
private def getNewBlock() { private def getNewBlock() {
val newAddr = space.getDefragBlock(curBlockAddr) curBlockAddr = space.getDefragBlock(curBlockAddr)
newAddr match { curBlockAddr match {
case Some(addr) => case Some(addr) =>
cursor = addr cursor = addr
limit = addr + SimpleImmixSpace.BLOCK_SIZE limit = addr + SimpleImmixSpace.BLOCK_SIZE
...@@ -37,9 +37,9 @@ class SimpleImmixDefragMutator(val heap: SimpleImmixHeap, val space: SimpleImmix ...@@ -37,9 +37,9 @@ class SimpleImmixDefragMutator(val heap: SimpleImmixHeap, val space: SimpleImmix
override def alloc(size: Word, align: Word, headerSize: Word): Word = { override def alloc(size: Word, align: Word, headerSize: Word): Word = {
logger.debug(s"alloc(${size}, ${align}, ${headerSize})") logger.debug(s"alloc(${size}, ${align}, ${headerSize})")
if (curBlockAddr == 0) { if (curBlockAddr == None) {
logger.debug("No more reserved blocks. Cannot defragment.") logger.debug("No more reserved blocks. Cannot defragment.")
return 0 throw new NoMoreDefragBlockException("No more blocks for defrag.")
} }
val actualAlign = if (align < TypeSizes.WORD_SIZE_BYTES) TypeSizes.WORD_SIZE_BYTES else align val actualAlign = if (align < TypeSizes.WORD_SIZE_BYTES) TypeSizes.WORD_SIZE_BYTES else align
tryTwice { tryTwice {
...@@ -67,6 +67,7 @@ class SimpleImmixDefragMutator(val heap: SimpleImmixHeap, val space: SimpleImmix ...@@ -67,6 +67,7 @@ class SimpleImmixDefragMutator(val heap: SimpleImmixHeap, val space: SimpleImmix
} }
def close() { def close() {
logger.debug("Closing defrag mutator...")
curBlockAddr.foreach(space.returnBlock) curBlockAddr.foreach(space.returnBlock)
} }
} }
...@@ -7,16 +7,16 @@ import TypeSizes._ ...@@ -7,16 +7,16 @@ import TypeSizes._
class SimpleImmixHeap(val begin: Word, val size: Word, val microVM: MicroVM) extends Heap { class SimpleImmixHeap(val begin: Word, val size: Word, val microVM: MicroVM) extends Heap {
val mid = begin + size / 2
val space: SimpleImmixSpace = new SimpleImmixSpace(this, "SimpleImmixSpace", begin, size / 2) val space: SimpleImmixSpace = new SimpleImmixSpace(this, "SimpleImmixSpace", begin, size / 2)
val los: LargeObjectSpace = new LargeObjectSpace(this, "Large object space", mid, size / 2)
val collector: SimpleImmixCollector = new SimpleImmixCollector(this, space, los, microVM) val collector: SimpleImmixCollector = new SimpleImmixCollector(this, space, los, microVM)
val collectorThread: Thread = new Thread(collector) val collectorThread: Thread = new Thread(collector)
val los: LargeObjectSpace = new LargeObjectSpace(this, "Large object space", mid, size / 2)
val mid = begin + size / 2
collectorThread.setDaemon(true) collectorThread.setDaemon(true)
collectorThread.start() collectorThread.start()
......
...@@ -62,6 +62,7 @@ class SimpleImmixMutator(val heap: SimpleImmixHeap, val space: SimpleImmixSpace, ...@@ -62,6 +62,7 @@ class SimpleImmixMutator(val heap: SimpleImmixHeap, val space: SimpleImmixSpace,
} }
def close() { def close() {
logger.debug("Closing mutator...")
curBlockAddr.foreach(space.returnBlock) curBlockAddr.foreach(space.returnBlock)
} }
} }
...@@ -24,8 +24,19 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext ...@@ -24,8 +24,19 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
import SimpleImmixSpace._ import SimpleImmixSpace._
if (begin % BLOCK_SIZE != 0) {
throw new UvmRefImplException("space should be aligned to BLOCK_SIZE " + BLOCK_SIZE)
}
if (extend % BLOCK_SIZE != 0) {
throw new UvmRefImplException("space size should be a multiple of BLOCK_SIZE " + BLOCK_SIZE)
}
val nBlocks: Int = (extend / BLOCK_SIZE).toInt val nBlocks: Int = (extend / BLOCK_SIZE).toInt
/** The number of reserved blocks (for defrag). */
private val nReserved: Int = Math.max(nBlocks / 20, 1) // reserve at least one block
/** Flag for each block */ /** Flag for each block */
private val blockFlags: Array[Int] = new Array[Int](nBlocks) private val blockFlags: Array[Int] = new Array[Int](nBlocks)
...@@ -41,14 +52,11 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext ...@@ -41,14 +52,11 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
/** For each block, count how many bytes are occupied. */ /** For each block, count how many bytes are occupied. */
private val blockUsedStats: Array[Word] = new Array[Word](nBlocks) private val blockUsedStats: Array[Word] = new Array[Word](nBlocks)
/** The number of reserved blocks (for defrag). */
private val nReserved: Int = nBlocks / 20
/** A list of free blocks reserved for defrag. */ /** A list of free blocks reserved for defrag. */
private val defragResv: Array[Int] = new Array[Int](nReserved) private val defragResv: Array[Int] = new Array[Int](nReserved)
/** The number of free blocks (valid entries) in defragResv. */ /** The number of free blocks (valid entries) in defragResv. */
private var defragResvFree: Int = _ private var defragResvFree: Int = nReserved
/** The index of the next free reserved block to allocate in defragResv. */ /** The index of the next free reserved block to allocate in defragResv. */
private var nextResv: Int = 0 private var nextResv: Int = 0
...@@ -56,14 +64,6 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext ...@@ -56,14 +64,6 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
/** A list of buckets, for statistics. Used by defrag. */ /** A list of buckets, for statistics. Used by defrag. */
private val buckets: Array[Word] = new Array[Word](N_BUCKETS) private val buckets: Array[Word] = new Array[Word](N_BUCKETS)
if (begin % BLOCK_SIZE != 0) {
throw new UvmRefImplException("space should be aligned to BLOCK_SIZE " + BLOCK_SIZE)
}
if (extend % BLOCK_SIZE != 0) {
throw new UvmRefImplException("space size should be a multiple of BLOCK_SIZE " + BLOCK_SIZE)
}
for (i <- 0 until nReserved) { // Block 0 to nReserved-1 are reserved for (i <- 0 until nReserved) { // Block 0 to nReserved-1 are reserved
defragResv(i) = i defragResv(i) = i
reserve(i) // Set the reserved flat reserve(i) // Set the reserved flat
...@@ -163,19 +163,7 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext ...@@ -163,19 +163,7 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
defragResvFree = newDefragResvFree defragResvFree = newDefragResvFree
freeListValidCount = newNFree freeListValidCount = newNFree
if (logger.underlying.isDebugEnabled()) { if (logger.underlying.isDebugEnabled()) {
val sb1 = new StringBuilder("New reserved freelist:") debugLogBlockStates()
for (i <- 0 until defragResvFree) {
sb1.append(" ").append(defragResv(i))
}
logger.debug(sb1.toString)
val sb2 = new StringBuilder("New freelist:")
for (i <- 0 until freeListValidCount) {
sb2.append(" ").append(freeList(i))
}
logger.debug(sb2.toString)
for (i <- 0 until nBlocks) {
logger.debug(s"blockFlags[${i}] = ${blockFlags(i)}")
}
} }
nextResv = 0 nextResv = 0
nextFree = 0 nextFree = 0
...@@ -185,6 +173,7 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext ...@@ -185,6 +173,7 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
def returnBlock(blockAddr: Word) { def returnBlock(blockAddr: Word) {
val blockNum = blockAddrToBlockIndex(blockAddr) val blockNum = blockAddrToBlockIndex(blockAddr)
unreserve(blockNum) unreserve(blockNum)
logger.debug("Block %d returned to space.".format(blockNum))
} }
// Statistics // Statistics
...@@ -263,4 +252,21 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext ...@@ -263,4 +252,21 @@ class SimpleImmixSpace(val heap: SimpleImmixHeap, name: String, begin: Word, ext
return Some(blockAddr) return Some(blockAddr)
} }
// Debugging
def debugLogBlockStates() {
val sb1 = new StringBuilder("Reserved freelist:")
for (i <- 0 until defragResvFree) {
sb1.append(" ").append(defragResv(i))
}
logger.debug(sb1.toString)
val sb2 = new StringBuilder("Freelist:")
for (i <- 0 until freeListValidCount) {
sb2.append(" ").append(freeList(i))
}
logger.debug(sb2.toString)
for (i <- 0 until nBlocks) {
logger.debug(s"blockFlags[${i}] = ${blockFlags(i)}")
}
}
} }
package uvm.refimpl.mem.simpleimmix
import uvm.refimpl.UvmOutOfMemoryException