Commit 33e433e5 authored by Kunshan Wang's avatar Kunshan Wang

A more configurable MicroVM constructor.

Tuning the heap size may reveal some GC bugs.
parent 533893e2
...@@ -68,7 +68,7 @@ static void init_jvm() { ...@@ -68,7 +68,7 @@ static void init_jvm() {
exit(1); exit(1);
} }
new_ex_mid = (*env)->GetStaticMethodID(env, cinitiater_cls, new_ex_method, "(JJJ)J"); new_ex_mid = (*env)->GetStaticMethodID(env, cinitiater_cls, new_ex_method, "(Ljava/lang/String;)J");
if (new_ex_mid == NULL) { if (new_ex_mid == NULL) {
printf("ERROR: method %s cannot be found.\n", new_ex_method); printf("ERROR: method %s cannot be found.\n", new_ex_method);
...@@ -94,13 +94,22 @@ MuVM *mu_refimpl2_new() { ...@@ -94,13 +94,22 @@ MuVM *mu_refimpl2_new() {
return (MuVM*)rv; return (MuVM*)rv;
} }
MuVM *mu_refimpl2_new_ex(int64_t heap_size, int64_t global_size, int64_t stack_size) { MuVM *mu_refimpl2_new_ex(const char *gc_conf) {
if (jvm == NULL) { if (jvm == NULL) {
init_jvm(); init_jvm();
} }
jstring conf_str = (*env)->NewStringUTF(env, gc_conf);
if (conf_str == NULL) {
printf("ERROR: Cannot convert gc_conf to Java String\n");
exit(1);
}
uintptr_t rv = (*env)->CallStaticLongMethod(env, cinitiater_cls, new_ex_mid, uintptr_t rv = (*env)->CallStaticLongMethod(env, cinitiater_cls, new_ex_mid,
heap_size, global_size, stack_size); conf_str);
(*env)->DeleteLocalRef(env, conf_str);
return (MuVM*)rv; return (MuVM*)rv;
} }
......
...@@ -10,7 +10,7 @@ extern "C" { ...@@ -10,7 +10,7 @@ extern "C" {
#endif #endif
MuVM *mu_refimpl2_new(); MuVM *mu_refimpl2_new();
MuVM *mu_refimpl2_new_ex(int64_t heap_size, int64_t global_size, int64_t stack_size); MuVM *mu_refimpl2_new_ex(const char *gc_conf);
void mu_refimpl2_close(MuVM *mvm); void mu_refimpl2_close(MuVM *mvm);
......
...@@ -7,10 +7,18 @@ ...@@ -7,10 +7,18 @@
#include <refimpl2-start.h> #include <refimpl2-start.h>
#include <muapi.h> #include <muapi.h>
char *hw_string = "Hello world!\n"; const char *hw_string = "Hello world!\n";
const char *gc_conf =
"sosSize=524288\n"
"losSize=524288\n"
"globalSize=1048576\n"
"stackSize=32768\n"
;
int main() { int main() {
MuVM *mvm = mu_refimpl2_new_ex(1048576, 1048576, 32768); MuVM *mvm = mu_refimpl2_new_ex(gc_conf);
MuCtx *ctx = mvm->new_context(mvm); MuCtx *ctx = mvm->new_context(mvm);
......
...@@ -4,4 +4,3 @@ def _assert_instance(obj, *tys): ...@@ -4,4 +4,3 @@ def _assert_instance(obj, *tys):
if not any(isinstance(obj, ty) for ty in tys): if not any(isinstance(obj, ty) for ty in tys):
raise AssertionError("{} is not an instance of {}".format(obj, raise AssertionError("{} is not an instance of {}".format(obj,
" or ".join(map(str,tys)))) " or ".join(map(str,tys))))
...@@ -5,17 +5,17 @@ from _libmuprivcommon import _assert_instance ...@@ -5,17 +5,17 @@ from _libmuprivcommon import _assert_instance
def _is_str_like(v): def _is_str_like(v):
return isinstance(v, str) or isinstance(v, unicode) return isinstance(v, str) or isinstance(v, unicode)
def _encode_ascii(v): def _encode(v, encoding):
_assert_instance(v, str, unicode) _assert_instance(v, str, unicode)
if isinstance(v, unicode): if isinstance(v, unicode):
return v.encode("ascii") return v.encode(encoding)
else: else:
return v return v
def _decode_ascii(v): def _decode(v, encoding):
_assert_instance(v, str, unicode) _assert_instance(v, str, unicode)
if isinstance(v, str): if isinstance(v, str):
return v.decode("ascii") return v.decode(encoding)
else: else:
return v return v
......
...@@ -3,17 +3,17 @@ from _libmuprivcommon import _assert_instance ...@@ -3,17 +3,17 @@ from _libmuprivcommon import _assert_instance
def _is_str_like(v): def _is_str_like(v):
return isinstance(v, str) or isinstance(v, bytes) return isinstance(v, str) or isinstance(v, bytes)
def _encode_ascii(v): def _encode(v, encoding):
_assert_instance(v, bytes, str) _assert_instance(v, bytes, str)
if isinstance(v, str): if isinstance(v, str):
return v.encode("ascii") return v.encode(encoding)
else: else:
return v return v
def _decode_ascii(v): def _decode(v, encoding):
_assert_instance(v, bytes, str) _assert_instance(v, bytes, str)
if isinstance(v, bytes): if isinstance(v, bytes):
return v.decode("ascii") return v.decode(encoding)
else: else:
return v return v
......
...@@ -36,7 +36,12 @@ Then a ``MuVM`` instance can be created from that object:: ...@@ -36,7 +36,12 @@ Then a ``MuVM`` instance can be created from that object::
or:: or::
mu = dll.mu_refimpl2_new_ex(HEAP_SIZE, GLOBAL_SIZE, STACK_SIZE) mu = dll.mu_refimpl2_new_ex(
sosSize = 2*1024*1024,
losSize = 2*1024*1024,
globalSize = 4*1024*1024,
stackSize = 63*1024,
)
A ``MuCtx`` instance can be created from the ``MuVM`` object:: A ``MuCtx`` instance can be created from the ``MuVM`` object::
...@@ -670,7 +675,7 @@ class MuCtx(_StructOfMethodsWrapper): ...@@ -670,7 +675,7 @@ class MuCtx(_StructOfMethodsWrapper):
Arguments: Arguments:
bundle_str: a str or unicode as the text-based bundle. bundle_str: a str or unicode as the text-based bundle.
""" """
ascii_bundle = _priv._encode_ascii(bundle_str) ascii_bundle = _priv._encode(bundle_str, "ascii")
return self.load_bundle_(ascii_bundle, len(ascii_bundle)) return self.load_bundle_(ascii_bundle, len(ascii_bundle))
def load_hail(self, hail_str): def load_hail(self, hail_str):
...@@ -679,7 +684,7 @@ class MuCtx(_StructOfMethodsWrapper): ...@@ -679,7 +684,7 @@ class MuCtx(_StructOfMethodsWrapper):
Arguments: Arguments:
bundle_str: a str or unicode as the text-based HAIL script. bundle_str: a str or unicode as the text-based HAIL script.
""" """
ascii_bundle = _priv._encode_ascii(hail_str) ascii_bundle = _priv._encode(hail_str, "ascii")
return self.load_hail_(ascii_bundle, len(ascii_bundle)) return self.load_hail_(ascii_bundle, len(ascii_bundle))
def handle_from_int(self, value, length): def handle_from_int(self, value, length):
...@@ -844,13 +849,13 @@ def _to_low_level_type(ty): ...@@ -844,13 +849,13 @@ def _to_low_level_type(ty):
def _to_low_level_arg(arg): def _to_low_level_arg(arg):
return (arg._to_low_level_arg() if isinstance(arg, _LowLevelTypeWrapper) else return (arg._to_low_level_arg() if isinstance(arg, _LowLevelTypeWrapper) else
_priv._encode_ascii(arg) if _priv._is_str_like(arg) else _priv._encode(arg, "ascii") if _priv._is_str_like(arg) else
arg) arg)
def _from_low_level_retval(restype, low_level_rv, self): def _from_low_level_retval(restype, low_level_rv, self):
return (restype._from_low_level_retval(low_level_rv, self) return (restype._from_low_level_retval(low_level_rv, self)
if isinstance(restype, type) and issubclass(restype, _LowLevelTypeWrapper) else if isinstance(restype, type) and issubclass(restype, _LowLevelTypeWrapper) else
_priv._decode_ascii(low_level_rv) if _priv._is_str_like(low_level_rv) else _priv._decode(low_level_rv, "ascii") if _priv._is_str_like(low_level_rv) else
low_level_rv) low_level_rv)
def _make_high_level_method(name, expected_nargs, restype, argtypes): def _make_high_level_method(name, expected_nargs, restype, argtypes):
...@@ -1119,8 +1124,7 @@ class MuRefImpl2StartDLL(object): ...@@ -1119,8 +1124,7 @@ class MuRefImpl2StartDLL(object):
dll.mu_refimpl2_new.argtypes = [] dll.mu_refimpl2_new.argtypes = []
dll.mu_refimpl2_new_ex.restype = CPtrMuVM dll.mu_refimpl2_new_ex.restype = CPtrMuVM
dll.mu_refimpl2_new_ex.argtypes = [ctypes.c_int64, dll.mu_refimpl2_new_ex.argtypes = [ctypes.c_char_p]
ctypes.c_int64, ctypes.c_int64]
dll.mu_refimpl2_close.restype = None dll.mu_refimpl2_close.restype = None
dll.mu_refimpl2_close.argtypes = [CPtrMuVM] dll.mu_refimpl2_close.argtypes = [CPtrMuVM]
...@@ -1132,13 +1136,17 @@ class MuRefImpl2StartDLL(object): ...@@ -1132,13 +1136,17 @@ class MuRefImpl2StartDLL(object):
ptr = self.dll.mu_refimpl2_new() ptr = self.dll.mu_refimpl2_new()
return MuVM(ptr, self) return MuVM(ptr, self)
def mu_refimpl2_new_ex(self, heap_size, global_size, stack_size): def mu_refimpl2_new_ex(self, **kwargs):
"""Create a MuVM instance using custom heap/global/stack sizes. """Create a MuVM instance using custom configuration.
heap_size, global_size, stack_size are the sizes of the GC heap, global Currently supported keyword arguments:
memory and each stack. All of them are in bytes. sosSize: small object space size (bytes, must be 4096-byte aligned)
losSize: large object space size (bytes, must be 4096-byte aligned)
globalSize: global space size (bytes, must be 4096-byte aligned)
stackSize: stack size (bytes)
""" """
ptr = self.dll.mu_refimpl2_new_ex(heap_size, global_size, stack_size) conf = "".join("{}={}\n".format(k,v) for k,v in kwargs.items())
ptr = self.dll.mu_refimpl2_new_ex(_priv._encode(conf, "utf8"))
return MuVM(ptr, self) return MuVM(ptr, self)
def mu_refimpl2_close(self, muvm): def mu_refimpl2_close(self, muvm):
......
...@@ -5,7 +5,12 @@ import unittest ...@@ -5,7 +5,12 @@ import unittest
from libmu import * from libmu import *
dll = MuRefImpl2StartDLL(u"../cbinding/libmurefimpl2start.so") dll = MuRefImpl2StartDLL(u"../cbinding/libmurefimpl2start.so")
mu = dll.mu_refimpl2_new() mu = dll.mu_refimpl2_new_ex(
sosSize = 2*1024*1024,
losSize = 2*1024*1024,
globalSize = 4*1024*1024,
stackSize = 63*1024,
)
with mu.new_context() as ctx: with mu.new_context() as ctx:
ctx.load_bundle(""" ctx.load_bundle("""
......
...@@ -45,8 +45,7 @@ public class CInitiater { ...@@ -45,8 +45,7 @@ public class CInitiater {
/** Called by the native program, this function creates a Mu instance. */ /** Called by the native program, this function creates a Mu instance. */
static long mu_refimpl2_new() { static long mu_refimpl2_new() {
configureLog(); configureLog();
MicroVM mvm = new MicroVM(MicroVM$.MODULE$.DEFAULT_HEAP_SIZE(), MicroVM$.MODULE$.DEFAULT_GLOBAL_SIZE(), MicroVM mvm = MicroVM$.MODULE$.apply();
MicroVM$.MODULE$.DEFAULT_STACK_SIZE());
long fak = NativeClientSupport$.MODULE$.exposeMicroVM(mvm); long fak = NativeClientSupport$.MODULE$.exposeMicroVM(mvm);
return fak; return fak;
} }
...@@ -55,9 +54,9 @@ public class CInitiater { ...@@ -55,9 +54,9 @@ public class CInitiater {
* Called by the native program, this function creates a Mu instance with * Called by the native program, this function creates a Mu instance with
* extra arguments. * extra arguments.
*/ */
static long mu_refimpl2_new_ex(long heap_size, long global_size, long stack_size) { static long mu_refimpl2_new_ex(String gcConfString) {
configureLog(); configureLog();
MicroVM mvm = new MicroVM(heap_size, global_size, stack_size); MicroVM mvm = MicroVM$.MODULE$.apply(gcConfString);
long fak = NativeClientSupport$.MODULE$.exposeMicroVM(mvm); long fak = NativeClientSupport$.MODULE$.exposeMicroVM(mvm);
return fak; return fak;
} }
......
...@@ -12,31 +12,72 @@ import uvm.refimpl.mem.TypeSizes.Word ...@@ -12,31 +12,72 @@ import uvm.refimpl.mem.TypeSizes.Word
import uvm.refimpl.nat.NativeCallHelper import uvm.refimpl.nat.NativeCallHelper
import uvm.staticanalysis.StaticAnalyzer import uvm.staticanalysis.StaticAnalyzer
object GCConf {
val ReComment = """^\s*#.*$""".r
val ReBlank = """^\s*$""".r
val ReConf = """^\s*(\w+)=(\w+)\s*$""".r
def apply(confStr: String): GCConf = {
var sosSize = MicroVM.DEFAULT_SOS_SIZE
var losSize = MicroVM.DEFAULT_LOS_SIZE
var globalSize = MicroVM.DEFAULT_GLOBAL_SIZE
var stackSize = MicroVM.DEFAULT_GLOBAL_SIZE
confStr.lines foreach {
case ReComment() =>
case ReBlank() =>
case ReConf(key, value) => {
key match {
case "sosSize" => sosSize = value.toLong
case "losSize" => losSize = value.toLong
case "globalSize" => globalSize = value.toLong
case "stackSize" => stackSize = value.toLong
case _ => throw new UvmRefImplException("Unrecognized option %s".format(key))
}
}
}
new GCConf(sosSize, losSize, globalSize, stackSize)
}
}
class GCConf(
val sosSize: Word = MicroVM.DEFAULT_SOS_SIZE,
val losSize: Word = MicroVM.DEFAULT_LOS_SIZE,
val globalSize: Word = MicroVM.DEFAULT_GLOBAL_SIZE,
val stackSize: Word = MicroVM.DEFAULT_STACK_SIZE)
object MicroVM { object MicroVM {
val DEFAULT_HEAP_SIZE: Word = 4L * 1024L * 1024L; // 4MiB val DEFAULT_SOS_SIZE: Word = 2L * 1024L * 1024L; // 2MiB
val DEFAULT_LOS_SIZE: Word = 2L * 1024L * 1024L; // 2MiB
val DEFAULT_GLOBAL_SIZE: Word = 1L * 1024L * 1024L; // 1MiB val DEFAULT_GLOBAL_SIZE: Word = 1L * 1024L * 1024L; // 1MiB
val DEFAULT_STACK_SIZE: Word = 63L * 1024L; // 60KiB per stack val DEFAULT_STACK_SIZE: Word = 63L * 1024L; // 60KiB per stack
val FIRST_CLIENT_USABLE_ID: Int = 65536 val FIRST_CLIENT_USABLE_ID: Int = 65536
}
class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE, def apply(): MicroVM = {
globalSize: Word = MicroVM.DEFAULT_GLOBAL_SIZE, val gcConf = new GCConf()
stackSize: Word = MicroVM.DEFAULT_STACK_SIZE) { new MicroVM(gcConf)
}
def apply(confStr: String): MicroVM = {
val gcConf = GCConf(confStr)
new MicroVM(gcConf)
}
}
class MicroVM(gcConf: GCConf) {
// implicitly injected resources // implicitly injected resources
private implicit val microVM = this private implicit val microVM = this
val globalBundle = new GlobalBundle() val globalBundle = new GlobalBundle()
val constantPool = new ConstantPool() val constantPool = new ConstantPool()
val memoryManager = new MemoryManager(heapSize, globalSize, stackSize) val memoryManager = new MemoryManager(gcConf)
private implicit val memorySupport = memoryManager.memorySupport private implicit val memorySupport = memoryManager.memorySupport
implicit val nativeCallHelper = new NativeCallHelper() implicit val nativeCallHelper = new NativeCallHelper()
val threadStackManager = new ThreadStackManager() val threadStackManager = new ThreadStackManager()
val trapManager = new TrapManager() val trapManager = new TrapManager()
val contexts = new HashSet[MuCtx]() val contexts = new HashSet[MuCtx]()
...@@ -57,7 +98,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE, ...@@ -57,7 +98,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
} }
// Some internal constants needed by the HAIL loader // Some internal constants needed by the HAIL loader
for (c <- Seq(NULL_REF_VOID, NULL_IREF_VOID, NULL_FUNCREF_VV, NULL_THREADREF, NULL_STACKREF)) { for (c <- Seq(NULL_REF_VOID, NULL_IREF_VOID, NULL_FUNCREF_VV, NULL_THREADREF, NULL_STACKREF)) {
globalBundle.constantNs.add(c) globalBundle.constantNs.add(c)
constantPool.addGlobalVar(c) constantPool.addGlobalVar(c)
...@@ -69,7 +110,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE, ...@@ -69,7 +110,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
*/ */
def addBundle(bundle: TrantientBundle) { def addBundle(bundle: TrantientBundle) {
staticAnalyzer.checkBundle(bundle, Some(globalBundle)) staticAnalyzer.checkBundle(bundle, Some(globalBundle))
globalBundle.merge(bundle); globalBundle.merge(bundle);
for (gc <- bundle.globalCellNs.all) { for (gc <- bundle.globalCellNs.all) {
......
...@@ -3,25 +3,46 @@ package uvm.refimpl.mem ...@@ -3,25 +3,46 @@ package uvm.refimpl.mem
import uvm.refimpl._ import uvm.refimpl._
import TypeSizes._ import TypeSizes._
import uvm.refimpl.mem.simpleimmix._ import uvm.refimpl.mem.simpleimmix._
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
class MemoryManager(val heapSize: Word, val globalSize: Word, val stackSize: Word)(implicit microVM: MicroVM) { object MemoryManager {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
}
class MemoryManager(val gcConf: GCConf)(implicit microVM: MicroVM) {
import MemoryManager._
val totalMemorySize = heapSize + globalSize logger.info("sosSize=%d, losSize=%d, globalSize=%d, stackSize=%d".format(
gcConf.sosSize, gcConf.losSize, gcConf.globalSize, gcConf.stackSize))
require(gcConf.sosSize % 4096L == 0, "Small object space size must be 4096 bytes aligned. actual size: %d".format(gcConf.sosSize))
require(gcConf.losSize % 4096L == 0, "Large object space size must be 4096 bytes aligned. actual size: %d".format(gcConf.losSize))
require(gcConf.globalSize % 4096L == 0, "Global space size must be 4096 bytes aligned. actual size: %d".format(gcConf.globalSize))
val totalMemorySize = gcConf.sosSize + gcConf.losSize + gcConf.globalSize
// Allocate slightly more memory to meet the SimpleImmixSpace's alignment requirement. // Allocate slightly more memory to meet the SimpleImmixSpace's alignment requirement.
implicit val memorySupport = new MemorySupport(totalMemorySize + SimpleImmixSpace.BLOCK_SIZE) implicit val memorySupport = new MemorySupport(totalMemorySize + SimpleImmixSpace.BLOCK_SIZE)
val memoryBegin = memorySupport.muMemoryBegin val memoryBegin = memorySupport.muMemoryBegin
val heapBegin = TypeSizes.alignUp(memoryBegin, SimpleImmixSpace.BLOCK_SIZE) val heapBegin = TypeSizes.alignUp(memoryBegin, SimpleImmixSpace.BLOCK_SIZE)
val globalBegin = heapBegin + gcConf.sosSize + gcConf.losSize
val globalEnd = globalBegin + gcConf.globalSize
logger.info(("Mu memory allocated.\n memoryBegin=%d 0x%x\n heapBegin=%d 0x%x\n" +
" globalBegin=%d 0x%x\n memory end=%d 0x%x").format(
memoryBegin, memoryBegin, heapBegin, heapBegin, globalBegin, globalBegin, globalEnd, globalEnd
))
val heap = new SimpleImmixHeap(heapBegin, heapSize) val heap = new SimpleImmixHeap(heapBegin, gcConf.sosSize, gcConf.losSize)
val globalMemory = new GlobalMemory(heapBegin + heapSize, globalSize) val globalMemory = new GlobalMemory(globalBegin, gcConf.globalSize)
def makeMutator(): Mutator = heap.makeMutator() def makeMutator(): Mutator = heap.makeMutator()
def makeStackMemory(mutator: Mutator): StackMemory = { def makeStackMemory(mutator: Mutator): StackMemory = {
val objRef = mutator.newHybrid(InternalTypes.BYTE_ARRAY, stackSize) val objRef = mutator.newHybrid(InternalTypes.BYTE_ARRAY, gcConf.stackSize)
val stackMemory = new StackMemory(objRef, stackSize) val stackMemory = new StackMemory(objRef, gcConf.stackSize)
stackMemory stackMemory
} }
} }
...@@ -2,9 +2,16 @@ package uvm.refimpl.mem ...@@ -2,9 +2,16 @@ package uvm.refimpl.mem
import uvm.types._ import uvm.types._
import TypeSizes._ import TypeSizes._
import com.typesafe.scalalogging.Logger
import org.slf4j.LoggerFactory
abstract class Mutator(implicit memorySupport: MemorySupport) { object Mutator {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
}
abstract class Mutator(implicit memorySupport: MemorySupport) {
import Mutator._
def alloc(size: Word, align: Word, headerSize: Word): Word def alloc(size: Word, align: Word, headerSize: Word): Word
def newScalar(ty: Type): Word = { def newScalar(ty: Type): Word = {
...@@ -13,6 +20,7 @@ abstract class Mutator(implicit memorySupport: MemorySupport) { ...@@ -13,6 +20,7 @@ abstract class Mutator(implicit memorySupport: MemorySupport) {
val align = alignOf(ty) val align = alignOf(ty)
val objAddr = alloc(size, align, GC_HEADER_SIZE_SCALAR) val objAddr = alloc(size, align, GC_HEADER_SIZE_SCALAR)
HeaderUtils.postAllocScalar(objAddr, tag) HeaderUtils.postAllocScalar(objAddr, tag)
logger.debug("newScalar: objAddr=%d 0x%x, ty=%s".format(objAddr, objAddr, ty))
objAddr objAddr
} }
...@@ -22,6 +30,7 @@ abstract class Mutator(implicit memorySupport: MemorySupport) { ...@@ -22,6 +30,7 @@ abstract class Mutator(implicit memorySupport: MemorySupport) {
val align = hybridAlignOf(ty, len) val align = hybridAlignOf(ty, len)
val objAddr = alloc(size, align, GC_HEADER_SIZE_HYBRID) val objAddr = alloc(size, align, GC_HEADER_SIZE_HYBRID)
HeaderUtils.postAllocHybrid(objAddr, tag, len) HeaderUtils.postAllocHybrid(objAddr, tag, len)
logger.debug("newHybrid: objAddr=%d 0x%x, len=%d 0x%x, ty=%s".format(objAddr, objAddr, len, len, ty))
objAddr objAddr
} }
...@@ -31,6 +40,7 @@ abstract class Mutator(implicit memorySupport: MemorySupport) { ...@@ -31,6 +40,7 @@ abstract class Mutator(implicit memorySupport: MemorySupport) {
val align = alignOf(ty) val align = alignOf(ty)
val objAddr = sm.alloc(size, align, GC_HEADER_SIZE_SCALAR) val objAddr = sm.alloc(size, align, GC_HEADER_SIZE_SCALAR)
HeaderUtils.postAllocScalar(objAddr, tag) HeaderUtils.postAllocScalar(objAddr, tag)
logger.debug("allocaScalar: objAddr=%d 0x%x, ty=%s".format(objAddr, objAddr, ty))
objAddr objAddr
} }
...@@ -40,6 +50,7 @@ abstract class Mutator(implicit memorySupport: MemorySupport) { ...@@ -40,6 +50,7 @@ abstract class Mutator(implicit memorySupport: MemorySupport) {
val align = hybridAlignOf(ty, len) val align = hybridAlignOf(ty, len)
val objAddr = sm.alloc(size, align, GC_HEADER_SIZE_HYBRID) val objAddr = sm.alloc(size, align, GC_HEADER_SIZE_HYBRID)
HeaderUtils.postAllocHybrid(objAddr, tag, len) HeaderUtils.postAllocHybrid(objAddr, tag, len)
logger.debug("allocaHybrid: objAddr=%d 0x%x, len=%d 0x%x, ty=%s".format(objAddr, objAddr, len, len, ty))
objAddr objAddr
} }
......
package uvm.refimpl.mem.simpleimmix package uvm.refimpl.mem.simpleimmix
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import uvm.refimpl._ import uvm.refimpl._
import uvm.refimpl.mem._ import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes._
import uvm.refimpl.mem.los.LargeObjectSpace import uvm.refimpl.mem.los.LargeObjectSpace
import TypeSizes._
class SimpleImmixHeap(val begin: Word, val size: Word)( object SimpleImmixHeap {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
}
class SimpleImmixHeap(val begin: Word, val sosSize: Word, val losSize: Word)(
implicit microVM: MicroVM, memorySupport: MemorySupport) implicit microVM: MicroVM, memorySupport: MemorySupport)
extends Heap { extends Heap {
import SimpleImmixHeap._
val mid = begin + size / 2 require(begin % 4096L == 0, "Heap beginning must be 4096 bytes aligned. actual beginning: %d".format(begin))
val losBegin = begin + sosSize
val losEnd = losBegin + losSize
logger.debug("Small object space: %d 0x%x to %d 0x%x".format(begin, begin, losBegin, losBegin))
logger.debug("Large object space: %d 0x%x to %d 0x%x".format(losBegin, losBegin, losEnd, losEnd))
val space: SimpleImmixSpace = new SimpleImmixSpace(this, "SimpleImmixSpace", begin, size / 2) val space: SimpleImmixSpace = new SimpleImmixSpace(this, "SimpleImmixSpace", begin, sosSize)
val los: LargeObjectSpace = new LargeObjectSpace(this, "Large object space", mid, size / 2) val los: LargeObjectSpace = new LargeObjectSpace(this, "Large object space", losBegin, losSize)
val collector: SimpleImmixCollector = new SimpleImmixCollector(this, space, los) val collector: SimpleImmixCollector = new SimpleImmixCollector(this, space, los)
......
...@@ -6,7 +6,7 @@ import uvm.refimpl.HowToResume.PassValues ...@@ -6,7 +6,7 @@ import uvm.refimpl.HowToResume.PassValues
object FactorialFromRPython extends App { object FactorialFromRPython extends App {
import uvm.refimpl.RichMuCtx._ import uvm.refimpl.RichMuCtx._
val microVM = new MicroVM() val microVM = MicroVM()
val ctx = microVM.newContext() val ctx = microVM.newContext()
......
...@@ -5,7 +5,7 @@ import uvm.refimpl._ ...@@ -5,7 +5,7 @@ import uvm.refimpl._
object Interact extends App { object Interact extends App {
// Create the Mu instance // Create the Mu instance
val microVM = new MicroVM() // #1 val microVM = MicroVM() // #1
// Implicitly convert names to IDs // Implicitly convert names to IDs
implicit def idOf(name: String) = microVM.idOf(name) // #2 implicit def idOf(name: String) = microVM.idOf(name) // #2
......
...@@ -59,7 +59,7 @@ abstract class UvmBundleTesterBase extends FlatSpec with Matchers { ...@@ -59,7 +59,7 @@ abstract class UvmBundleTesterBase extends FlatSpec with Matchers {
} }
} }
def makeMicroVM(): MicroVM = new MicroVM() def makeMicroVM(): MicroVM = MicroVM()
val microVM = makeMicroVM() val microVM = makeMicroVM()
......
...@@ -23,7 +23,7 @@ class UvmInterpreterSpec extends UvmBundleTesterBase { ...@@ -23,7 +23,7 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
//"uvm.refimpl.mem.simpleimmix.SimpleImmixCollector$" -> DEBUG, //"uvm.refimpl.mem.simpleimmix.SimpleImmixCollector$" -> DEBUG,
"uvm.refimpl.itpr" -> DEBUG) "uvm.refimpl.itpr" -> DEBUG)
override def makeMicroVM = new MicroVM(heapSize = 8L * 1024L * 1024L) override def makeMicroVM = new MicroVM(new GCConf(sosSize = 4L * 1024L * 1024L, losSize = 4L * 1024L * 1024L))
preloadBundles("tests/uvm-refimpl-test/primitives.uir", preloadBundles("tests/uvm-refimpl-test/primitives.uir",
"tests/uvm-refimpl-test/basic-tests.uir") "tests/uvm-refimpl-test/basic-tests.uir")
......
...@@ -39,13 +39,13 @@ class UvmInterpreterStackGCTests extends UvmBundleTesterBase { ...@@ -39,13 +39,13 @@ class UvmInterpreterStackGCTests extends UvmBundleTesterBase {
rv rv